Sara talks about effects of “Display Properties -> Appearance -> Effects -> Hide Underline letters ..” . The check box controls two behaviors: - first the underlining of the mnemonics (keyboard accelerators), and second “startup” focus. If that checkbox is checked (which is the default in Win2k+ OSes), Windows shell keeps track of user action and determines if focus and keyboard accelerators should be visible or not. “About Keyboard Accelerators” article on MSDN talks about it (scroll all the way to the bottom, and read the section “UI State”).
Why should one keep this checkbox unchecked?
Suppose you have a bug with title “Startup focus is not defined on dialog xyz”. You start investigating the issue, and you notice that sometimes focus is present, sometimes it is not. It is very easy to overlook the fact once you used mouse, and at other times, you used keyboard to bring up your dialog. The repro steps in bug will say, “bring up the dialog” and won't say “bring up the dialog using mouse”. You would be scratching your head before you figure out that difference is due to the way of activating the dialog.
Or consider the case, you had this bug and you fixed the issue by defining the start focus, but when it comes to verification, the fix doesn't seem to work because you activated the dialog using mouse. Head banging stuff!! Hence, I always keep this checkbox unchecked and not worry about how I activate my dialog.
It also saves you time when you are defining mnemonics on your dialog. You don't have to press “Alt” key to see what all labels have mnemonics. A UI scan is sufficient.
I am owner-drawing a control and want to have a consistent behavior. How do I figure out when to paint focus rectangle and when to draw string with mnemonics underlined?
Managed Code: - There are two properties on Control, ShowFocusCues and ShowKeyboardCues, that you should pay attention to. A sample OnPaint function (C#) would look like
protected override void OnPaint(PaintEventArgs e)
if (Focused && ShowFocusCues)
To handle Keyboard accelators, you can have code similar to following to define StringFormat that you pass to Graphics.DrawString() method.
sf.HotKeyPrefix = (ShowKeyBoardCues) ? HotKeyPrefix.Show : HotKeyPrefix.Hide;
Native Code: - You can find the UI state by sending WM_QUERYUISTATE message to the control and paint according to the value returned. It is also possible that you might have to pay attention to WM_CHANGEUISTATE and WM_UPDATEUISTATE. Sorry, I don't have any sample code :-(.
Thinking of overriding the default behavior and have focus and accelators visible irrespective of the state of checkbox?
You should first answer the question “does it makes sense to override the default behavior and become inconsistent w.r.t. the platform (Windows)”? One should have very strong reasons to be UI inconsistent. UI inconsistency reflects badly on your application, confuses your users and leads to usability issues.
Yes, you can override the default behavior. One way is to owner draw everything :-). The other suggestion would be to read about and experiment with WM_CHANGEUISTATE and WM_UPDATEUISTATE on the top-level window (Hint: - If you send WM_CHANGEUISTATE message to the top level window, it sends WM_UPDATEUISTATE message to all the child windows).
Note that overriding ShowFocusCues on your toplevel form and always returning true might give you the impression that you can have focus visible irrespective of the way you activate the dialog (especially if your startup focus is on a LinkLabel). But then try setting startup focus on CheckBox with FlatSytle as System and you would realize that it doesn't work (don't forget to launch using mouse instead of keyboard while experimenting i.e. instead of hitting F5, click Debug->Start). Watch out for these pitfalls.
PS: - I do know that previous versions of VS (2002, 2003) are not consistent when it comes to keyboard accelators on menus. We have fixed it in VS 2005.