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.

Comments (10)
  1. Dan Bugglin says:

    My guess: No because it will only change the menu, not the buttons (which are tied to the window styles), and the WM_INITMENU will disable them again.  Just set the window styles.

    My second guess if the first one is wrong: Yes, but only if it was possible in Win 3.11 and some programs still rely on that behavior.

  2. David Walker says:

    Come on, "Question for Microsoft" is such a helpful, explanatory subject line for a message!

  3. Joshua says:

    That's a fascinating bit that can bite you if you don't know it's coming.

  4. Bob says:

    The "question for Microsoft" subject line is an example of a very common problem.

    For example, I edit a newsletter.  If you were to write an article for me, you might well call it "newsletter_article.doc" because that might fit your naming scheme.  Of course, that wouldn't work for me to have so many similarly named files.  I might change it to "raymond_chen.doc" which would be very helpful to identify the file in my directory.  However, it wouldn't be a useful name on your end.

  5. jader3rd says:

    I think that many would find it helpful if email clients auto created a subject, based on the contents of the email, in the event that the subject field was blank. If it were useful, more and more people wouldn't fill in the subject in the first place, and we'd get more useful email subjects.

  6. Ben Voigt says:

    @jader: If it was possible to auto-generate a quality summary, e-mail clients would display that instead of the sender-specified subject line.  It's a very very difficult problem in general though.  (Most) Humans are still better at writing human-readable summaries than any computer algorithm

  7. TC says:

    Re. "question for Microsoft":

    Every man and his dog, has at some stage written a blog post: "How To Ask Your Question Effectively". Unfortunately, the people who really need to read that post, will never actually do so. The only people who'll actually read that post, are the very people who don't need to!

  8. Jonathan says:

    jader3rd: Word does something similar for file names. When you save an untitled document, it will helpfully suggest the first few words from the document as filename. This has worked for me in many cases.

    However, for e-mail I'm afraid we'll end up with courtesies as titles: "Hello Raymond, hope you can answer this"…

  9. Grammar Nazi says:

    You stated:

    <blockquote>It also meant that there was one less thing you had to change when porting your program to Windows 95.</blockquote>

    You meant "fewer", not less. (Sorry, knee jerk for these, almost OCD level you know.)

  10. David Walker says:

    We got off topic (maybe I led us there), but the original point of the article was in line with "don't do work now that you can do later, or never do".  That's always a good idea, as long as everyone understands it.

Comments are closed.