0

How to make drag & drop? On the win32 machine it works without problems but on the x64 the WM_DROPFILES message is not called at all. Where is the problem?

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);

I found in another topic from here that drag & drop would be problems with x64 Drag-and-drop from 32 to 64-bit

The difference is that the WM_DROPFILES message doesn't appear to me at all

drescherjm
  • 10,365
  • 5
  • 44
  • 64
  • Can't reproduce in a Windows 10 x64 or x86 environment with this code: https://pastebin.com/raw/w5YMTb3L where are you pasting from? Note for D&D to succeed both app need to run at same UAC level. For example if you drop from an app running as non-admin to an app running as admin, it will never work (same for reverse). Or post a 100% full reproducing code. – Simon Mourier Oct 22 '20 at 16:33
  • @SimonMourier "*Note for D&D to succeed both app need to run at same UAC level*" - or, for the receiving app to call `ChangeWindowMessageFilter/Ex()` to allow D&D messages to be sent from lower-integrity processes. Personally, I wouldn't suggest using `WM_DROPFILES` at all, it is an OLD legacy API, Microsoft prefers apps to implement [`IDropTarget`](https://docs.microsoft.com/en-us/windows/win32/api/oleidl/nn-oleidl-idroptarget) with [`RegisterDragDrop()`](https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-registerdragdrop) instead (it still suffers from the UAC issue, though) – Remy Lebeau Oct 22 '20 at 17:10
  • @RemyLebeau - I know this function exists, but for example try my sample code. If I add this `ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD))` somewhere in init (check it returns TRUE), compile, and run it as admin, I don't receive the message from a file drag from Explorer, say. Is it supposed to work with WM_DROPFILES? – Simon Mourier Oct 22 '20 at 17:26
  • @SimonMourier There are other messages besides `WM_DROPFILES` that are involved in message-based D&D that would have to be enabled in the filter, in particular `WM_COPYGLOBALDATA`, and maybe `WM_COPYDATA`. This is a well-known issue, and there are many questions about it on StackOverflow. – Remy Lebeau Oct 22 '20 at 17:31

1 Answers1

1

Adding

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

After SendMessage(hWnd, WM_SETFONT, (WPARAM)hfont, TRUE); solve the problem - thanks.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490