The Unofficial Newsletter of Delphi Users - by Robert Vivrette




Drag File Helper Component

by Grahame Marsh - gsmarsh@aol.com

I recently sent two components to UNDU which allowed files (strictly file path names) to be dropped on to Delphi forms or controls, and a third that responded to those dropped on the application's icon.  Robert described these controls as "to and from" whereas they are actually for "to" only.

So here's a "from" solution as well!

This component allows a drag operation to be started on a control, and a list of files to be dropped into another application.  But before I go on I must give a severe health warning:

Why doesn't it work with Win 95? And so what use is it?  It doens't operate with Win 95 because it uses an old drag and drop mechanism for filename transfer and not the new COM interface stuff.  Microsoft obviously don't want us to use it and have not enabled it within Win 95.  The value of it is that it is very simple and does permit the transfer of filenames between, at least, our own applications, and with anyone else who has used the mechanism.  It is difficult to say whether it will be deleted in the future from Windows, but it is currently there for backward compatiblity.  Lastly it is THE mchanism for drag and drop filenames under Windows 3.1 so Delphi 1 users can use it fully.

If you had looked through the Drop components you would have seen that they are triggered by the receipt of a WM_DROPFILES message; wParam contains a handle to a memory block which contains the dropped filename information.  To be a drag source we must make this happen by generating the filename list and sending it with a WM_DROPFILES message to a window that says it's prepared to accept the data.

The drag source component waits for left mouse button to be pressed and it's in the left mouse button handler where all of the action takes place.  For the drag to proceed we need several conditions:

The last point is interesting, the API provides a useful call which is DragDetect. This function returns true is the mouse to be moved outside of a small area around the initial click point while the left button is down, or else returns false.  Borland don't appear to use it in the VCL drag and drop operations which is strange as it allows easy separation of Click and Drag operations.

I obtain the file list from the application by means of an event which requires the application to put the names into a string list.  Thus the control used to initiate the drag does not have to provide the strings itself, but often will be.

To detect if a window can accept the data you test the WS_EX_ACCEPTFILES style flag (it is here that Win 95 fails to work as none of its own windows have this flag set).  If the window will not accept the files the the cursor is changed to crNoDrop, if it will then to crDrag, and to be slightly posh to crMultiDrag if more than one filename is being dragged.

The drag operation ends with either the left mouse button being released, or, cancelled by the right button clicked or Esc pressed.  If the left button was released over a window that says it can accept the files then it is only now left to package up the data and send it off.  It is here that we get into undocumented windows with this record:

The size member is set to the size of this structure (SizeOf (TDropFiles)), the MousePos to the x- and y-coordinates relative to the client area of the drop window, and InNCArea is true if the the mouse was in the windows non-client area when released.  This structure is immediately followed by the file pathnames, each are zero (#0) terminated and a zero length path name shows there are no more to follow.  The handle to the this memory block is posted to the accepting window using a WM_DROPFILES message.  It is the duty of the accepting window to free the memory block, not ours.

The zip file contains the full source, a dcr file and a simple demo. Click here to download it.

That is just about it, having indicated that this in the "wrong" way to drag and drop in win 95 I suppose I should write something for UNDU on the "right" way which is using COM interfaces.

Enjoy!

Grahame

References:
    -  Undocumented Windows, Schulman et al, Addison Wesley, 0-201-60834-0
    -  Windows 3.1: A Developers Guide, Richter, M&T Books, 1-55851-276-4