Windows 3.11 File Manager Drag and Drop Process
In Microsoft Windows 3.11, dragging files from File Manager onto an
active application window relied on a lightweight drag-and-drop
mechanism managed by SHELL.DLL. This article explains the
underlying architecture of that process, detailing how destination
applications registered to accept files, how File Manager initiated and
tracked the transfer, and how Windows dispatched the
WM_DROPFILES message to hand off file path data between
16-bit processes.
1. Target Window Registration
Before an active application could receive files from File Manager
(WINFILE.EXE), it had to notify the operating system of its
capability.
The application called the DragAcceptFiles function from
SHELL.DLL:
DragAcceptFiles(hWndTarget, TRUE);This API call altered the internal window attributes of the target
handle (hWndTarget), setting an internal flag equivalent to
the WS_EX_ACCEPTFILES style. This flag told the Windows
window manager and File Manager that the window could act as a valid
drop target.
2. Initiating the Drag from File Manager
When a user selected one or more files in File Manager and held down
the left mouse button, File Manager entered a modal mouse-tracking loop
using SetCapture.
As the mouse moved across the desktop:
- File Manager determined the window handle directly beneath the
cursor using standard Win16 hit-testing routines (such as
WindowFromPoint). - It queried whether the window beneath the cursor was registered to accept drops.
- File Manager updated the mouse cursor to provide visual feedback: displaying a document-shaped drag cursor over valid drop targets, or a circle-with-a-slash ("no drop") cursor over invalid targets.
3. Creating the
HDROP Structure and Dispatch
When the user released the mouse button over a registered target window:
- Memory Allocation: File Manager allocated a block
of globally shared memory using
GlobalAllocwith theGMEM_SHARE(orGMEM_DDESHARE) flag. - Data Structure Population: File Manager populated
this memory block with an internal structure known as
DROPSTRUCT(or a list of null-terminated strings followed by a double null character). This structure stored:- The coordinates (X, Y) where the drop occurred, relative to the target's client area.
- A flag indicating whether the drop occurred in the client or non-client area.
- An array containing the fully qualified paths of all selected files.
- Handle Creation: The handle to this global memory
block was cast as an
HDROPhandle. - Message Posting: File Manager posted the
WM_DROPFILESmessage directly to the target window’s queue:
PostMessage(hWndTarget, WM_DROPFILES, (WPARAM)hDrop, 0L);4. Application Processing and File Retrieval
Upon receiving WM_DROPFILES, the target application
processed the HDROP handle passed in wParam
using helper routines provided by SHELL.DLL:
- Querying File Count: The application determined the
total number of files dropped by passing an index of
0xFFFFFFFF(-1) toDragQueryFile:UINT fileCount = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); - Retrieving File Names: The application looped
through the indices (
0tofileCount - 1), callingDragQueryFileto copy each file path into a local buffer:char szFilePath[MAX_PATH]; DragQueryFile(hDrop, i, szFilePath, sizeof(szFilePath)); - Drop Coordinates (Optional): If the application
cared about the drop location, it called
DragQueryPoint(hDrop, &point).
5. Memory Cleanup
Because the memory block backing HDROP was allocated
globally, the receiving application was responsible for releasing it
once processing finished. The application called:
DragFinish(hDrop);DragFinish called GlobalFree on the memory
handle, releasing the resources back to the Windows 16-bit global heap
and concluding the drag-and-drop transaction.