zntg/addons/drop/drop_windows.c
Sander Schobers 3c89748eac Added drag & drop addon.
- Drop addon is based on WM_DROPFILES, dragdrop addon is based on the OLE IDragDrop interface and thus can registerer more interactions.
- The allg5ui implementation will try to fall back on the drop addon (because the dragdrop addon wouldn't work properly).
- Drop addon is refactored to use the same interface as the dragdrop addon.
2021-06-04 17:17:22 +02:00

64 lines
1.5 KiB
C

#include <Windows.h>
#include <shellapi.h>
#include <stdint.h>
#include "_cgo_export.h"
#define droppedFilePathSize 32767
BOOL dropHookInitialized = FALSE;
HHOOK nextHook;
LRESULT CALLBACK DragAndDropHook(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam)
{
if (nCode < 0 || wParam == 0)
return CallNextHookEx(nextHook, nCode, wParam, lParam);
LPMSG message = (LPMSG)lParam;
switch (message->message)
{
case WM_DROPFILES:
{
wchar_t droppedFilePath[droppedFilePathSize];
clearDrop();
HDROP drop = (HDROP)message->wParam;
UINT numberOfFiles = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
for (UINT fileIndex = 0; fileIndex < numberOfFiles; fileIndex++)
{
UINT length = DragQueryFileW(drop, fileIndex, droppedFilePath, droppedFilePathSize);
addDroppedFile(&droppedFilePath[0], length);
}
POINT position;
DragQueryPoint(drop, &position);
dropFinished(position.x, position.y);
}
break;
}
return CallNextHookEx(nextHook, nCode, wParam, lParam);
}
void initDropHook(HWND windowHandle)
{
if (dropHookInitialized == TRUE)
return;
DWORD threadId = GetWindowThreadProcessId(windowHandle, NULL);
nextHook = SetWindowsHookEx(WH_GETMESSAGE, DragAndDropHook, NULL, threadId);
dropHookInitialized = TRUE;
}
void SetDragAndDropHook(void *window)
{
HWND windowHandle = (HWND)window;
initDropHook(windowHandle);
DragAcceptFiles(windowHandle, TRUE);
}