Событие перетаскивания (WM_DROPFILES) в C ++ GUI - PullRequest
0 голосов
/ 06 июля 2018

Я пытаюсь создать простое приложение, в котором пользователь может перетаскивать файлы из-за пределов окна (обычно проводника) в область внутри окна. Моя конечная цель - получить путь к файлу, который будет позже обрабатываться.

В настоящее время я могу перетаскивать файлы в область, но никогда не получаю событие 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;
}

Ответы [ 2 ]

0 голосов
/ 07 июля 2018

Вы пропали без вести

DragAcceptFiles( hwnd, TRUE );

Поместите это как раз перед циклом сообщений.

WM_DROPFILES не может правильно передать данные из 64-разрядного приложения в 32-разрядное. Может быть исправлено путем внедрения IDropTarget и удаления обработки WM_DROPFILES.

0 голосов
/ 06 июля 2018

Вы не получаете сообщение 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...