我正在编写一个接受文件拖放的C程序。
当以32位编译时,它在任何情况下都可以工作。但是,当它以64位编译时,它仅适用于从64位应用程序中拖动的文件:
我仍然收到WM_DROPFILES消息,但是DragQueryFile不返回任何内容(文件数为0)。
对于许多应用程序来说,这似乎是一个问题,但是我想知道是否有解决方法。
编辑:
因此,数据就在这里的某个地方,我只是不知道如何检索它们(至少没有难看的黑客手段)。
编辑2:
我不会提供任何代码,因为我假设回答的人对此问题有一定的了解,而该问题会影响大量的软件。
- - - 编辑 - - - - -
复制它的最少代码
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);
}
}
有趣的是,如果调用DragAcceptFiles(甚至只跳到它的第一个指令)wParam的高32位将全部为1。如果不调用它,则通过自行设置WS_EX_ACCEPTFILES exstyle-wParam的所有高位将为0
要进行测试,可以执行32位记事本,打开“打开文件”对话框,然后将任何文件拖放到我们的窗口中
最佳答案
问题重新开放后,我可以发布适当的答案。
这确实是Windows的错误。在64位进程中,wParam是一个64位值,按原样发送“HDROP”,它实际上是指向DROPFILES结构的指针。
测试表明,shell使用整个64位,并将数据写入堆中。
如果从32位应用程序中拖动文件,则即使堆位于以上,数据仍会正确写入堆中。但是尽管如此,在这种情况下,wParam仍转换为32位值,然后将其符号扩展为64位。
实际上,当我们将文件从32位应用程序拖到64位应用程序时,后者应该崩溃,因为我们提供了指向DragQueryFile()
的错误指针。但事实并非如此,因为DragQueryFile()
处理这些异常。
现在,解决方案:GlobalAlloc(GMEM_MOVEABLE, 0)
给出。它通常给出wParam的值(或者应该是wParam的值)+16。即使有时可能会稍高一些,这也足以检索wParam缺少的高阶32位。
为了解决堆重叠4GB边界的可能性不大的情况,我们可以尝试通过在高阶32位中添加或删除1来进行尝试。
请注意,GlobalFree()
仍然是必需的。否则,每次调用GlobalAlloc()
后,您将消耗几个字节(根据我的测试,为16个字节)。
就是说,由于符号扩展,您可能仍必须将高阶32位清零。并且该解决方案意味着安全性降低。
关于c - 从32位拖放到64位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39612616/