打开主菜单总是一个模态操作?

时间:2012-08-08 17:47:03

标签: windows winapi menu modal-dialog

我不知道如何,但似乎当打开一个窗口的主菜单时,程序中的主消息循环(PeekMessage / GetMessage等等)就会停止。如果打开一个模态对话框,行为似乎很像,因为我的WindowProc仍然会在消息到达时被调用,所以必须有一些其他消息循环来保持这种情况发生。

我不知道是怎么发生的(还没有测试),哪个函数或消息阻塞了主消息循环,我猜它发生在DefWindowProc的某个地方,因为某些消息与打开菜单有关。

这是Windows上主菜单的默认行为吗?在这种情况下,这究竟是什么意思?是否可以更改主消息循环将继续运行,而不是一些内部消息循环?

2 个答案:

答案 0 :(得分:3)

我错了,所以我更新了这个答案。

Windows通常在显示菜单时进入内部模态消息循环。当Windows进入此循环时,WM_ENTERMENULOOP消息会通知您。

您可以通过设置MNS_MODELESS标志使菜单无模式。例如,你可以这样做到窗口hWnd

HMENU hMenu = GetMenu(hWnd);
MENUINFO menuInfo;
menuInfo.cbSize = sizeof(MENUINFO);
menuInfo.fMask = MIM_STYLE;
GetMenuInfo(hMenu, &menuInfo);
menuInfo.fMask = MIM_STYLE;
menuInfo.dwStyle |= MNS_MODELESS;
SetMenuInfo(hMenu, &menuInfo);

不幸的是,这会导致您的主窗口在打开菜单时失去激活,这在视觉上会分散注意力。 this answer的第二部分解释了菜单在模态情况下如何避免此问题。 This answer提示解决方案;您需要干扰WM_NCACTIVATE消息,以便主窗口的外观与其激活不同步。

答案 1 :(得分:0)

对于hMenuBar,您可以尝试以下方式: 1)MENUINFO.fMask | MIM_STYLE | MIM_APPLYSUBMENUS, 2)GetMenuInfo(hMenuBar,addr MENUINFO), 3)MENUINFO.dwStyle | MNS_MODELESS, 4)SetMenuInfo(hMenuBar,addr MENUINFO)。