c++ - PostMessage() 成功但我的消息处理代码从未收到消息

标签 c++ winapi user-interface postmessage

在我的 C++ 应用程序的 GUI 对象中,我在主窗口过程中有以下内容:

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() 函数永远不会失败,但似乎只在第一次处理 WM_SIZE 时发送 GUI_MSG_SIZECHANGED(#defined as WM_APP + 0x000d),这是在处理 WM_CREATE 之后。

我不知道是什么原因造成的。我尝试使用 SendMessage 和 PostThreadMessage 但结果是一样的。还通读了 MSDN 的消息处理文档,但找不到我的代码有什么问题。

有人能帮忙吗?

最佳答案

破解自定义消息循环是您终有一天会后悔的事情。你打得早。

不要发布带有 NULL 窗口句柄的消息,它们只有在您可以保证您的程序只发送您的自定义消息循环时才能工作。你不能做出这样的保证。一旦您启动对话或 Windows 决定自行抽取消息循环,这些消息就会落入位桶中。当用户调整窗口大小时,调整大小逻辑是模态的。 Windows 泵送它自己的消息循环,WM_ENTERSIZEMOVE 宣布它。如果线程能够显示任何窗口,这也是 PostThreadMessage 邪恶 的原因。即使是 MessageBox 也是致命的。 DispatchMessage 无法传递消息。

创建一个充当 Controller 的隐藏窗口。现在您可以在其窗口过程中检测到 GUI_MSG_SIZECHANGED,并且不需要对消息循环进行任何修改。顺便说一下,该 Controller 经常是您应用程序的主窗口。

关于c++ - PostMessage() 成功但我的消息处理代码从未收到消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6486046/

相关文章:

c++ - golang 的 Swig 包装器

c++ - Visual Studio 2017 中是否有自动保存功能来处理其错误和崩溃?

c - 重新创建 Win32 的 header 是个好主意吗?

Eclipse 中的 Android GUI 布局

java - 适合在java中绘制二维笛卡尔坐标系的小部件

c++ - 加载/存储宽松原子变量和普通变量有什么区别?

c++ - 将每个内存分配大小增加固定字节数将如何影响堆碎片?

c++ - code::blocks 出现奇怪的编译器错误

c++ - 我有一段代码从 FILETIME 结构中获取持续时间。这是什么意思?

user-interface - 更用户友好的 GUI 有哪些常见元素/功能?