Buttons

Dialog boxes and controls support communication between an application and the user. A button is a control the user can click to provide input to an application.

There are several types of buttons and one or more button styles to distinguish among buttons of the same type. The user clicks a button using the mouse or keyboard. Clicking a button typically changes its visual appearance and state (from checked to cleared, for example). The system, the button, and the application cooperate in changing the button's appearance and state. A button can send messages to its parent window, and a parent window can send messages to a button. Some buttons are painted by the system, some by the application. Buttons can be used alone or in groups and can appear with or without application-defined text (a label). They belong to the BUTTON window class.

Although an application can use buttons in overlapped, pop-up, and child windows, they are designed for use in dialog boxes, where the system standardizes their behavior. If an application uses buttons outside dialog boxes, it increases the risk that the application may behave in a nonstandard fashion. Applications typically either use buttons in dialog boxes or use window subclassing to create customized buttons.

Button Types and Styles

There are five kinds of buttons:

Each type of button has one or more styles. For a table of button styles, see Button Styles.

Button States

This section discusses how selecting a button changes its state and how the application should respond. The section consists of the following topics:

Button Selection

The user can select a button in three ways: by clicking it with the mouse, by tabbing to it and then pressing the ENTER key, or (if the button is part of a group defined by the WS_GROUP style) by tabbing to the selected button in the group and using the arrow keys to move within that group. The two tabbing methods are part of the predefined keyboard interface provided by the system. For a complete description of this interface, see Dialog Boxes.

Selecting a button typically causes the following events:

Elements of a Button State

A button's state can be characterized by its focus state, push state, and check state.

Focus State

The focus state applies to a check box, radio button, push button, or owner-drawn button. A button receives the keyboard focus when the user selects it and loses the focus when the user selects another control. Only one control can have the keyboard focus at a time.

When a button has the keyboard focus, the system typically highlights the text, icon, or bitmap of a button by surrounding it with a dotted line. In addition, a push button has a heavy dark border when it has the focus. The system automatically changes the highlight for an automatic button, but the application must change the highlight for a non-automatic button by sending messages.

Push State

The push state applies to a push button, check box, radio button, or three-state check box, but does not apply to other buttons. The push state of a button can be either pushed or not pushed. When a push button (or any button with the BS_PUSHLIKE style) is pushed, the button is drawn as a sunken button. When it is not pushed, it is drawn as a raised button. When a check box, radio button, or three-state check box is clicked, the background of the button is grayed. When it is not pushed, the background of the button is not grayed.

Check State

The check state applies to a check box, radio button, or three-state check box, but does not apply to other buttons. The state can be checked, cleared, or (for three-state check boxes) indeterminate. A check box is checked when it contains a check mark, and is cleared when it does not. A radio button is checked when it contains a black dot; and is cleared when it does not. A three-state check box is checked when it contains a check mark, is cleared when it does not, and is indeterminate when it contains a grayed box. The system automatically changes the check state of an automatic button, but the application must change the check state of a non-automatic button.

Changes to a Button State

When the user selects a button, it is generally necessary to change one or more of the button's state elements. The system automatically changes the focus state for all button types, the push state for push buttons or buttons with the BS_PUSHLIKE style, and the check state for all automatic buttons. The application must make all other state changes, taking into account the button's type, style, and current state. The following list shows the state elements that must be changed for each button type:

An application can determine a button's state by sending it a BM_GETCHECK or BM_GETSTATE message; the application can set a button's state by sending it a BM_SETCHECK or BM_SETSTATE message.

Notification Messages from Buttons

When the user clicks a button, its state changes, and the button sends notification messages to its parent window. For example, a push button control sends the BN_CLICKED notification message whenever the user chooses the button. In all cases, the low-order word of the wParam parameter contains the control identifier, the high-order word of wParam contains the notification code, and the lParam parameter contains the control window handle.

Both the message and the parent window's response depend on the type, style, and current state of the button. Following are the button notification messages an application should monitor and process.

Message

Description

BN_CLICKED

The user clicked a button.

BN_DBLCLK or
BN_DOUBLECLICKED

The user double-clicked a button.

BN_DISABLE

A button is disabled.

BN_PUSHED or
BN_HILITE

The user pushed a button.

BN_KILLFOCUS

The button lost the keyboard focus.

BN_PAINT

The button should be painted.

BN_SETFOCUS

The button gained the keyboard focus.

BN_UNPUSHED or
BN_UNHILITE

The button is no longer pushed.

 

A button sends the BN_DISABLE, BN_PUSHED, BN_KILLFOCUS, BN_PAINT, BN_SETFOCUS, and BN_UNPUSHED notification messages only if it has the BS_NOTIFY style. BN_DBLCLK notification messages are sent automatically for BS_USERBUTTON, BS_RADIOBUTTON, and BS_OWNERDRAW buttons. Other button types send BN_DBLCLK only if they have the BS_NOTIFY style. All buttons send the BN_CLICKED notification message regardless of their button styles.

For automatic buttons, the system changes the push state and paints the button. In this case, the application typically processes only the BN_CLICKED and BN_DBLCLK notification messages. For buttons that are not automatic, the application typically responds to the notification message by sending a message to change the state of the button. For information about sending messages to buttons, see Messages to Buttons.

When the user selects an owner-drawn button, the button sends its parent window a WM_DRAWITEM message containing the identifier of the control to be drawn and information about its dimensions and state. For more information about this message, see Using Owner-Drawn Buttons.

Messages to Buttons

A parent window can send messages to a button in an overlapped or child window by using the SendMessage function, or it can send messages to a button in a dialog box by using the SendDlgItemMessage, CheckDlgButton, CheckRadioButton, and IsDlgButtonChecked functions.

An application can use the BM_GETCHECK message to retrieve the check state of check box or radio button. An application can also use the BM_GETSTATE message to retrieve the button's current states (the check state, push state, and focus state). To get information about a specific state, use a bitmask on the returned state value.

The BM_SETCHECK message sets the check state of a check box or radio button; the message returns zero. The BM_SETSTATE message sets the push state of a button; this message also returns zero. The BM_SETSTYLE message changes the style of a button. It is designed for changing button styles within a type (for example, changing a check box to an automatic check box). It is not designed for changing between types (for example, changing a check box to a radio button). An application should not change a button from one type to another.

A button of the BS_BITMAP or BS_ICON style displays a bitmap or icon instead of text. The BM_SETIMAGE message associates a handle to a bitmap or icon with a button. The BM_GETIMAGE message retrieves a handle to the bitmap or icon associated with a button.

An application can also use the DM_GETDEFID message to retrieve the identifier of the default push button control in a dialog box. An application can use the DM_SETDEFID message to set the default push button for a dialog box.

Calling the CheckDlgButton or CheckRadioButton function is equivalent to sending a BM_SETCHECK message. Calling the IsDlgButtonChecked function is equivalent to sending a BM_GETCHECK message.

Button Color Messages

The system provides default color values for buttons. An application can retrieve the default values for these colors by calling the GetSysColor function, or set the values by calling the SetSysColors function. The following table shows the default button-color values.

Value

Element colored

COLOR_BTNFACE

Button faces.

COLOR_BTNHIGHLIGHT

Highlight area (the top and left edges) of a button.

COLOR_BTNSHADOW

Shadow area (the bottom and right edges) of a button.

COLOR_BTNTEXT

Regular (nongrayed) text in buttons.

COLOR_GRAYTEXT

Disabled (gray) text in buttons. This color is set to 0 if the current display driver does not support a solid gray color.

COLOR_WINDOW

Window backgrounds.

COLOR_WINDOWFRAME

Window frames.

COLOR_WINDOWTEXT

Text in windows.

 

However, calling SetSysColors affects all applications, so you should not call this function to customize buttons for your application.

The system sends a WM_CTLCOLORBTN message to a button's parent window before drawing a button. This message contains a handle to the button's device context and a handle to the child window. The parent window can use these handles to change the button's text and background colors. However, only owner-drawn buttons respond to the parent window processing the message.

Button Default Message Processing

The window procedure for the predefined button control window class carries out default processing for all messages that the button control procedure does not process. When the button control procedure returns FALSE for any message, the predefined window procedure checks the messages and performs the default actions listed in the following table.

Message

Default action

BM_CLICK

Sends the button a WM_LBUTTONDOWN and a WM_LBUTTONUP message, and sends the parent window a BN_CLICKED notification message.

BM_GETCHECK

Returns the check state of the button.

BM_GETIMAGE

Returns a handle to the bitmap or icon associated with the button or NULL if the button has no bitmap or icon.

BM_GETSTATE

Returns the current check state, push state, and focus state of the button.

BM_SETCHECK

Sets the check state for all styles of radio buttons and check boxes. If the wParam parameter is greater than zero for radio buttons, the button is given the WS_TABSTOP style.

BM_SETIMAGE

Associates the specified bitmap or icon handle with the button and returns a handle to the previous bitmap or icon.

BM_SETSTATE

Sets the push state of the button. For owner-drawn buttons, a WM_DRAWITEM message is sent to the parent window if the state of the button has changed.

BM_SETSTYLE

Sets the button style. If the low-order word of the lParam parameter is TRUE, the button is redrawn.

WM_CHAR

Checks a check box or automatic check box when the user presses the plus (+) or equal (=) keys. Clears a check box or automatic check box when the user presses the minus (–) key.

WM_ENABLE

Paints the button.

WM_ERASEBKGND

Erases the background for owner-drawn buttons. The backgrounds of other buttons are erased as part of the WM_PAINT and WM_ENABLE processing.

WM_GETDLGCODE

Returns values indicating the type of input processed by the default button procedure, as shown in the following table.

 

Button style

Returns

BS_AUTOCHECKBOX

DLGC_WANTCHARS | DLGC_BUTTON

BS_AUTORADIOBUTTON

DLGC_RADIOBUTTON

BS_CHECKBOX

DLGC_WANTCHARS | DLGC_BUTTON

BS_DEFPUSHBUTTON

DLGC_DEFPUSHBUTTON

BS_GROUPBOX

DLGC_STATIC

BS_PUSHBUTTON

DLGC_UNDEFPUSHBUTTON

BS_RADIOBUTTON

DLGC_RADIOBUTTON

 

Message

Default action

WM_GETFONT

Returns a handle to the current font.

WM_KEYDOWN

Pushes the button if the user presses the SPACEBAR.

WM_KEYUP

Releases the mouse capture for all cases except the TAB key.

WM_KILLFOCUS

Removes the focus rectangle from a button. For push buttons and default push buttons, the focus rectangle is invalidated. If the button has the mouse capture, the capture is released, the button is not clicked, and any push state is removed.

WM_LBUTTONDBLCLK

Sends a BN_DBLCLK notification message to the parent window for radio buttons and owner-drawn buttons. For other buttons, a double-click is processed as a WM_LBUTTONDOWN message.

WM_LBUTTONDOWN

Highlights the button if the position of the mouse cursor is within the button's client rectangle.

WM_LBUTTONUP

Releases the mouse capture if the button had the mouse capture.

WM_MOUSEMOVE

Performs the same action as WM_LBUTTONDOWN, if the button has the mouse capture. Otherwise, no action is performed.

WM_NCCREATE

Turns any BS_OWNERDRAW button into a BS_PUSHBUTTON button.

WM_NCHITTEST

Returns HTTRANSPARENT, if the button control is a group box.

WM_PAINT

Draws the button according to its style and current state.

WM_SETFOCUS

Draws a focus rectangle on the button getting the focus. For radio buttons and automatic radio buttons, the parent window is sent a BN_CLICKED notification message.

WM_SETFONT

Sets a new font and optionally updates the window.

WM_SETTEXT

Sets the text of the button. In the case of a group box, the message paints over the preexisting text before repainting the group box with the new text.

WM_SYSKEYUP

Releases the mouse capture for all cases except the TAB key.

 

The predefined window procedure passes all other messages to the DefWindowProc function for default processing.