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.
What if you wanted to always display the underlined menu accelerators (such as VS.NET)?
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.)
Paul: I think you need to do it yourself :). The VS.NET menus have nothing in common with the Win32 menus.
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).
I agree with Lorenzo. Highly annoying.
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.
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.
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
Was the reason for hiding them by default simply to make the UI look cleaner? Or was there some other argument?
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)
? If you don’t want Windows drawing a menu don’t give your window a menu.
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!
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.
"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.
> 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.