<Norm Carlberg> wrote in message news:✉forums.embarcadero.com...
> The following link and other code are as close as I could find however
> neither work.
> I am only dragging 1 file if that will simplify any.
> Errors?
> Improvements?
> <EDIT: I am dragging to another application, not receiving a dragged file.
The "preferred" way to pass data around is to implement the IDataObject and
IDragSource interfaces in your code. Microsoft wants you to use the Win32
API DoDragDrop() function, however since you want to send data to a specific
window, that will not work as DoDragDrop() is an interactive function that
requires human action to do its work. There is no official way to get an
IDropTarget interface from a specific HWND, but there is an unofficial way
(untested):
{code:delphi}
var
DT: IDropTarget;
begin
DT := IDropTarget(GetProp(hWnd, 'OleDropTargetInterface'));
...
end;
{code}
With that (assuming it works), you can then call the IDropTarget.DragEnter()
method to ask the other app for permission to "drop" your data, and then if
allowed call the IDropTarget.Drop() to do the actual drop.
> procedure DoDropFiles(Wnd: HWND; Files: TStringList);
To future-proof the code if you ever upgrade to D2009+ later on, you should
take SizeOf(Char) into account in your calculations. That way, the code
seemlessly switches to Unicode without requiring any code changes, eg:
{code:delphi}
var
...
Run: PByte; // not PChar
...
begin
...
// number of characters per string plus one #0 terminator
Inc(Size, (Length(Files[I]) + 1) * SizeOf(Char));
...
// entire string list is terminated by another #0, add drop files
structure size too
Inc(Size, SizeOf(Char) + SizeOf(TDropFiles));
...
fWide := (SizeOf(Char) > SizeOf(AnsiChar));
...
Inc(Run, (Length(Files[I])+1) * SizeOf(Char))
...
// put a final #0 character at the end
PChar(Run)^ := #0;
end;
{code}
> PostMessage(Wnd, WM_DROPFILES, MemHandle, 0);
> // ... and finally release the memory
> GlobalFree(MemHandle);
You are freeing the memory right away, not giving the other process any
chance to use it. Either use SendMessage() instead of PostMessage() so you
know when the message has finished being processed, or else simply do not
free the memory at all. If the other window processes WM_DROPFILES
messages, then it should be calling DragFinish() to free the memory on its
end. If it does not, the memory is leaked.
Also, in order for the other window to know that it should process
WM_DROPFILES messages at all, it had to have actively called
DragAcceptFiles() on itself beforehand. There is no way for your app to
detect whether it has done that or not.
--
Remy Lebeau (TeamB)