WM_DROPFILES не вызывается на x64

Как сделать перетаскивание? На машине win32 работает без проблем, а на x64 вообще не вызывается сообщение WM_DROPFILES. В чем проблема?

static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch(msg) {
        case WM_CREATE: {   
      SetTimer(hWnd, 0, int(1000./24), NULL);
            DragAcceptFiles(hWnd, true);
            return 0;
        }
        case WM_DROPFILES: {    
            DEBUG;
            return 0;
        }
    case WM_DESTROY: 
            KillTimer(hWnd, 0);
      PostQuitMessage(0);
    break;
      return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}

        HWND hWnd; WNDCLASSEX wCs; 
        static const char* wndClassName = "WndClass";

        wCs.cbSize          = sizeof wCs;
        wCs.style           = CS_HREDRAW | CS_VREDRAW;
        wCs.lpfnWndProc     = WindowProc;
        wCs.cbClsExtra      = 0;
        wCs.cbWndExtra      = 0;
        wCs.hInstance       = hInstance;
        wCs.hIcon           = LoadIcon(hInstance, MAKEINTRESOURCE(ID_MYICON));
        wCs.hCursor         = LoadCursor(NULL, IDC_ARROW);
        wCs.hbrBackground   = NULL;
        wCs.lpszMenuName    = NULL;
        wCs.lpszClassName   = wndClassName;
        wCs.hIconSm         = LoadIcon(hInstance, MAKEINTRESOURCE(ID_MYICON));

        if (RegisterClassEx(&wCs)) {
            hWnd = CreateWindowEx(
                WS_EX_CLIENTEDGE | WS_EX_ACCEPTFILES,           // extended window style
                wndClassName,   // registered class name
                TEXT("APP"),    // and window title
                WS_OVERLAPPEDWINDOW,        // window style
                CW_USEDEFAULT, CW_USEDEFAULT, g_winw, g_winh,   
                NULL, NULL, hInstance,      // handle to application instance
                this                        // if need to take pointer
            );
            SetWindowLongPtr(hWnd, GWLP_USERDATA, (LPARAM)this);
        }
        if(hWnd==NULL) {
            MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
            return E_FAIL;
        }
        if (s_winstate==3)
            ShowWindow(hWnd, SW_MAXIMIZE);
        else
            ShowWindow(hWnd, SW_SHOWNORMAL);
        UpdateWindow(hWnd);
        mHInstance=hInstance;       
        hfont = CreateFont(15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Arial");
        SendMessage(hWnd,  WM_SETFONT, (WPARAM)hfont,  TRUE);

Я нашел в другой теме отсюда, что перетаскивание будет проблемой с x64 Перетащите из 32-разрядной версии в 64-разрядную

Разница в том, что сообщение WM_DROPFILES у меня вообще не появляется


person Gabi Fintescu    schedule 22.10.2020    source источник
comment
Невозможно воспроизвести в среде Windows 10 x64 или x86 с помощью этого кода: pastebin.com/raw/w5YMTb3Lоткуда вставляешь? Обратите внимание, что для успеха D&D оба приложения должны работать на одном уровне UAC. Например, если вы перейдете из приложения, работающего от имени администратора, в приложение, работающее от имени администратора, оно никогда не будет работать (то же самое для обратного). Или опубликуйте 100% полностью воспроизводимый код.   -  person Simon Mourier    schedule 22.10.2020
comment
@SimonMourier Примечание: чтобы D&D преуспела, оба приложения должны работать на одном уровне UAC — или, чтобы принимающее приложение вызывало ChangeWindowMessageFilter/Ex(), чтобы разрешить отправку сообщений D&D из процессов с более низкой степенью целостности. Лично я бы вообще не предлагал использовать WM_DROPFILES, это СТАРЫЙ устаревший API, Microsoft предпочитает, чтобы приложения реализовывали IDropTarget с RegisterDragDrop() вместо этого (однако он по-прежнему страдает от проблемы с UAC)   -  person Remy Lebeau    schedule 22.10.2020
comment
@RemyLebeau - я знаю, что эта функция существует, но, например, попробуйте мой пример кода. Если я добавлю этот ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD)) где-нибудь в инициализацию (проверьте, что он возвращает TRUE), скомпилирую и запущу его от имени администратора, я не получу сообщение, скажем, от перетаскивания файла из Проводника. Должен ли он работать с WM_DROPFILES?   -  person Simon Mourier    schedule 22.10.2020
comment
@SimonMourier Есть и другие сообщения, помимо WM_DROPFILES, которые участвуют в D&D на основе сообщений, которые необходимо включить в фильтре, в частности, WM_COPYGLOBALDATA и, возможно, WM_COPYDATA. Это хорошо известная проблема, и на StackOverflow есть много вопросов по этому поводу.   -  person Remy Lebeau    schedule 22.10.2020


Ответы (1)


Добавление

    ChangeWindowMessageFilter (WM_DROPFILES, MSGFLT_ADD);
    ChangeWindowMessageFilter (WM_COPYDATA, MSGFLT_ADD);
    ChangeWindowMessageFilter (0x0049, MSGFLT_ADD);

После SendMessage(hWnd, WM_SETFONT, (WPARAM)hfont, TRUE); решить проблему - спасибо.

person Gabi Fintescu    schedule 22.10.2020
comment
Лучше не пытаться угадать это. Проблема кажется не связанной с 64-битной. - person David Heffernan; 22.10.2020