What’s the difference between CreateMenu and CreatePopupMenu?


CreateMenu creates a horizontal menu bar, suitable for attaching to a top-level window. This is the sort of menu that says "File, Edit", and so on.

CreatePopupMenu creates a vertical popup menu, suitable for use as a submenu of another menu (either a horizontal menu bar or another popup menu) or as the root of a context menu.

If you get the two confused, you can get strange menu behavior. Windows on rare occasions detects that you confused the two and converts as appropriate, but I wouldn't count on Windows successfully reading your mind.

There is no way to take a menu and ask it whether it is horizontal or vertical. You just have to know.

Answers to other questions about menus:

When a window is destroyed, its menu is also destroyed. When a menu is destroyed, the entire menu tree is destroyed. (All its submenus are destroyed, all the submenu's submenus, etc.) And when you destroy a menu, it had better not be the submenu of some other menu. That other menu would have an invalid menu as a submenu!

If you remove a submenu from its parent, then you become responsible for destroying it, since it no longer gets destroyed automatically when the parent is destroyed.

It is legal for a menu to be a submenu of multiple parent menus. Be extra careful when you do this, however, because if one of the parents is destroyed, it will destroy the submenu with it, leaving the other parent with an invalid submenu.

And finally: The menu nesting limit is currently 25 on Windows XP. That may change in the future, of course. (As with window nesting, Windows 95 let you go ahead and nest menus all you wanted. In fact, you could go really evil and create an infinite loop of menus. You crashed pretty quickly thereafter, of course...)

Comments (16)
  1. Serge Wautier says:

    Menus are strange creatures in the Windows world : They are no windows, are they ? Even pop-up menus !

    What was the reason for not implementing them as good old windows ?

  2. Raymond Chen says:

    ? What would be he reason for implementing them as windows? They’re not windows bcause a menu is a menu and a window is a window.

    A menu can have more than one parent; a window can have only one parent. A child window is completely enclosed by its parent; a child menu exists next to its parent. A window can be used only by the thread that created it; any thread can use a menu.

  3. Centaur says:

    So, if I plant a symlink (errm… junk… errrm… junction point) to %SystemDrive%Documents and Settings into my Start menu…?

    (*saves all data*)

    (*experiments*)

    Ok, nothing disastrous happened. I could walk 16 levels (counting the root Start menu as 1) and then 17th Documents and Settings came up as "(empty)". Although "Programs" on the same level opened all right.

    Of course it is not a very good idea to nest menus that deep. They then take up the whole screen and are really difficult to navigate.

    On a related note, is it legal/moral/fattening to mount a volume into a subdirectory of itself? What will Explorer do when instructed to File|Delete such a mount point?

    <DISCLAIMER>I shall not be held responsible for data loss caused by anybody trying to reproduce such an experiment. Proceed on your own risk. Always have a fresh backup of the partition being experimented on.</DISCLAIMER> :)

  4. Serge Wautier says:

    > What would be he reason for implementing them as windows?

    Well… every _basic_ widget, gadget, whatever-get that I can think of is a window. By basic, I mean something that is about as old as Windows (not the latest UI thingie in the latest kewl app).

    Simply, if you ask me, as a homework, to implement menus, my first idea would be to create them as windows : It’s a rectangular area that shouldn’t be clipped in any other window (at least for pop-up menus). It needs to capture input events. It has some notion of focus. A window looks like a perfect candidate, doesn’t it ?

    I’d even go further : How can one implement a pop-up menu without making it a window ? How can you track mouse clicks on a pop-up menu (mouse capture will not work here IMO) ?

    > A menu can have more than one parent <snip>

    OK, let me clarify :

    1. I’d use a window for the visual representation. I don’t mean here the windows should be used for the internal representation of the menu.

    2. I mostly think of the implementation of pop-up menus.

  5. Raymond Chen says:

    Right, a menu uses a window for its visual representation, but the menu itself is separate from its visual representation. And when the menu isn’t visible on the screen, it has no visual representation at all.

  6. Dmitriy Zaslavskiy says:

    Raymond, could you please comment on multithreading issues in GDI and USER. Why is there requirement to "use window" only from the thread that creates it. Isn’t USER is reentrant? In general different processes can touch their window from obviously different threads, so where the requirement comming from?

    Thanks in advance.

  7. Mike Hearn says:

    Eeeek! Stuff like this really scares me:

    "Windows on rare occasions detects that you confused the two converts as appropriate, but I wouldn’t count on Windows successfully reading your mind."

    Silently detecting and correcting API errors is surely evil – it’d be better to return an error, or bail the app.

    Probably the best policy I’ve seen for this in a C API is what GTK+ does – I’m not sure how familiar you are with Linux Raymond, but GTK+ is a popular widget toolkit there, roughly it’s equivalent to user, comctl32, and richedit combined.

    GTK+ is full of non-fatal assertions. If you give it bad API data (like passing in incorrect objects, null pointers, whatever) it aborts the API call and prints as assertion error message to stderr. As developers on Linux usually run their app from the command line this is a very visible way of reporting mistakes. Having similar functionality in Win32 would not have been hard though. Why was this approach never used?

    I wonder what the .NET policy on API usage mistakes is. Throw exceptions presumably.

  8. Writing a program? Windows 95 lets you create an infinite loop of menus. Go on, be evil.

  9. Raymond Chen says:

    If you run the Debugging version of Windows you get all sorts of great debugging messages. The Application Verifier spews even more.

    Win32 tends not to "silently fix mistakes" – I myself was surprised to see it happening for menus in certain odd cases. There’s probably some compatibility story somewhere lurking behind it.

    Note that a lot of programmers *want* mistakes to be silently fixed. This is in fact a major chunk of the programming audience; we call them "Mort". Mort does not sit down and architect a program to be industrial strength. Mort pounds out code until it "mostly works" and then deploys it to his department. Mort wants mistakes to be silently fixed. Mort relies heavily on AutoComplete as a form of documentation. Mort doesn’t care that "this technique works only on English-language systems in the Eastern time zone". We have interviewed dozens of Morts – we have giant posters with descriptions of actual real-live Morts, doing their job.

    If you google for "mort, elvis and einstein" you can learn more about Mort.

  10. Raymond Chen says:

    Dmitriy: Thanks for the topic. I’ll talk about thread affinity in a future entry.

  11. Mike Hearn says:

    How do you get a debugging version of Windows though? Is that the same as a checked build? Don’t you have to pay for them? Is there any way to upgrade an existing install without wiping the whole thing?

    Is there a way to sideload checked/debugging DLLs, so you can use the same box to (for instance) play games?

  12. RichB says:

    Re: Windows, menus and focus

    Search the Internet for Raymond’s FakeMenu code and discussion. Start with:

    http://groups.google.com/groups?as_q=FakeMenu&as_uauthors=raymond%20chen

  13. Raymond Chen says:

    The Windows 3.x codebase called it the "debug build"; the Windows NT codebase calls it the "checked build". You pretty much have to dediciate a machine to it, since many of the checks happen in kernel mode. (Recall that starting in NT4, large chunks of USER32 and GDI32 were moved into kernel mode.)

  14. Rob McAfee says:

    "If you get the two confused, you can get strange menu behavior."

    The other day I mistakenly used CreateMenu (instead of CreatePopupMenu) to create an owner-drawn context menu. In this case the system ignores the client-provided sizes returned from the WM_MEASUREITEM handling code, and makes the menu about 8 pixels wide! After an hour of futile debugging, I decided to take a break and read Raymond’s site, and by pure coincidence found the answer :) CreatePopupMenu fixed everything right up.

    "It is legal for a menu to be a submenu of multiple parent menus."

    Is this documented anywhere? I couldn’t find explicit mention of this in MSDN. This does seem useful, especially in SDI applications, where you might create a unique top-level menu for each document window, but share the submenus. I’m just wondering about forward-compatibility with Longhorn, etc.

  15. Raymond Chen says:

    Commenting on this article has been closed.

  16. For making dialog controls match a menu, as if anybody even does this any more.

Comments are closed.