8.4.1 Buttons

A button is a small window used for simple yes or no, on or off types of input. Following are some of the most common types of buttons:

Push buttons

Default push buttons

Check boxes

Radio buttons

Owner-drawn buttons

Group boxes

8.4.1.1 Push Buttons

A push button is a button that the user can select to carry out a specific action. The button contains text that indicates what that button does. When the user clicks a push button, the application usually carries out the associated action immediately. For example, if the user clicks the Cancel button in a dialog box, the application immediately removes the dialog box and cancels the user's changes to the dialog box (if any).

To create a button, specify BUTTON as its window class and specify the button style(s) in the dwStyle parameter. For example, the following call to the CreateWindow function creates a push button that has the label Cancel:

HWND hCancelButton;
    .
    .
    .

hCancelButton = CreateWindow(
    "BUTTON", "Cancel",
    BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
    20,40, 80,20, hWnd, IDCANCEL, hinst, NULL);

Because this example specifies the WS_VISIBLE style, Windows displays the push button after creating it. The control identifier of the push button is IDCANCEL. This constant is defined in the WINDOWS.H header file and is intended to be used with Cancel push buttons.

8.4.1.2 Default Push Buttons

A default push button typically allows the user to signal the completion of some activity, such as filling in an edit control with a filename. A default push button, as with other buttons, responds to both mouse and keyboard input. If the user clicks the button, the button sends a BN_CLICKED notification message to the parent window. The button need not have the input focus in order to respond to mouse input. It does require the focus, however, to respond to keyboard input. So that the user can call the keyboard, call the SetFocus function to give the input focus to the button. The user can then press ENTER or the SPACEBAR to direct the button to send a BN_CLICKED notification message to the parent window.

Creating a default push button is similar to creating a push button. Specify BUTTON as the window class of the button, and specify the button style(s) in the dwStyle parameter. For example, the following call to the CreateWindow function creates a default push button that has the label OK:

HWND hDefButton;
    .
    .
    .

hDefButton = CreateWindow(
    "BUTTON", "OK",
    BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE,
    20,40, 80,20, hWnd, IDOK, hinst, NULL);

Since this example specifies the WS_VISIBLE style, Windows displays the default push button after creating it. The control identifier is IDOK. This constant is defined in the WINDOWS.H header file and is intended to be used with default push buttons, such as this OK button.

8.4.1.3 Check Boxes

A check box typically allows the user to select an option to use in the current task. By convention, within a group of check boxes, the user can select more than one option. (To present options that are mutually exclusive, use radio buttons instead of check boxes.)

For example, you might present a group of check boxes from which the user selects font properties for the next output operation. The user could select both bold and italic by checking both the Bold and the Italic check boxes.

To create a check box, use the BS_CHECKBOX style, as in the following example:

#define IDC_ITALIC    201
HWND hCheckBox;
    .
    .
    .

hCheckBox = CreateWindow("BUTTON", "Italic",
    BS_CHECKBOX | WS_CHILD | WS_VISIBLE,
    20,40, 80,20, hWnd, IDC_ITALIC, hinst, NULL);

In this example, the check box label is Italic and the control identifier is IDC_ITALIC.

A check box responds to mouse and keyboard input much as a push button would. That is, it sends a notification message to the parent window when the user clicks the check box or presses the SPACEBAR. However, a check box can display a check (an X) in its box to show that it is currently selected.

To display a check in a check box, send the control the BM_SETCHECK message. You can also determine whether the check box is already checked by sending the BM_GETCHECK message. For example, to place a check in the check box, use the following function:

SendMessage(hCheckBox, BM_SETCHECK, 1, 0L);

This means you can select or clear a check box whenever you want; for example, when the parent window procedure receives a BN_CLICKED notification message. Windows also provides a BS_AUTOCHECKBOX style that automatically changes its state (selects or clears it) each time the user clicks it.

8.4.1.4 Radio Buttons

Although radio buttons work in much the same way as check boxes, they are usually used in groups and represent mutually exclusive options. For example, you might use a group of radio buttons to allow the user to specify text alignment (right-aligned, left-aligned, or centered). The user could then select only one type of alignment at a time.

Create a radio button as you would any button. Specify BUTTON as the window class of the radio button, and specify the button style(s) in the dwStyle parameter. For example, the following call to the CreateWindow function creates a radio button that has the label Right:

HWND HRightJustifyButton
#define IDC_RIGHTJUST
   .
   .
   .

hRightJustifyButton = CreateWindow("BUTTON", "Right",
    BS_RADIOBUTTON | WS_CHILD | WS_VISIBLE,
    20, 40, 80, 20, hWnd, IDC_RIGHTJUST, hinst, NULL);

As you do with a check box, you must send a BM_SETCHECK message to the radio button to display a check (actually, a solid circle) in the radio button when the user selects that button. Also, since radio buttons represent mutually exclusive choices, you should also send the BM_SETCHECK message to the previously selected radio button (if any) to clear it. You can determine which radio button in a group is selected by sending the BM_GETCHECK message to each button.

You can create radio buttons in a dialog box by using the BS_AUTORADIOBUTTON style. When all the radio buttons in a group box have this style, Windows automatically clears the previously selected button when the user selects a different radio button.

You can also use the CheckRadioButton function to select a radio button and clear other buttons in a dialog box. When you call CheckRadioButton, you specify the identifiers of the first and last buttons in a range of radio buttons and the identifier of the button (within that range) that is to be selected. Windows clears all the buttons in the specified range and then selects the appropriate radio button. For example, in a group of radio buttons representing types of text alignment, you might call CheckRadioButton to select the Right button, as in the following example:

CheckRadioButton(hDlg, ID_RIGHTLEFTJUST, ID_LEFTJUST,
    ID_RIGHTJUST)

In this example, CheckRadioButton would select the radio button identified by ID_RIGHTJUST and clear all the other buttons whose identifiers fall within the range specified by ID_RIGHTLEFTJUST and ID_LEFTJUST, regardless of whether they are radio buttons.

8.4.1.5 Owner-Drawn Buttons

An owner-drawn button is similar to other buttons, except that the application is responsible for maintaining the button's appearance, including whether the button has the input focus, is disabled, or is selected. Windows notifies your application when the button has been clicked.

To create an owner-drawn button, use the BS_OWNERDRAW style, as in the following example:

hMyOwnButton = CreateWindow("BUTTON", NULL,
    BS_OWNERDRAW | WS_CHILD | WS_VISIBLE,
    20, 40, 30, 12, hWnd, ID_MYBUTTON,
    hinst, NULL);

Whenever the button must be drawn, Windows sends the WM_DRAWITEM message to the window that owns the button. The lParam parameter of the WM_DRAWITEM message contains a pointer to a DRAWITEMSTRUCT structure. This structure contains, among other information, the control identifier, a value specifying the type of drawing action required, a value indicating the state of the button, a bounding rectangle for the button, and a device-context handle for the button.

In response to the WM_DRAWITEM message, your application must perform the following actions before returning from processing the message:

1.Determine the type of drawing that is required. To do so, the application examines the itemAction member of the DRAWITEMSTRUCT structure.

2.Draw the button appropriately, using the bounding rectangle and device context obtained from DRAWITEMSTRUCT.

3.Restore all graphics device interface (GDI) objects selected for the button's device context.

For example, if the button has lost the input focus, Windows sets the itemAction member of DRAWITEMSTRUCT to ODA_FOCUS but does not set the ODS_FOCUS bit in the itemState member. This is your application's cue to redraw the button so that it no longer appears to have the focus.

8.4.1.6 Group Boxes

Group boxes are rectangles that enclose two or more related buttons or other controls. You can send the WM_SETTEXT message to the group box to place a label in the upper-left corner of the box. Group boxes do not respond to user input; that is, they do not generate notification messages.