Every window with the WS_SYSMENU style has a system menu, but it’s not there until it needs to be

I mentioned last time that there's an optimization in the treatment of the system menu which significantly reduces the number of menus in the system.

When a window has the WS_SYSMENU window style, it has a system menu, but until somebody calls Get­System­Menu on that window, nobody knows what its menu handle is. Until that point, the window manager doesn't actually have to commit to creating a menu for the window; it can just pretend that the window has one. (This technique goes by the fancy name lazy initialization.)

The window manager creates a global default system menu which contains the standard system menu items. If somebody presses Alt+Space or otherwise calls up the system menu for a window that has never had Get­System­Menu called on it, the window manager just uses the global default system menu, since it knows that nobody has customized the menu. (You can't customize a menu you don't have the handle to!) Since most people never customize their system menu, this optimization avoids cluttering the desktop heap with identical copies of the same menu. This was a particularly important optimization back in the 16-bit days, when all window manager objects had to fit into a single 64KB heap (known as System Resources).

If you are really sneaky, you can catch a glimpse of the elusive global default system menu as it whizzes by: As with any other popup menu, the handle to the menu being displayed is passed to your window's WM_INIT­MENU­POPUP, and if your program has never called Get­System­Menu, the handle that you will see is the global default system menu. Mind you, you can't do much to this menu, since the window manager blocks any attempt to modify it. (Otherwise, your program's menu modification would have an unintended effect on the menus of other programs!)

Therefore, if your program is in the habit of modifying its system menu in its WM_INIT­MENU­POPUP handler, you should stick a dummy call to Get­System­Menu in your WM_CREATE handler to force your system menu to change from a pretend system menu to a real one.

Comments (5)
  1. Anonymous says:

    you could also brute force though all possible menu handles and change all of them in some way. when you then open the system menu you would see that it did not change although you changed very single menu that exists!

  2. Anonymous says:

    Looks like Adam Rosenfield was right on the money!

  3. Anonymous says:

    ‘This was a particularly important optimization…’: Although perhaps to a lesser degree, such optimisations are still important. I know that premature optimisation is the root of all evil, but that doesn't mean that people shouldn't write tight code; especially memory consumption is important to pay attention to since it's too easy to negatively impact not just yourself with cache misses and swapping, but other processes too. I always get depressed a little when I see version 10 of some software run more slowly on today's hardware than version 3 did in the 90s.

  4. Anonymous says:

    Makes me wonder if some apps that change the system menu globally (like the nVidia nView stuff) modify the "pseudo-system menu" once or do GetSystemMenu for every window that's created.

    Might explain why desktop heaps get depleted fast on XP if every window has the system menu optimization disabled and you have a lot of windows open.

  5. Anonymous says:

    @Worf – I shudder to think. You can be sure that any app writer who's totally convinced you need to see evidence of their cleverness just everywhere you turn doesn't care too much about being a good citizen.

Comments are closed.