【发布时间】:2011-09-23 02:00:42
【问题描述】:
在我的 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 的消息处理文档,但找不到我的代码有什么问题。
有人可以帮忙吗?
【问题讨论】:
-
你为什么不运行一个正常的消息循环。
GUI::getMessage中的while循环到底有什么意义?您似乎有两个嵌套的消息泵!我根本无法理解这一点。如果您运行正常的消息泵,则更有动力尝试回答问题。就目前而言,人们只能猜测发生了什么其他怪事。 -
和
(msg.message > (GUI_MSG_BASE-1) && msg.message < (GUI_MSG_LAST+1))而不是使用>=和<=?为什么? -
尝试在进入和离开
GUI::getMessage函数以及围绕_gui.GetMessage循环之后添加一些调试输出。我认为这是您的程序控制流中的问题,但我无法确定确切的位置。 -
@David 嵌套消息泵是我试图将 GUI 代码和应用程序逻辑分开的结果。例如,应用程序对象实际上并不关心 WM_PAINT,因此它由 GUI 对象中的内部泵处理。但是,由于 GUI 也是一种输入机制,因此需要通知 app 对象某些事情,例如当用户选择要打开的文件时,或者在这种情况下,当调整窗口大小时......我猜我的底层问题是OO设计...如果对象B是对象A的成员,B如何通知A某些事件?
-
嵌套消息泵无法正确解决
标签: c++ winapi user-interface postmessage