August 5th, 2011

Menu item states are not reliable until they are shown because they aren't needed until then

A question arrived from a customer (with the rather unhelpful subject line Question for Microsoft) wondering why, when they call Get­System­Menu and then ask for the states of the various menu items like SC_MINIMIZE, the menu item states don’t reflect reality. The menu item states don’t synchronize with reality until the user actually opens the system menu. There is no requirement that applications keep menu item states continuously in sync. After all, that’s why we have messages like WM_INIT­MENU: To tell the application, “Whoa, we’re about to show this menu, so you might want to comb its hair and pick the food out of its teeth so it can be seen by the user.” Lazy evaluation is common, because maintaining states continuously can be expensive, and there’s no point constantly turning items on and of and on and off if the user can’t see them anyway. This is double-true for system menus, because maintaining the states continuously is not possible when the system menu is being shared across windows. The menu states are not synchronized to the window until the menu is about to be displayed. If you want to know whether the SC_MINIMIZE menu item would be enabled if the menu were shown, you can check the window styles: A window can be minimized if it has a WS_MINIMIZE­BOX and is not already WS_MINIMIZEd. Similar logic can be applied to the other menu items. Well, except for SC_CLOSE. While in most cases the window caption determines what is enabled on the menu, the Close button works backward: It is the state of the menu item that controls whether the Close button is enabled. So in the special case of SC_CLOSE, you can query the state at any time, because for that case, the menu controls the state rather than simply reflecting it. Why is SC_CLOSE so special? Here come da history. The Close button was added in Windows 95. Since versions of Windows prior to Windows 95 didn’t have a Close button, they didn’t need a style to specify whether the Close button should be enabled or not. (You don’t need a style to control something that doesn’t exist.) Windows 95 added the Close button and hooked it up to the only thing that it had available, namely, the SC_CLOSE item on the system menu. Sure, Windows 95 could have have invented a new window style, but since SC_CLOSE already existed and applications were already using it, using SC_CLOSE to control the Close button allowed old applications to reap the benefits of the new Close button automatically. It also meant that there was one less thing you had to change when porting your program to Windows 95.

Bonus chatter: You can now answer Alex Cohn’s question:

I wonder if the EnableMenuItem method will work for minimize and maximize, too. After all, these buttons also have siblings in the Alt-space menu.

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.