Não é a linguagem de programação que define o programador, mas sim sua lógica

Arrastar arquivos para aplicação [ TDropTarget ] | Delphi


Iremos precisar:
  • TMemo = Memo1
  • TListBox =  ListBox1
Tem que ser declarado na Unit do seu formulário na área privada a procedure

{Ela é um manipulador para mensagem da operação de drag-and-drop(arrastar-e-soltar) de arquivos:}
procedure WMDropFiles(var Msg: TMessage); message wm_DropFiles;

Acabei de descobri este recurso valioso quando procurava uma maneira mais rápida de pegar o caminho de arquivos para serem anexados em um envio de e-mail, sem precisar de um OpenDialog
procedure TFSistema.DoCreate;
begin
     inherited;
     {Ativa o recurso de arrastar e soltar arquivos sobre o aplicativo}
     DragAcceptFiles(Handle, true);
end;

procedure TFSistema.DoDestroy;
begin
     inherited;
     {Desativa o recurso de arrastar e soltar arquivos sobre o aplicativo}
     DragAcceptFiles(Handle, false);
end;

procedure TFSistema.WMDropFiles(var Msg: TMessage);
var
     I, FileCount, BufferSize: word;
     Drop: HDROP;
     FileName: string;
     Pt: TPoint;
     RctListBox, RctMemo: TRect;
begin
     { Pega o manipulador (handle) da operação "arrastar e soltar" (drag-and-drop) }
     Drop := Msg.wParam;
     { Pega a quantidade de arquivos soltos (dropped) }
     FileCount := DragQueryFile(Drop, $FFFFFFFF, nil, 0);
     { Se nenhum arquivo... }
     if FileCount = 0 then begin
          ShowMessage('Sem arquivo.');

          Exit;
     end;
     { Pega o retângulo do ListBox }
     RctListBox := ListBox1.BoundsRect;
     { Pega o retângulo do Memo }
     RctMemo := Memo1.BoundsRect;
     { Se soltou fora da área cliente do form... }
     if not DragQueryPoint(Drop, Pt) then
          ShowMessage('Arquivos soltos fora da área cliente do form')
          { Se soltou na área do ListBox... }
     else if PtInRect(RctListBox, Pt) then begin
          { Pega todos os nomes de arquivos e coloca no ListBox }
          for I := 0 to FileCount -1 do begin
              { Obtém o comprimento necessário para o nome do arquivo, sem contar o caractere nulo do fim da string. }
               BufferSize := DragQueryFile(Drop, I, nil, 0);
               SetLength(FileName, BufferSize +1); { O +1 é p/ nulo do fim da string }
               if DragQueryFile(Drop, I, PChar(FileName), BufferSize+1) = BufferSize then
                    ListBox1.Items.Add(string(PChar(FileName)))
               else
                    ShowMessage('Erro ao obter nome do arquivo.');
         end;
          { Se soltou na área do Memo... }
     end else if PtInRect(RctMemo, Pt) then begin
          { Obtém o comprimento necessário para o nome do arquivo,sem contar o caractere nulo do fim da string. O segundo parâmetro (zero) indica o primeiro arquivo da lista }
          BufferSize := DragQueryFile(Drop, 0, nil, 0);
          SetLength(FileName, BufferSize + 1); { O +1 é p/ nulo do fim da string }
          if DragQueryFile(Drop, 0, PChar(FileName), BufferSize+1) = BufferSize then
               Memo1.Lines.LoadFromFile(string(PChar(FileName)))
          else
               ShowMessage('Erro ao obter nome do arquivo.');
     end;
     Msg.Result := 0;
end;

Exemplo: Download do exemplo

11 comentários:

  1. Que bacana, parabéns Ana

    ResponderExcluir
  2. Bem legal. Só lembrar de colocar o ShellAPI no uses.

    ResponderExcluir
  3. Opa Ana, tentei vários exemplos e utilizando o seu no windows 10 não está funcionando, utilizo o delphi rio ce sabe o que pode ser?

    ResponderExcluir
    Respostas
    1. Tentou baixar o exemplo e compilar? Fiz o exemplo no Delphi 2007 se não me engano, vou testar no Delphi Rio se funciona de acordo!

      Excluir
    2. Boa tarde Ana, e aos demais, tudo bem?
      Me chamo Thiago.
      eu copiei o código e adaptei ao meu form no Delphi rio, realmente não funcionou tbm,
      porém a sua aplicação disponibilizada no 4Shared funciona perfeitamente, se puder me ajudar ficaria grato.
      Email para contato: thiagomoreira60@gmail.com
      desde já agradeço.

      Excluir
    3. Boa noite! Esta ocorrendo alguma mensagem de erro ou simplesmente não esta conseguindo arrastar?

      Excluir
  4. Incluindo a uses ShellAPI, como disse o Rafael funciona perfeitamente Ana, show vou usar, obrigado!

    ResponderExcluir
  5. Alguem fez funcionar no delphi RIO?

    ResponderExcluir
  6. No Delphi Xe8 esse código não funciona

    ResponderExcluir
  7. Alguém tem alguma solução? Eu tentei utilizar umas 5 implementações que achei aqui na internet, mais simplesmente não funcionam

    ResponderExcluir
  8. Veja se o problema não está em utilizar o delphi como administrador, depois de muito quebrar cabeça esse foi o meu problema, ja tinha testado vários, e após isso funcionou todos.

    ResponderExcluir