Tab Stops and Groups

In Chapter 6, we used window subclassing to add a facility to COLORS1 that let us move from one scroll bar to another by pressing the Tab key. In a dialog box, window subclassing is unnecessary: Windows does all the logic for moving the input focus from one control to another. However, you have to help out by using the WS_TABSTOP and WS_GROUP window styles in the dialog box template. For all controls that you want to access using the Tab key, specify WS_TABSTOP in the window style. If you refer back to the table on page 415, you'll notice that many of the controls include WS_TABSTOP as a default, while others do not. Generally the controls that do not include WS_TABSTOP style (particularly the static controls) should not get the input focus because they can't do anything with it. Unless you set the input focus to a specific control in a dialog box during processing of the WM_INITDIALOG message and return FALSE from the message, Windows sets the input focus to the first control in the dialog box that has the WS_TABSTOP style.

The second keyboard interface that Windows adds to a dialog box involves the cursor movement keys. This interface is of particular importance with radio buttons. After you use the Tab key to move to the currently checked radio button within a group, you need to use the cursor movement keys to change the input focus from that radio button to other radio buttons within the group. You accomplish this by using the WS_GROUP window style. For a particular series of controls in the dialog box template, Windows will use the cursor movement keys to shift the input focus from the first control that has the WS_GROUP style up to (but not including) the next control that has the WS_GROUP style. Windows will cycle from the last control in a dialog box to the first control if necessary to find the end of the group.

By default, the controls LTEXT, CTEXT, RTEXT, and ICON include the WS_GROUP style, which conveniently marks the end of a group. You often have to add WS_GROUP styles to other types of controls.

Let's look at the dialog box template in ABOUT2.RC:

AboutBox DIALOG 20, 20, 140, 188

STYLE WS_POPUP | WS_DLGFRAME

{

CTEXT "About2" -1, 0, 12, 140, 8

ICON "About2" -1, 8, 8, 0, 0

CTEXT "About Box Demo Program" -1, 4, 36, 130, 8

CTEXT "" IDD_PAINT, 68, 54, 60, 60

GROUPBOX "&Color" -1, 4, 50, 54, 112

RADIOBUTTON "&Black" IDD_BLACK, 8, 60, 40, 12, TABGRP

RADIOBUTTON "B&lue" IDD_BLUE, 8, 72, 40, 12

RADIOBUTTON "&Green" IDD_GREEN, 8, 84, 40, 12

RADIOBUTTON "Cya&n" IDD_CYAN, 8, 96, 40, 12

RADIOBUTTON "&Red" IDD_RED, 8, 108, 40, 12

RADIOBUTTON "&Magenta" IDD_MAGENTA, 8, 120, 40, 12

RADIOBUTTON "&Yellow" IDD_YELLOW, 8, 132, 40, 12

RADIOBUTTON "&White" IDD_WHITE, 8, 144, 40, 12

GROUPBOX "&Figure" -1, 68, 120, 60, 40, WS_GROUP

RADIOBUTTON "Rec&tangle" IDD_RECT, 72, 134, 50, 12, TABGRP

RADIOBUTTON "&Ellipse" IDD_ELL, 72, 146, 50, 12

DEFPUSHBUTTON "OK" IDOK, 20, 168, 40, 14, WS_GROUP

PUSHBUTTON "Cancel" IDCANCEL, 80, 168, 40, 14, WS_GROUP

}

To simplify the appearance of the template, an identifier is defined in ABOUT2.RC that combines WS_TABSTOP and WS_GROUP:

#define TABGRP (WS_TABSTOP | WS_GROUP)

The four controls that have the WS_TABSTOP style are the first radio buttons of each group (explicitly included) and the two push buttons (by default). When you first invoke the dialog box, these are the four controls you can move among using the Tab key.

Within each group of radio buttons, you use the cursor movement keys to change the input focus and the check mark. For example, the first radio button of the Color group (Black) and the group box labeled Figure have the WS_GROUP style. This means that you can use the cursor movement keys to move the focus from the Black radio button up to (but not including) the Figure group box. Similarly, the first radio button of the Figure group (Rectangle) and DEFPUSHBUTTON have the WS_GROUP style, so you can use the cursor movement keys to move between the two radio buttons in this group: Rectangle and Ellipse. Both push buttons get a WS_GROUP style to prevent the cursor movement keys from doing anything when the push buttons have the input focus.

You'll notice when using ABOUT2 that the dialog box manager in Windows performs some magic in the two groups of radio buttons. As expected, the cursor movement keys within a group of radio buttons shift the input focus and send a WM_COMMAND message to the dialog box procedure. But when you change the checked radio button within the group, Windows also assigns the newly checked radio button the WS_TABSTOP style. The next time you tab to that group, Windows will set the input focus to the checked radio button.

An ampersand (&) causes the letter that follows to be underlined and adds another keyboard interface. You can move the input focus to any of the radio buttons by pressing the underlined letter. By pressing C (for the Color group box) or F (for the Figure group box), you can move the input focus to the currently checked radio button in that group.

Although programmers normally let the dialog box manager take care of all this, Windows includes two functions that let you search for the next or previous tab stop or group item. These functions are:

hwndCtrl = GetNextDlgTabItem (hDlg, hwndCtrl, bPrevious) ;

and:

hwndCtrl = GetNextDlgGroupItem (hDlg, hwndCtrl, bPrevious) ;

If bPrevious is TRUE, the functions return the previous tab stop or group item; if FALSE, they return the next tab stop or group item.