1) Ativando o arrastar


            procedure TForm1.GridOrigemCellClick(Column: TColumn);

begin

  GridOrigem.BeginDrag(True);

end;
        

Ao chamar o método BeginDragM e passar o parâmetro como True, informamos ao DBGrid que é para iniciar a tarefa de arrastar. Você vai observar que ao clicar no registro, o ponteiro do mouse muda seu estado, indicando que a operação de arrastar está ativa.

Lembre-se que a operação é “arrastar e soltar”, portanto temos que ter um outro componente que vai receber os dados que estão sendo arrastados a partir do GridOrigem.

2) Preparando um TMemo para receber os dados


            procedure TForm1.Memo1DragOver(Sender, Source: TObject; X, Y: Integer;

  State: TDragState; var Accept: Boolean);

begin

  Accept := Source is TDBGrid;

end;
        

O evento DragOver é disparado quando um objeto é arrastado sobre um controle, neste caso, sobre nosso TMemo1. Veja que o evento possui uma variável Accept que indica se o controle (TMemo1) deve aceitar ou não o objeto que vai ser “soltado” sobre ele.

É neste evento que decidimos de quem nosso TMemo1 pode receber informações. Após aceitar o objeto temos que implementar o evento que vai lidar, tratar, com os dados desse objeto.

3) Lidando com os dados que são “soltos”


            procedure TForm1.Memo1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin

  Memo1.Lines.Add((Source as TDBGrid).DataSource.DataSet.FieldByName('NOME').AsString);

end;
        

O evento DragDrop possui uma variável Source, que indica o objeto origem, e como nosso TMemo só recebe de TDBGrid, fazemos um TypeCast de TObject para TDBGrid. Podemos também arrastar e soltar entre TDBGrids. Vamos preparar nosso GridDestino.

1) Preparado o GridDestino


            procedure TForm1.GridDestinoDragOver(Sender, Source: TObject; X,

            Y: Integer; State: TDragState; var Accept: Boolean);
          
          begin
          
            Accept := (Sender is TDBGrid);
          
          end;
        

Da mesma forma como o TMemo1, estamos determinando de quem o GridDestino pode receber informações.

2) Lidando com as informações do GridOrigem


            procedure TForm1.GridDestinoDragDrop(Sender, Source: TObject; X,

            Y: Integer);
          
          var
          
           Coordenadas: TGridCoord;
          
           lNome: string;
          
          begin
          
            Coordenadas := THackGrid(GridDestino).MouseCoord(X,Y);
          
            if (Coordenadas.X > 0) AND (Coordenadas.Y > 0) then
          
            begin
          
              lNome := cdsOrigemNome.AsString;
          
          
              with THackGrid(GridDestino) do
          
              begin
          
                DataSource.DataSet.MoveBy(Coordenadas.Y - Row);
          
                DataSource.DataSet.Insert;
          
                Columns.Items[-1 + Coordenadas.X].Field.AsString := lNome;
          
              end;
          
            end;
          
          end;
        

Agora pode parecer um pouco complicado, mas não é não. A classe TDBGrid possui algumas propriedades protegidas que podem ser muito úteis, mas como são protegidas não conseguimos acessá-las através da classe em si, porque não estão expostas. Mas podemos fazer um truque para acessá-las, esse truque é chamado de Hack. Para acessar a parte protegida (protected) de uma classe, criamos uma classe derivada dela, e fazemos um typecast no objeto que desejamos hackear. Na seção interface da unit, criamos uma classe que herda de TDBGrid.


            THackGrid = class(TDBGrid);
        

É através dela que conseguimos acesso à parte protegida da classe TDBGrid e atribuímos à variável Coordenadas a posição do mouse em relação ao GridDestino.

De posse das coordenadas, verificamos se o mouse está sobre alguma linha do GridDestino, estando, movendo o Data para o registro em que o mouse está sobre, e damos um insert, dessa maneira o novo registro será inserido na posição do mouse.

Arrastar e soltar entre DBGrids