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;

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;,c++,winapi,user-interface,postmessage,C++,Winapi,User Interface,Postmessage,应用程序对象对窗口大小感兴趣,因为它将此信息存储在配置文件中 当我在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()函数从未失败,

应用程序对象对窗口大小感兴趣,因为它将此信息存储在配置文件中

当我在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_大小时发送GUI_MSG_SIZECHANGED(#定义为WM_APP+0x000d),这是在处理WM_CREATE之后

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


有人能帮忙吗?

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

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


创建用作控制器的隐藏窗口。现在,您可以在其窗口过程中检测GUI_MSG_SIZECHANGED,并且无需对消息循环进行任何攻击。顺便说一句,该控制器通常是应用程序的主窗口。

为什么不运行正常的消息循环呢。
GUI::getMessage
中的
while
循环到底有什么意义?您似乎有两个嵌套的消息泵!!我一点也不明白这件事。如果你运行一个普通的信息泵,你会更容易被激励去回答这个问题。从目前的情况来看,人们只能猜测还有什么奇怪的事情在发生。并且
(msg.message>(GUI\u msg\u BASE-1)和&msg.message<(GUI\u msg\u LAST+1))
而不是使用
=
在进入和离开
GUI::getMessage
函数时以及在
\u GUI.getMessage
循环之后尝试添加一些调试输出。我认为这是你的程序控制流中的问题,但我不能准确地指出嵌套消息泵的位置。@David嵌套消息泵是我试图将GUI代码和应用程序逻辑分开的结果。例如,应用程序对象实际上并不关心WM_PAINT,因此这是由GUI对象中的内部泵处理的。但是,由于GUI也是一种输入机制,因此需要将某些事情通知应用程序对象,例如当用户选择要打开的文件时,或者在这种情况下,当窗口调整大小时。。。我想我的根本问题是OO设计。。。如果对象B是对象a的成员,B如何通知a某些事件?嵌套消息泵不可能是正确的解决方案虽然我不太喜欢在我的应用程序对象中隐藏窗口的想法(因为我试图在我的GUI对象中保留GUI代码),但如果我找不到更优雅的解决方案,这可能是我最终要做的事情。请阅读我对David的回复,也许你对我的OO设计问题有一些很好的意见。我同意在模式大小调整循环期间线程消息被扔到地板上,但是第一个消息是如何通过的?:)@Frédéric-第一个可能是初始窗口创建时的WM_大小。像这样的,这很有道理。谢谢:)
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;
    }
}
WM_SIZE received.
GUI message received.
GUI_MSG_SIZECHANGED received.
WM_SIZE received.
WM_SIZE received.
WM_SIZE received.
WM_SIZE received.
...etc...