PostMessage () успешно, но мой код обработки сообщений никогда не получает сообщение

в GUI-объекте моего приложения C++ у меня есть следующее в процедуре главного окна:

case WM_SIZE:
    {
        OutputDebugString(L"WM_SIZE received.n");
        RECT rect = {0};
        GetWindowRect(hwnd, &rect);
        if (!PostMessage(0, GUI_MSG_SIZECHANGED, w, MAKELONG(rect.bottom - rect.top, rect.right - rect.left))) {
            OutputDebugString(L"PostMessage failed.n"); // <--- never called
        }
    }

    return 0; // break;

объект GUI также имеет следующий метод getMessage ():

int GUI::getMessage(MSG & msg) {
    BOOL result = 0;

    while ((result = GetMessage(&msg, 0, 0, 0)) > 0) {
        if (msg.message > (GUI_MSG_BASE-1) && msg.message < (GUI_MSG_LAST+1)) {
            OutputDebugString(L"GUI message received.n");
            break;
        }
        else {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return result;
}

объект приложения вызывает этот метод следующим образом:

while ((result = _gui.getMessage(msg)) > 0) {
    switch (msg.message) {
        // TODO: Add gui message handlers
        case GUI_MSG_SIZECHANGED:
            OutputDebugString(L"GUI_MSG_SIZECHANGED received.n");
            _cfg.setWndWidth(HIWORD(msg.lParam));
            _cfg.setWndHeight(LOWORD(msg.lParam));
            if (msg.wParam == SIZE_MAXIMIZED)
                _cfg.setWndShow(SW_MAXIMIZE);
            else if (msg.wParam == SIZE_MINIMIZED)
                _cfg.setWndShow(SW_MINIMIZE);
            else if (msg.wParam == SIZE_RESTORED)
                _cfg.setWndShow(SW_SHOWNORMAL);
            break;
    }
}

объект приложения заинтересован в размере окна, поскольку он хранит эту информацию в файле конфигурации.

когда я запускаю это в отладчике Visual Studio, окно вывода выглядит так после изменения размера окна:

WM_SIZE received.
GUI message received.
GUI_MSG_SIZECHANGED received.
WM_SIZE received.
WM_SIZE received.
WM_SIZE received.
WM_SIZE received.
...etc...

функция PostMessage () никогда не терпит неудачу, но, похоже, отправляет только GUI_MSG_SIZECHANGED (#defined as WM_APP + 0x000d) при первой обработке WM_SIZE, которая сразу после обработки WM_CREATE.

Я не знаю, что может быть причиной этого. Я попытался использовать SendMessage и PostThreadMessage, но результат тот же. Также прочитайте документацию по обработке сообщений MSDN, но не смогли найти, что не так с моим код.

может кто-нибудь помочь?

1 ответов


взлом пользовательского цикла сообщений-это то, о чем вы когда-нибудь пожалеете. Вы попали на ранней стадии.

Не публикуйте сообщения с нулевым дескриптором окна, они могут работать только в том случае, если вы можете гарантировать, что ваша программа только когда-либо качает ваш пользовательский цикл сообщений. Вы не можете дать такую гарантию. Эти сообщения попадают в бит ведро, как только вы начинаете диалог или Windows решает перекачать цикл сообщений сам. Что происходит, когда пользователь изменяет размер окна, размер логика модальный. Windows перекачивает собственный цикл сообщений, WM_ENTERSIZEMOVE объявляет об этом. Это также является причиной того, что PostThreadMessage зло если поток способен отображать любое окно. Даже почтовый ящик смертелен. DispatchMessage не может доставить сообщение.

создайте скрытое окно, которое действует как контроллер. Теперь вы можете обнаружить GUI_MSG_SIZECHANGED в его процедуре окна, и никакие хаки в цикле сообщений не требуются. Этот контроллер нередко является основным окно вашего приложения btw.