Drag and Drop

Post date: Mar 9, 2010 12:08:22 PM

Drag 'n' drop single or multiple files into your application to load the filename(s) into an array of pChar.

Add ShellAPI and Messages to your project's uses:

uses
    ShellAPI, Messages;

Add a method to your form that handles the WM_DROPFILES message.

For example, the following would be placed in the TForm1 declaration in the protected section:

protected
    procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;

Drag 'n' drop are activated by calling:

DragAcceptFiles(Handle, true);

and deactivated by calling:

DragAcceptFiles(Handle, false);

It is normal to activate drag 'n' drop in the OnCreate event, and deactivate it in the OnClose or OnDestroy events:

procedure TForm1.FormCreate(Sender: TObject);
begin
  DragAcceptFiles(Handle, true);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DragAcceptFiles(Handle, false);
end;

This first procedure will enable you to drop files one at a time:

procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
var filename: PChar;
    length: LongWord;
begin
  length:= DragQueryFile(Msg.Drop, 0, NIL, 0);
  filename:= StrAlloc(length+1);
  DragQueryFile(Msg.Drop,0,filename,length+1);
  {do something with filename}
  Msg.Result:=0;
  inherited;
end;

This second procedure will enable you to drop multiple files at one time:

procedure TForm1.WMDropFiles(var Msg: TWMDropFiles);
var length, num, i: LongWord;
    filenames: array of PChar;
begin
  number:=DragQueryFile(Msg.Drop,$ffff,nil,0);
  SetLength(filenames,number);
  for i:=0 to n-1 do begin
    length:=DragQueryFile(Msg.Drop,i,nil,0);
    filenames[i]:=StrAlloc(length+1);
    DragQueryFile(Msg.Drop,i,filenames[i],length+1);
  end;
  {do whatever you want with the array filenames}
  Msg.Result:=0;
  inherited;
end;