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

? 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.

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

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.

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.

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?

"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?

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.

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?

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

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.