【问题标题】:Drag&drop event (WM_DROPFILES) in C++ GUIC++ GUI 中的拖放事件 (WM_DROPFILES)
【发布时间】:2018-07-06 07:10:05
【问题描述】:

我正在尝试创建一个简单的应用程序,用户可以在其中将文件从窗口(通常是资源管理器)外部拖放到窗口内部的区域中。我的最终目的是获取文件路径以供以后处理。

目前我可以将文件拖放到该区域,但我从未收到 WM_DROPFILES 事件。我尝试了一些相关的函数(DoDragDrop、RegisterDragDrop、CDropSource),但它们要么无法编译,要么编译不成功。

谁能告诉我是否缺少设置任何属性?

在此先感谢

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
        case WM_CREATE:
        {
            CreateWindowEx(
                WS_EX_ACCEPTFILES,
                TEXT("static"),
                TEXT("Drag and drop your file to this area"),
                WS_VISIBLE | WS_CHILD,
                20, // x
                20, // y
                120, // w
                60, // h
                hwnd, // parent window
                (HMENU) 1, // unique label
                NULL, NULL);
        }
        case WM_DROPFILES:
        {
            MessageBox(hwnd, "Dragged!", "Title", MB_OK | MB_ICONINFORMATION);
        }

        case WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }

        default:
        {
            return DefWindowProc(hwnd, Message, wParam, lParam);
        }
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG msg;

    memset(&wc,0,sizeof(wc));
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszClassName = "WindowClass";
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
        return 0;
    }

    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        "WindowClass",
        "MySimpleApp",
        WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        WINDOW_W,
        WINDOW_H,
        NULL,NULL,hInstance,NULL);

    if (hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
        return 0;
    }

    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

【问题讨论】:

    标签: c++ windows user-interface winapi drag-and-drop


    【解决方案1】:

    您没有收到WM_DROPFILES 消息,因为您没有继承您创建的 STATIC 控件来接收发送给它的消息。您假设您可以在控件的 parent 窗口中捕获消息,但这不是消息所在的位置。它被发送到您实际放置的窗口 - STATIC 控件。

    试试这个:

    LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
    {
        if (uMsg == WM_DROPFILES) {
            MessageBox(hwnd, "Dragged!", "Title", MB_OK | MB_ICONINFORMATION);
        }
        return DefSubclassProc(hwnd, uMsg, wParam, lParam);
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (uMsg)
        {
            case WM_CREATE: {
                HWND hStatic = CreateWindowEx(
                    WS_EX_ACCEPTFILES,
                    TEXT("static"),
                    TEXT("Drag and drop your file to this area"),
                    WS_VISIBLE | WS_CHILD,
                    20, // x
                    20, // y
                    120, // w
                    60, // h
                    hwnd, // parent window
                    (HMENU) 1, // unique label
                    NULL, NULL);
                SetWindowSubclass(hStatic, &StaticWndProc, 0, 0);
                break;
            }
    
            case WM_DESTROY: {
                PostQuitMessage(0);
                break;
            }
    
            default: {
                return DefWindowProc(hwnd, Message, wParam, lParam);
            }
        }
    
        return 0;
    }
    

    DoDragDrop()RegisterDragDrop()(您应该使用它们而不是WM_DROPFILES)与接收WM_DROPFILES 无关。

    【讨论】:

      【解决方案2】:

      你不见了

      DragAcceptFiles( hwnd, TRUE );
      

      把它放在消息循环之前。

      WM_DROPFILES 无法正确地将数据从 32 位应用程序传输到 64 位应用程序。可以通过实施IDropTarget 并删除WM_DROPFILES 处理来补救。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-12
        • 1970-01-01
        • 2011-09-21
        • 2017-04-28
        • 2015-03-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多