Buttons and Input Focus

As I noted earlier in this chapter, push buttons, check boxes, radio buttons, and user-defined buttons receive the input focus when they are clicked with the mouse. The control indicates it has the input focus by a dashed line surrounding the text. When the child window control gets the input focus, the parent window loses it; all keyboard input then goes to the control rather than to the parent window. However, the child window control responds only to the Spacebar, which now functions like the mouse. This situation presents an obvious problem: Your program has lost control of keyboard processing. Let's see what we can do about it.

When Windows switches the input focus from one window (such as a parent) to another (such as a child window control), it first sends a WM_KILLFOCUS message to the window losing the input focus. The wParam parameter is the handle of the window that is to receive the input focus. Windows then sends a WM_SETFOCUS message to the window receiving the input focus, with wParam the handle of the window losing the input focus. (In both cases, wParam may be NULL, which indicates that no window has or is receiving the input focus.)

A parent window can prevent a child window control from getting the input focus by processing WM_KILLFOCUS messages. Assume that the array hwndChild contains the window handles of all child windows. (These were saved in the array during the CreateWindow calls that created the windows.) NUM is the number of child windows:

case WM_KILLFOCUS :

for (i = 0 ; i < NUM ; i++)

if (hwndChild [i] == wParam)

{SetFocus (hwnd) ;

break ;

}return 0 ;

In this code, when the parent window detects that it's losing the input focus to one of its child window controls, it calls SetFocus to restore the input focus to itself.

Here's a simpler (but less obvious) way of doing it:

case WM_KILLFOCUS :

if (hwnd == GetParent (wParam))

SetFocus (hwnd) ;

return 0 ;

Both these methods have a shortcoming, however: They prevent the button from responding to the Spacebar, because the button never gets the input focus. A better approach would be to let the button get the input focus but also to include the facility for the user to move from button to button using the Tab key. At first this sounds impossible, but I'll show you how to accomplish it with a technique called ”window subclassing“ in the COLORS1 program shown later in this chapter.