2

I don't know how, but it seems that when the main menu of a window is opened, the main message loop (PeekMessage/GetMessage, etc...) in my program stops. The behavior seems to be much like if a modal dialog was opened, because my WindowProc still gets called when messages arrive, so there must be some other message loop somewhere keeping that happening.

I don't know how that happens yet (did not test yet), which function or message blocks the main message loop, I am guessing it happens somewhere in the DefWindowProc for some message which has to do with opening the menu.

Is this the default behavior of main menu on Windows? What is really the point of this in that case? Can it be changed so that the main message loop will keep running, instead of some internal one?

Cray
  • 2,396
  • 19
  • 29
  • Yes, that's how it works. The [WM_ENTERMENULOOP](http://msdn.microsoft.com/en-us/library/windows/desktop/ms647595%28v=vs.85%29.aspx) message notifies you when Windows enters its modal menu loop. You can't avoid this other than by creating your own menu. – arx Aug 08 '12 at 18:44
  • Have any idea why have they done it this way? – Cray Aug 08 '12 at 18:56
  • This design is at least 20 years old. I guess it was the easiest and cheapest way to do it back then. And it's rarely a problem, though you've found a case where it is. – arx Aug 08 '12 at 19:08
  • 1
    @arx Your two comments are *the answer* to this question. You should post them as an answer yourself, rather than me repeating them myself. – Cody Gray - on strike Aug 08 '12 at 20:24

2 Answers2

3

I was wrong, so I've updated this answer.

Windows normally enters an internal modal message loop while it is displaying a menu. The WM_ENTERMENULOOP message notifies you when Windows enters this loop.

You can make a menu modeless by setting the MNS_MODELESS flag. For example, you can do it to window hWnd thus:

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);

Unfortunately, this causes your main window to lose activation when a menu is opened, which is visually distracting. The second part of this answer explains how menus avoid this problem in the modal case. This answer hints at a solution; you need to interfere with the WM_NCACTIVATE message so that the appearance of the main window is out of sync with its activation.

Community
  • 1
  • 1
arx
  • 16,686
  • 2
  • 44
  • 61
  • so how about MENUINFO.dwStyle|MNS_MODELESS ? – kero Feb 19 '14 at 09:24
  • 1
    @kero You're right. This affects the appearance of the window when a menu is activated so I've updated my answer to include some notes on that. – arx Feb 19 '14 at 15:25
0

For hMenuBar you can try following way: 1) MENUINFO.fMask|MIM_STYLE|MIM_APPLYSUBMENUS, 2) GetMenuInfo(hMenuBar,addr MENUINFO), 3) MENUINFO.dwStyle|MNS_MODELESS, 4) SetMenuInfo(hMenuBar,addr MENUINFO).

kero
  • 678
  • 3
  • 10