Я пишу программу на C, которая принимает перетаскивание файлов. Когда он скомпилирован в 32-разрядный, он работает в любом случае. Но когда он компилируется в 64-битном, это работает только для файлов, тащили из 64-битного приложения:Перетаскивание с 32 до 64 бит
- 32-бит -> 32-бит: успех
- 64-битном -> 64-бит: успех
- 64-бит -> 32-бит: успех
- 32-бит -> 64-бит: сбой
я все еще получаю сообщение WM_DROPFILES, но DragQueryFile ничего не возвращает (количество файлов 0).
Это, кажется, проблема для множества приложений, но я хотел бы знать, есть ли обходной путь об этом.
Edit:
- Если я перетащить и падение файла из 64-разрядных исполняемого файла для моего 64-битного приложения, WPARAM имеет такие значения, как 0x000000F211C000B8 (который показывает, что нет ни одного вопроса, литого).
- Далее, не закрывая мое приложение, если я перетащил файл из 32-разрядного исполняемого файла, wParam будет иметь что-то вроде 0x0000000011C000B8 или 0xFFFFFFFF11C000B8, а это значит, что 32 бита высокого порядка недействительны.
- Если я заменил недопустимый высокий порядок на действующий из предыдущего сообщения (в этом примере это будет 0x000000F2), тогда будет работать DragQueryFile!
Итак, данные здесь, где-то, я просто не знаю, как их получить (по крайней мере, без уродливого взлома).
Edit 2:
Я не дам никакого кода, потому что я полагаю, что те, кто отвечает что-то знать об этой проблеме, которая затрагивает большое количество программного обеспечения.
------ EDIT ----------
минимальный код, который воспроизводит его
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 вызов (даже только прыгать на первой инструкции так ли) максимум 32 бит wParam будут все 1. если не вызывать его, задайте WS_EX_ACCEPTFILES exstyle самостоятельно - все старшие бит wParam будут 0
для тестового exec 32-битного блокнота, открыть диалог открытия файла и перетащить, отбросить любой файл в наше окно
Просьба указать либо C, либо C++: это может привести к привлечению downvotes, если вы сохраните его таким образом. Также теги windows API. – Bathsheba
Пожалуйста, опубликуйте [SSCCE] (http://sscce.org). –
Просто гадать здесь. По-видимому, эта особая функция имеет специальный случай для значения 0xFFFFFFFF. Если код использует эту функцию, и кто-то написал код, например '~ 0', чтобы получить это значение, тогда код может превратиться в не переносимый, когда меняются размеры' int'. – Lundin