Simulate Drop Files with SendMessage WM_DROPFILES

nimedon

Newcomer
Joined
Nov 11, 2010
Messages
2
Do anyone has any idea of how can I drop files to another app in the background?

I have found that it can be done with SendMessage WM_DROPFILEs, but I don't know how to structure the wParam.

I also found this on MSDN
http://msdn.microsoft.com/en-us/library/bb773269(VS.85).aspx

But I still don't have any idea of how to do it,
I also found this code, but is for Delphi:

Code:
procedure DoDropFiles(Wnd: HWND; Files: TStringList);

var
  Size: Cardinal;
  DropFiles: PDropFiles;
  Run: PChar;
  MemHandle: THandle;
  I: Integer;

begin
  // first determine size of string buffer we have to allocate
  Size := 0;
  for I := 0 to Files.Count - 1 do
  begin
    // number of characters per string (as ANSI) plus one #0 terminator
    Inc(Size, Length(Files[I]) + 1);
  end;
  if Size > 0 then
  begin
    // entire string list is terminated by another #0, add drop files structure size too
    Inc(Size, 1 + SizeOf(TDropFiles));
    // allocate globally accessible memory
    MemHandle := GlobalAlloc(GHND or GMEM_SHARE, Size);
    DropFiles := GlobalLock(MemHandle);
    // fill the header
    with DropFiles^ do
    begin
      pFiles := SizeOf(TDropFiles); // offset of file list, it follows immediately the structure
      pt := Point(0, 0);            // drop point (client coords), not important here
      fNC := False;                 // is it on NonClient area }, not important here
      fWide := False;               // WIDE character switch, we pass ANSI string in this routine
    end;
    // and finally the file names
    Run := Pointer(DropFiles);
    Inc(Run, SizeOf(TDropFiles));
    for I := 0 to Files.Count - 1 do
    begin
      StrPCopy(Run, Files[I]);
      Inc(Run, Length(Files[I]));
    end;
    // put a final #0 character at the end
    Run^ := #0;
    // release the lock we have to the memory,...
    GlobalUnlock(MemHandle);
    // ...do the message...
    SendMessage(Wnd, WM_DROPFILES, MemHandle, 0);
    // ... and finally release the memory
    GlobalFree(MemHandle);
  end;
end;

procedure TMainForm.Button1Click(Sender: TObject);

var
  List: TStringList;

begin
  List := TStringList.Create;
  try
    List.Add('C:\Data\Test.txt');
    DoDropFiles(Handle, List);
  finally
    List.Free;
  end;
end;
 
Last edited:
No simulation necessary. DotNET comes with drag-drop support built in; no need for mucking around with messages.

The Control.DoDragDrop method initiates a drag-drop operation. You'll want to look at the documentation:
The Documentation said:
The allowedEffects parameter determines which drag operations can occur. If the drag operation needs to interoperate with applications in another process, data should either be a base managed class (String, Bitmap, or Metafile), or an object that implements ISerializable or IDataObject.

If you want to drag files to another application, you can populate a DataObject with a file list, then specify that as the data when you call DoDragDrop, with the appropriate DragDropEffects (probably move or copy).

Code:
someDataObject.SetFileDropList(someFileList);
DoDragDrop(someDataObject, DragDropEffects.Move);
 
thanks for your answer snarfblam, I want to do it in the background, I mean I don't want the user to need to do or see anything, do you have any idea of how can I do it? thanks again!
 
Sorry, completely missed that. I guess you can disregard my post. Off the top of my head I don't know any more about doing a file drop via messages than you do.
 
Back
Top