Managing the UI state of accelerators and focus rectangles


Starting with Windows 2000, keyboard indicators such as underlined accelerators and focus rectangles (collectively known as "keyboard cues") are hidden by default, and are revealed only when you start using the keyboard. You can control this behavior from the Desktop Control Panel, under Appearance, Effects, "Hide underlined letters for keyboard navigation until I press the Alt key".

Note that this setting actually controls both underlined letters and focus rectangles, even though the text describes only one of the effects. Underlines are hidden until you press the Alt key, and focus rectangles are hidden until you either press the Alt key or press the Tab key.

Here's how it works.

There are three UI state mesages: WM_CHANGEUISTATE, WM_QUERYUISTATE and WM_UPDATEUISTATE. The third one is, in my opinion, a misnomer. It really should be called something like WM_UISTATECHANGED since it is a notification that something has happened, not a message that you send to cause something to happen.

When a dialog box or menu is displayed via a mouse click, keyboard cues are hidden; if the dialog box or menu was displayed via a keypress, then keyboard cues are visible. This decision is made by sending a WM_CHANGEUISTATE message to the root window with the UIS_INITIALIZE flag. This is done automatically by the dialog manager, but if you're doing your own custom windows, you'll have to send it yourself.

The WM_CHANGEUISTATE message bubbles up to the top-level window, which changes the window UI state accordingly, then broadcasts a WM_UPDATEUISTATE message to all its child windows to notify them that the state has changed. (Of course, if the WM_CHANGEUISTATE message has no effect—for example, hiding something that is already hidden—then the WM_UPDATEUISTATE message is optimized out since the entire operation is a no-op.)

When a window that draws keyboard cues receives a WM_UPDATEUISTATE message, it typically invalidates itself so that the cues can be redrawn/erased, depending on the new state.

At drawing time, a window that draws keyboard cues can use the WM_QUERYUISTATE message to determine which keyboard cues are visible and which are hidden, and draw its content accordingly. If focus rectangles are hidden, then the window should skip the call to the DrawFocusRect function. If keyboard underlines are hidden, then the window suppresses underlines in its text drawing. If the window uses the DrawText function, it can pass the DT_HIDEPREFIX flag to suppress the underlines. If you are responding to the WM_DRAWITEM message, then you should check for the ODS_NOACCEL and ODS_NOFOCUSRECT flags to determine whether you should draw an underline accelerator or a focus rectangle.

Finally, during execution you may discover that the user has used the keyboard to perform navigation within your control. For example, the listview control may have noticed that the user has used the arrow keys to change the selected item. When this happens, the control sends itself a WM_CHANGEUISTATE specifying which keyboard cues should be revealed. As noted above, the WM_CHANGEUISTATE message eventually causes all the windows in the window tree to receive a WM_UPDATEUISTATE message if their states need to change.

The IsDialogMessage function sends WM_CHANGEUISTATE messages as appropriate, so dialog boxes and anybody else who uses IsDialogMessage gets keyboard-cues tracking for free.

Comments (15)
  1. Raul says:

    What if you wanted to always display the underlined menu accelerators (such as VS.NET)?

  2. You should be respecting the user’s settings, not ignoring them. (If you still want to ignore them, then go ahead and ignore all these cue management messages.)

  3. Mike says:

    Paul: I think you need to do it yourself :). The VS.NET menus have nothing in common with the Win32 menus.

  4. Lorenzo says:

    What a poor choice to disable by default accelerators! Why someone at MS has taken that decision? Is the second thing I disable when I install XP (the first one is to enable the old style Start menu).

  5. boxmonkey says:

    I agree with Lorenzo. Highly annoying.

  6. Mike Dunn says:

    I’m testing out the ODS_NOACCEL flag with an owner-drawn menu, but I don’t seem to be getting the flag in all the right situations (meaning, it doesn’t match the behavior of a plain menu).

    Test case: 0-Make a dialog that has a button that shows a popup menu. 1-set focus to the button with the mouse. 2-hit the spacebar. 3-cancel the menu. 4-click the button with the mouse.

    For a plain menu, the mnemonics are shown in only case 2. For owner-drawn, the ODS_NOACCEL flag is sent in case 4 as well (and all subsequent times the menu is shown, in fact).

    Also, if you uncheck the "hide keyboard cues" option, I would expect ODS_NOACCEL to never be sent. Instead, I have to also check SystemParametersInfo(SPI_GETKEYBOARDCUES) which seems like unnecessary work.

  7. Simon Cooke says:

    Lorenzo wrote:

    ———–

    What a poor choice to disable by default accelerators! Why someone at MS has taken that decision? Is the second thing I disable when I install XP (the first one is to enable the old style Start menu).

    ———–

    Er… the accelerators aren’t disabled. The UI hints for them are just not displayed. You can make them appear at any time by hitting ALT – and they all still work just the way they did before – the UI just looks cleaner.

  8. Puckdropper says:

    Hm… I never noticed they were gone. I guess since I spend most my time in applications that ignore the settings I didn’t miss them.

    Cleaner or not, this is one feature I think should default to on. (To me, a feature is something you can turn off easily.)

    Puckdropper

  9. msemack says:

    Was the reason for hiding them by default simply to make the UI look cleaner? Or was there some other argument?

  10. Mauro says:

    when the "Hide underlined letters for keyboard navigation until I press the Alt key" option is enabled, is there a way to prevent the accelerator cues for window menus from being drawn on the window ? (useful in cases where the window is non standard)

  11. ? If you don’t want Windows drawing a menu don’t give your window a menu.

  12. Mat Hall says:

    Slightly OT, but is there any specific reason why the ampersand was chosen to signify that the next character is the accelerator (or at least that it should be underlined)? Although it’s not a common character it’s one that does get a reasonable amount of use, and it’s not uncommon to see underlined spaces in odd locations when something like "Fish & Chips" crops up as a caption.

    Why not pick something more obscure? I don’t think I’ve ever used the ¬ character for anything, and yet it’s been on every keyboard I’ve ever owned!

  13. Simon Cooke says:

    Mat Hall wrote:

    ———————-

    Slightly OT, but is there any specific reason why the ampersand was chosen to signify that the next character is the accelerator (or at least that it should be underlined)? Although it’s not a common character it’s one that does get a reasonable amount of use, and it’s not uncommon to see underlined spaces in odd locations when something like "Fish & Chips" crops up as a caption.

    ———————-

    Use "and" instead of "&" is one of the written English "Good Style Guide" bulletpoints. The only time you should ever see something like "Fish & Chips" on a dialog is in a title – and that isn’t something you put a mnemonic accelerator on. You can disable the prefix handling using a style on the static text control too, if you really need to.

    Also, you can override it just by typing "Fish && Chips".

    ———————-

    Why not pick something more obscure? I don’t think I’ve ever used the ¬ character for anything, and yet it’s been on every keyboard I’ve ever owned!

    ———————-

    It’s not on this one I’m using. Nor has it been on any others that I’ve ever owned since I left England. Although you might have a point if you suggested the use of the "^" character – although even then, you might well suggest the "~" character, and all of a sudden that became commonly used in web pages on unix systems.

  14. ElBiggus says:

    "Use "and" instead of "&" is one of the written English "Good Style Guide" bulletpoints. The only time you should ever see something like "Fish & Chips" on a dialog is in a title…"

    Unfortunately we have several departments here that have an ampersand in their internal code — P&S, M&E, H&S, and O&M to name four — and it causes a few oddities in some of our apps. In stuff we’ve developed internally we’ve tended to filter them when using them as captions, but third party apps get all manner of confused…

    (An example: Earlier today I printed a few hundred documents called "P&S xxx", and Word quite helpfully told me it was printing "PS xxx" with the S underlined.)

    It’s situations like that, where an ampersand is more than likely going to show up sooner or later, that make me wonder why they picked such a common character. (Alternatively, use && to signify an accelerator, and treat a single ampersand as a single ampersand.)

    Obviously it’s waaaay too late to change now, but it’s still strikes me as an odd decision.

  15. Norman Diamond says:
    1. > underlined accelerators and focus

      > rectangles (collectively known as "keyboard

      > cues") are hidden by default

      Not in the defaults we get from Microsoft.

      2. > Note that this setting actually controls

      > both underlined letters and focus rectangles

      Not that I could tell. I changed the setting from the default to what you call the default, and the underlines disappeared from the shortcut letters in menu bars and menu entries. However, focus rectangles continue to be displayed.

      3. I changed the setting back to the actual default. Underlines reappeared in some but not all cases, which looks like a bug. Existing windows got their underlines back under the shortcut letters in menu items but not in menu bars. Newly created windows got their underlines in both menu items and menu bars.

Comments are closed.

Skip to main content