I am writing a C program that accepts drag-and-drop of files. When it is compiled in 32-bit, it works in any case. But when it compiled in 64-bit, it works only for files dragged from a 64-bit application:
- 32-bit -> 32-bit : success
- 64-bit -> 64-bit : success
- 64-bit -> 32-bit : success
- 32-bit -> 64-bit : fail
I still get the WM_DROPFILES message, but DragQueryFile returns nothing (the number of files is 0).
This seems to be an issue for a lot of applications but I would like to know if there is a workaround about that.
Edit:
- If I drag-and-drop a file from a 64-bit executable to my 64-bit application, wParam has a value such as 0x000000F211C000B8 (which shows that there is no cast issue).
- Next, without closing my application, if I drag the file from a 32-bit executable, wParam will have something like 0x0000000011C000B8 or 0xFFFFFFFF11C000B8, which means that the high order 32 bits are invalid.
- If I replace the invalid high order by a valid one from a previous message (in this example, this would be 0x000000F2), then DragQueryFile works!
So the data are here, somewhere, I just don't know how to retrieve them (at least without an ugly hack).
Edit 2:
I will provide no code because I assume that those who answer know something about this issue that affects a large number of softwares.
------ EDIT ----------
minimal code that reproduces it
LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WCHAR sz[32];
switch (uMsg)
{
case WM_DROPFILES:
swprintf(sz, L"%p", wParam);// look for wParam
MessageBox(0,0,sz,0);
break;
case WM_NCCREATE:
DragAcceptFiles(hwnd, TRUE);
break;
case WM_NCDESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void minimal()
{
static WNDCLASS wndcls = { 0, WindowProc, 0, 0, 0, 0, 0, 0, 0, L"testwnd" };
if (RegisterClass(&wndcls))
{
if (HWND hwnd = CreateWindowEx(WS_EX_ACCEPTFILES, wndcls.lpszClassName, 0,
WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, 0, 0, 0))
{
MSG msg;
while (0 < GetMessage(&msg, 0, 0, 0))
{
if (msg.message == WM_DROPFILES)
{
// look for msg.wParam returned by GetMessage
WCHAR name[256];
DragQueryFile((HDROP)msg.wParam, 0, name, RTL_NUMBER_OF(name));
}
DispatchMessage(&msg);
}
}
UnregisterClass(wndcls.lpszClassName, 0);
}
}
interesting that if call DragAcceptFiles (even only jump on first it instruction) high 32 bits of wParam will be all 1. if not call it, by set WS_EX_ACCEPTFILES exstyle by self - all high bits of wParam will be 0
for test can exec 32 bit notepad, open Open File Dialog and drag-drop any file to our window