Last time, we looked at the confusingly-named WM_UPDATE­UI­STATE and WM_CHANGE­UI­STATE messages. But how does the whole indicator thingie get off the ground?

The default state for a window is to show all indicators. But as a special trick, the dialog manager will send a WM_UPDATE­UI­STATE message with UIS_INITIALIZE after the dialog has been initialized, which turns off the indicators if the last input event was a mouse event. This is its way of inferring whether the dialog box was triggered by a mouse or keyboard action and setting the initial indicators accordingly. (Note that if the user checked Underline keyboard shortcuts and access keys, then the dialog manager leaves the indicators enabled regardless of the last input event.)

That special WM_UPDATE­UI­STATE message is what gives dialog boxes the extra special feature of hiding the keyboard accelerators until you use the keyboard.

But notice that only the dialog manager does this. If you want this behavior in your own non-dialog windows, you will need to send the message yourself.

BOOL MyWindow::OnCreate(...)
{
 ... create and initialize any child windows ...

 // initialize indicators
 BOOL fAlwaysUnderline = FALSE;
 SystemParametersInfo(SPI_GETKEYBOARDCUES, 0,
                      &fAlwaysUnderline, 0);
 if (!fAlwaysUnderline) {
  SendMessage(this->m_hwnd, WM_UPDATEUISTATE,
              MAKEWPARAM(UIS_INITIALIZE, 0), 0);
 }
}

Exercise: Why is it important to create and initialize the child windows before sending the WM_UPDATE­UI­STATE message?

Exercise: Why can't the window manager do this automatically after WM_CREATE returns?

Exercise: Explain the behavior this customer observes.

We have a dialog box with three buttons. Sometimes the dialog displays underlines for the hotkeys, and sometimes it doesn't. I know about the feature which hides keyboard accelerators by default, but that doesn't explain why the setting gets ignored sometimes. The first time I show the dialog in my program, I get the underlines, but the second and subsequent times, I do not.