Jump to content

PMGuide - Button Controls: Difference between revisions

From EDM2
 
(One intermediate revision by the same user not shown)
Line 83: Line 83:
===Default Button Behavior===
===Default Button Behavior===
Following are the messages processed by the predefined button-control window class (WC_BUTTON). Each message is described in terms of how a button control responds to that message.
Following are the messages processed by the predefined button-control window class (WC_BUTTON). Each message is described in terms of how a button control responds to that message.
<PRE>
 
┌─────────────────────────┬───────────────────────────────────┐
{| class="wikitable"
│Message                  │Description                        │
|+ Button Messages and Descriptions
├─────────────────────────┼───────────────────────────────────┤
|-
│BM_AUTOSIZE              │Causes the buttons in a new-style
! Message !! Description
│                        │notebook to automatically size to
|-
│                        │fit their contents.               │
| BM_AUTOSIZE || Causes the buttons in a new-style notebook to automatically size to fit their contents.
├─────────────────────────┼───────────────────────────────────┤
|-
│BM_CLICK                │Sends a WM_BUTTON1DOWN and         │
| BM_CLICK || Sends a WM_BUTTON1DOWN and WM_BUTTON1UP message to itself to simulate a user button selection.
│                        │WM_BUTTON1UP message to itself to
|-
│                        │simulate a user button selection.
| BM_QUERYCHECK || Returns the checked state of the button.
├─────────────────────────┼───────────────────────────────────┤
|-
│BM_QUERYCHECK            │Returns the checked state of the   │
| BM_QUERYCHECKINDEX || Returns the 0-based index to the selected button in a group. Returns -1 if no button in the group is selected or if the button receiving the message is not a radio button or an auto-radio button.
│                        │button.                           │
|-
├─────────────────────────┼───────────────────────────────────┤
| BM_QUERYHILITE || Returns the highlighted state of the button.
│BM_QUERYCHECKINDEX      │Returns the 0-based index to the   │
|-
│                        │selected button in a group.       │
| BM_SETCHECK || Sets the checked state of the button and returns the previous checked state.
│                        │Returns -1 if no button in the     │
|-
│                        │group is selected or if the button
| BM_SETDEFAULT || Sets the default button state and redraws the button.
│                        │receiving the message is not a     │
|-
│                        │radio button or an auto-radio     │
| BM_SETHILITE || Sets the highlighted state of the button and returns the previous highlighted state.
│                        │button.                           │
|-
├─────────────────────────┼───────────────────────────────────┤
| WM_BUTTON1DBLCLK || Highlights the button and sends a BN_DBLCLICKED notification code when the button-up message arrives.
│BM_QUERYHILITE          │Returns the highlighted state of   │
|-
│                        │the button.                       │
| WM_BUTTON1DOWN || Sets the button window so it can capture mouse input.
├─────────────────────────┼───────────────────────────────────┤
|-
│BM_SETCHECK              │Sets the checked state of the     │
| WM_BUTTON1UP || If the button window is set to capture mouse input, and if the mouse pointer is inside the button window when the mouse button is released, this message releases the mouse and sends a notification message to the owner window. If the button is a push button, the push button control posts a WM_COMMAND message; otherwise, the button control sends a WM_CONTROL message with the BN_CLICKED notification code.
│                        │button and returns the previous   │
|-
│                        │checked state.                     │
| WM_CHAR || Sets the button window so it can capture mouse input when the spacebar is pressed; releases the mouse when the spacebar is released. Passes other key messages to the default window procedure.
├─────────────────────────┼───────────────────────────────────┤
|-
│BM_SETDEFAULT            │Sets the default button state and
| WM_CREATE || Validates the requested button style and sets the window text.
│                        │redraws the button.               │
|-
├─────────────────────────┼───────────────────────────────────┤
| WM_DESTROY || Frees the memory containing the window's text.
│BM_SETHILITE            │Sets the highlighted state of the
|-
│                        │button and returns the previous   │
| WM_ENABLE || Sent when an application changes the enabled state of a window.
│                        │highlighted state.                 │
|-
├─────────────────────────┼───────────────────────────────────┤
| WM_MATCHMNEMONIC || Returns TRUE if mp1 matches a mnemonic in the control window's text.
│WM_BUTTON1DBLCLK        │Highlights the button and sends a
|-
│                        │BN_DBLCLICKED notification code   │
| WM_MOUSEMOVE || Sets the default mouse pointer. If the button has the mouse captured, the button's highlighted state changes as the mouse pointer moves in and out of the button boundary.
│                        │when the button-up message arrives.
|-
├─────────────────────────┼───────────────────────────────────┤
| WM_PAINT || Draws the button according to its style and current state.
│WM_BUTTON1DOWN          │Sets the button window so it can   │
|-
│                        │capture mouse input.               │
| WM_QUERYDLGCODE || Returns the DLGC_BUTTON code combined with other DLGC_ codes that designate the button's type.
├─────────────────────────┼───────────────────────────────────┤
|-
│WM_BUTTON1UP            │If the button window is set to     │
| WM_QUERYWINDOWPARAMS || Returns the requested window parameters.
│                        │capture mouse input, and if the   │
|-
│                        │mouse pointer is inside the button
| WM_SETFOCUS || Creates a cursor if the button-control window is receiving the focus. Destroys the cursor if the button-control window is losing the focus.
│                        │window when the mouse button is   │
|-
│                        │released, this message releases the│
| WM_SETWINDOWPARAMS || Sets the requested window parameters and redraws the button, including the cursor, if the button-control window has the focus.
│                        │mouse and sends a notification     │
|}
│                        │message to the owner window. If the│
 
│                        │button is a push button, the push
│                        │button control posts a WM_COMMAND
│                        │message; otherwise, the button     │
│                        │control sends a WM_CONTROL message
│                        │with the BN_CLICKED notification   │
│                        │code.                             │
├─────────────────────────┼───────────────────────────────────┤
│WM_CHAR                  │Sets the button window so it can   │
│                        │capture mouse input when the       │
│                        │spacebar is pressed; releases the
│                        │mouse when the spacebar is         │
│                        │released. Passes other key       │
│                        │messages to the default window     │
│                        │procedure.                         │
├─────────────────────────┼───────────────────────────────────┤
│WM_CREATE                │Validates the requested button     │
│                        │style and sets the window text.   │
├─────────────────────────┼───────────────────────────────────┤
│WM_DESTROY              │Frees the memory containing the   │
│                        │window's text.                     │
├─────────────────────────┼───────────────────────────────────┤
│WM_ENABLE                │Sent when an application changes   │
│                        │the enabled state of a window.     │
├─────────────────────────┼───────────────────────────────────┤
│WM_MATCHMNEMONIC        │Returns TRUE if mp1 matches a     │
│                        │mnemonic in the control window's   │
│                        │text.                             │
├─────────────────────────┼───────────────────────────────────┤
│WM_MOUSEMOVE            │Sets the default mouse pointer. If│
│                        │the button has the mouse captured,
│                        │the button's highlighted state     │
│                        │changes as the mouse pointer moves
│                        │in and out of the button boundary.
├─────────────────────────┼───────────────────────────────────┤
│WM_PAINT                │Draws the button according to its
│                        │style and current state.           │
├─────────────────────────┼───────────────────────────────────┤
│WM_QUERYDLGCODE          │Returns the DLGC_BUTTON code       │
│                        │combined with other DLGC_ codes   │
│                        │that designate the button's type.
├─────────────────────────┼───────────────────────────────────┤
│WM_QUERYWINDOWPARAMS    │Returns the requested window       │
│                        │parameters.                       │
├─────────────────────────┼───────────────────────────────────┤
│WM_SETFOCUS              │Creates a cursor if the           │
│                        │button-control window is receiving
│                        │the focus. Destroys the cursor if
│                        │the button-control window is losing│
│                        │the focus.                         │
├─────────────────────────┼───────────────────────────────────┤
│WM_SETWINDOWPARAMS      │Sets the requested window         │
│                        │parameters and redraws the button,
│                        │including the cursor, if the       │
│                        │button-control window has the     │
│                        │focus.                             │
└─────────────────────────┴───────────────────────────────────┘
</PRE>
===Button Notification Messages===
===Button Notification Messages===
A button, regardless of its style or type, posts a message to its owner when selected by the user. The message posted by push buttons is ordinarily WM_COMMAND. However, for buttons created with the BS_PUSHBUTTON or BS_USERBUTTON style, the message posted can be changed to WM_HELP or WM_SYSCOMMAND by additionally specifying either the BS_HELP or BS_SYSCOMMAND styles, respectively, when creating the button. A button control that has a style other than BS_PUSHBUTTON or BS_USERBUTTON sends WM_CONTROL messages to its owner when the user selects it.
A button, regardless of its style or type, posts a message to its owner when selected by the user. The message posted by push buttons is ordinarily WM_COMMAND. However, for buttons created with the BS_PUSHBUTTON or BS_USERBUTTON style, the message posted can be changed to WM_HELP or WM_SYSCOMMAND by additionally specifying either the BS_HELP or BS_SYSCOMMAND styles, respectively, when creating the button. A button control that has a style other than BS_PUSHBUTTON or BS_USERBUTTON sends WM_CONTROL messages to its owner when the user selects it.
Line 199: Line 142:


When the user selects any button other than a push button, that button sends a WM_CONTROL message. The application can examine SHORT1FROMMP(mp1) in the WM_CONTROL message to find the button identifier, and can examine SHORT2FROMMP(mp1) to determine the notification code for the control message. The notification code can be one of the following:
When the user selects any button other than a push button, that button sends a WM_CONTROL message. The application can examine SHORT1FROMMP(mp1) in the WM_CONTROL message to find the button identifier, and can examine SHORT2FROMMP(mp1) to determine the notification code for the control message. The notification code can be one of the following:
<PRE>
 
┌─────────────────────────┬───────────────────────────────────┐
{| class="wikitable"
│Code                    │Description                        │
|+ Button Notification Codes and Descriptions
├─────────────────────────┼───────────────────────────────────┤
|-
│BN_CLICKED              │The user selected the button.     │
! Code !! Description
├─────────────────────────┼───────────────────────────────────┤
|-
│BN_DBLCLICKED            │The user double-clicked the button.
| BN_CLICKED || The user selected the button.
├─────────────────────────┼───────────────────────────────────┤
|-
│BN_PAINT                │A user-defined button needs to be
| BN_DBLCLICKED || The user double-clicked the button.
│                        │drawn. Buttons with the           │
|-
│                        │BS_USERBUTTON style send this     │
| BN_PAINT || A user-defined button needs to be drawn. Buttons with the BS_USERBUTTON style send this notification code to instruct the owner window to draw the button control. The second message parameter of the WM_CONTROL message contains a pointer to a USERBUTTON structure that contains the information necessary for drawing the button.
│                        │notification code to instruct the
|}
│                        │owner window to draw the button   │
 
│                        │control. The second message       │
│                        │parameter of the WM_CONTROL message│
│                        │contains a pointer to a USERBUTTON
│                        │structure that contains the       │
│                        │information necessary for drawing
│                        │the button.                       │
└─────────────────────────┴───────────────────────────────────┘
</PRE>
When the user selects a check box or radio button, the button control sends the WM_CONTROL message with the BN_CLICKED notification code to the owner window. In response, the owner window should set the display state of the button by sending the appropriate message back to the button.
When the user selects a check box or radio button, the button control sends the WM_CONTROL message with the BN_CLICKED notification code to the owner window. In response, the owner window should set the display state of the button by sending the appropriate message back to the button.


An application need not respond to WM_CONTROL messages sent by an auto-check box or an auto-radio button; the system automatically sets the states of these buttons.  
An application need not respond to WM_CONTROL messages sent by an auto-check box or an auto-radio button; the system automatically sets the states of these buttons.
 
===Button States===
===Button States===
An application can query and set the highlighted and checked states of its buttons by sending messages to them. An application can obtain the handle of a button by calling WinWindowFromID, using the parent window handle and the identifier of the button. In the case of a dialog window, the parent window would be the dialog window, and the identifier would be the button identifier from the dialog template.
An application can query and set the highlighted and checked states of its buttons by sending messages to them. An application can obtain the handle of a button by calling WinWindowFromID, using the parent window handle and the identifier of the button. In the case of a dialog window, the parent window would be the dialog window, and the identifier would be the button identifier from the dialog template.

Latest revision as of 04:47, 19 April 2025

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Presentation Manager Programming Guide and Reference
  1. How to Use this Book
  2. Device Functions
  3. Direct Manipulation Functions
  4. Dynamic Data Formatting Functions
  5. Hooks and Procedures
  6. Profile Functions
  7. Spooler Functions
  8. Window Functions
  9. Message Processing
  10. Data Types
  11. Errors
  12. Atom Tables
  13. Button Controls
  14. Clipboards
  15. Combination Box
  16. Container Controls
  17. Control Windows
  18. Cursors
  19. Dialog Windows
  20. Direct Manipulation
  21. Drawing in Windows
  22. Dynamic Data Exchange
  23. Entry-Field Controls
  24. File Dialog Controls
  25. Font Dialog Controls
  26. Frame Windows
  27. Hooks
  28. Initialization Files
  29. Keyboard Accelerators
  30. List-Box Controls
  31. Menus
  32. Messages and Message Queues
  33. Multiple-Line Entry Field Controls
  34. Mouse and Keyboard Input
  35. Mouse Pointers and Icons
  36. Notebook Controls
  37. Painting and Drawing
  38. Presentation Parameters
  39. Resource Files
  40. Scroll-Bar Controls
  41. Slider Controls
  42. Spin Button Controls
  43. Static Controls
  44. Title-Bar Controls
  45. Value Set Controls
  46. Windows
  47. Window Classes
  48. Window Procedures
  49. Window Timers
  50. Appendices
  51. Notices
  52. Glossary

A button is a type of control window used to initiate an operation or to set the attributes of an operation. This chapter describes how to create and use buttons in PM applications.

About Button Controls

A button control can appear alone or with a group of other buttons. When buttons are grouped, the user can move from button to button within the group by pressing the Arrow keys. The user also can move among groups by pressing the Tab key.

A user can select a button by clicking it with the mouse, pressing the spacebar when the button has the keyboard focus, or sending a BM_CLICK message. In most cases, a button changes its appearance when selected.

A button control is always owned by another window, usually a dialog window or an application's client window. A button control posts WM_COMMAND messages or sends WM_CONTROL notification messages to its owner when a user selects the button. For further information on messages generated, see Button Notification Messages. The owner window receives messages from a button control and can send messages to the button to alter its position, appearance, and enabled/disabled state.

To use a button control in a dialog window, an application specifies the control in a dialog template in the application's resource-definition file. The application processes button messages in the dialog-window procedure.

An application creates a button control in a client window by calling WinCreateWindow, specifying a window class of WC_BUTTON, and identifying the client window as the owner of the button control.

Button Types

There are four main types of buttons: push buttons, radio buttons, check boxes, and three-state check boxes. A button's type determines how the button looks and behaves.

A radio button, check box, or three-state check box controls an operation; a push button initiates an operation. For example, a user might set printing options (such as paper size, print quality, and printer type) in a print-command dialog window containing an array of radio buttons and check boxes. After setting the options, the user would select a push button to tell an application that printing should begin (or be canceled). Then, the application would query the state of each check box and radio button to determine the printing parameters.

Push Buttons

A push button is a rectangular window typically used to enable the user to start or stop an operation. When selected, a push button control posts a WM_COMMAND message to its owner window.

The push button can contain a text string, an icon or mini-icon, or a combination of text and images.

Radio Buttons

A radio button is a window with text displayed to the right of a small circular indicator. Each time the user selects a radio button, that button's state toggles between selected and unselected. This state remains until the next time the user selects the button. An application typically uses radio buttons in groups.

Within a group, usually one button is selected by default, and the user can move the selection to another button by using the cursor keys; however, only one button can be selected at a time. Radio buttons are appropriate if an exclusive choice is required from a fixed list of related options. For example, applications often use radio buttons to allow the user to select the screen foreground and background colors. A radio-button control sends WM_CONTROL messages to its owner window.

Check Boxes

Check boxes are similar to radio buttons, except that they can offer multiple-choice selection as well as individual choice. Check boxes offer the user a fixed list of choices, with the option of selecting more than one, or even all.

Check boxes also toggle application features on or off. For example, a word processing application might use a check box to let the user turn word wrapping on or off. A check-box control sends WM_CONTROL messages to its owner window.

Three-State Check Boxes

Three-state check boxes are similar to check boxes, except that they can be displayed in halftone as well as selected and unselected. An application might use the halftone state to indicate that, currently, the checkbox is not selectable. A three-state check-box control sends WM_CONTROL messages and posts WM_COMMAND messages to its owner window.

Application-defined Buttons

In addition to using the four predefined button-control types, an application can create button controls that appear as defined by the owner window. When they must be drawn or highlighted, these button controls send WM_CONTROL messages with BN_PAINT as the notification code to their owner windows.

Button Styles

The following table describes the button styles an application can use when creating button controls:

Button Styles and Descriptions
Style Description
BS_3STATE Creates a three-state check box (see also BS_CHECKBOX). When the user selects the check box, it sends a WM_CONTROL message to the owner window. The owner should set the check box to the appropriate state: selected, unselected, or halftone.
BS_AUTO3STATE Creates an auto-three-state check box (see also BS_CHECKBOX). When the user selects the check box, the system automatically sets the check box to the appropriate state: selected, unselected, or halftone.
BS_AUTOCHECKBOX Creates an auto-check box (see also BS_CHECKBOX). The system automatically toggles the check box between the selected and unselected states each time the user selects the box.
BS_AUTORADIOBUTTON Creates an auto-radio button (see also BS_RADIOBUTTON). When the user selects an auto-radio button, the system automatically selects the button and removes the selection from the other auto-radio buttons in the group.
BS_AUTOSIZE Creates a button that is sized automatically to ensure that the contents fit. Note: The cx or cy parameter of WinCreateWindow must be specified as -1 to implement the autosize feature.
BS_BITMAP Creates a push button containing a bit map instead of text. This style can only be implemented with BS_PUSHBUTTON.
BS_CHECKBOX Creates a check box-a small square that has text displayed to its right. When the user selects a check box, the check box sends a WM_CONTROL message to the owner window. The owner window should toggle the check box between selected and unselected states.
BS_DEFAULT Creates a push button that has a heavy black border. The user can select this push button by pressing the spacebar. This style is useful for letting the user quickly select the most likely set of options in a dialog window. This style is valid only in combination with the BS_PUSHBUTTON style or the PUSHBUTTON statement in a resource-definition file.
BS_HELP Creates a push button that posts a WM_HELP message (instead of a WM_COMMAND message) to its owner window when the user selects the button. This style is valid only in combination with the BS_PUSHBUTTON style or the PUSHBUTTON statement in a resource-definition file.
BS_ICON Creates a push button containing an icon instead of text.
BS_MINIICON Creates a push button containing a mini-icon instead of text.
BS_NOBORDER Creates a push button that has no border. This style is valid only in combination with the BS_PUSHBUTTON style or the PUSHBUTTON statement in a resource-definition file.
BS_NOCURSORSELECT Creates an auto-radio button that will not be selected automatically when the user moves the cursor to the button using the cursor-movement keys. This style is valid only in combination with the BS_AUTORADIOBUTTON style or the AUTORADIOBUTTON statement in a resource-definition file.
BS_NOPOINTERFOCUS Creates a radio button or check box that does not receive the keyboard focus when the user selects it. This style is valid in combination with the BS_AUTORADIOBUTTON, BS_RADIOBUTTON, BS_3STATE, BS_AUTO3STATE, BS_AUTOCHECKBOX, and BS_CHECKBOX styles, or the AUTORADIOBUTTON, RADIOBUTTON, AUTOCHECKBOX, or CHECKBOX statements in a resource-definition file.
BS_NOTEBOOKBUTTON Creates a notebook button, which is identical to a pushbutton except that when it is created as a child of a notebook page it becomes a button in the common button area of the notebook page. If the button is not in a notebook page it will be indistinguishable from a pushbutton.
BS_PUSHBUTTON Creates a push button-a round-cornered rectangle with text displayed inside it. When selected, the push button posts a WM_COMMAND message to its owner window.
BS_RADIOBUTTON Creates a radio button-a small circle that has text displayed to its right. Radio buttons usually are used in groups of related, but exclusive, choices. When the user selects a radio button, the button sends a WM_CONTROL message to its owner window. The user should select the button and remove the selection from the other radio buttons in the group.
BS_SYSCOMMAND Creates a button that posts a WM_SYSCOMMAND message (instead of a WM_COMMAND message) to the owner window when the user selects the button. This style is valid only in combination with the BS_PUSHBUTTON style or the PUSHBUTTON statement in a resource-definition file.
BS_TEXT Creates a push button containing both text and icons/mini-icons.
BS_USERBUTTON Creates a user-defined button that sends a WM_CONTROL message to the owner window when the button needs to be drawn, highlighted, or disabled. A user-defined button also posts WM_COMMAND messages to the owner window when the user selects the button.

Default Button Behavior

Following are the messages processed by the predefined button-control window class (WC_BUTTON). Each message is described in terms of how a button control responds to that message.

Button Messages and Descriptions
Message Description
BM_AUTOSIZE Causes the buttons in a new-style notebook to automatically size to fit their contents.
BM_CLICK Sends a WM_BUTTON1DOWN and WM_BUTTON1UP message to itself to simulate a user button selection.
BM_QUERYCHECK Returns the checked state of the button.
BM_QUERYCHECKINDEX Returns the 0-based index to the selected button in a group. Returns -1 if no button in the group is selected or if the button receiving the message is not a radio button or an auto-radio button.
BM_QUERYHILITE Returns the highlighted state of the button.
BM_SETCHECK Sets the checked state of the button and returns the previous checked state.
BM_SETDEFAULT Sets the default button state and redraws the button.
BM_SETHILITE Sets the highlighted state of the button and returns the previous highlighted state.
WM_BUTTON1DBLCLK Highlights the button and sends a BN_DBLCLICKED notification code when the button-up message arrives.
WM_BUTTON1DOWN Sets the button window so it can capture mouse input.
WM_BUTTON1UP If the button window is set to capture mouse input, and if the mouse pointer is inside the button window when the mouse button is released, this message releases the mouse and sends a notification message to the owner window. If the button is a push button, the push button control posts a WM_COMMAND message; otherwise, the button control sends a WM_CONTROL message with the BN_CLICKED notification code.
WM_CHAR Sets the button window so it can capture mouse input when the spacebar is pressed; releases the mouse when the spacebar is released. Passes other key messages to the default window procedure.
WM_CREATE Validates the requested button style and sets the window text.
WM_DESTROY Frees the memory containing the window's text.
WM_ENABLE Sent when an application changes the enabled state of a window.
WM_MATCHMNEMONIC Returns TRUE if mp1 matches a mnemonic in the control window's text.
WM_MOUSEMOVE Sets the default mouse pointer. If the button has the mouse captured, the button's highlighted state changes as the mouse pointer moves in and out of the button boundary.
WM_PAINT Draws the button according to its style and current state.
WM_QUERYDLGCODE Returns the DLGC_BUTTON code combined with other DLGC_ codes that designate the button's type.
WM_QUERYWINDOWPARAMS Returns the requested window parameters.
WM_SETFOCUS Creates a cursor if the button-control window is receiving the focus. Destroys the cursor if the button-control window is losing the focus.
WM_SETWINDOWPARAMS Sets the requested window parameters and redraws the button, including the cursor, if the button-control window has the focus.

Button Notification Messages

A button, regardless of its style or type, posts a message to its owner when selected by the user. The message posted by push buttons is ordinarily WM_COMMAND. However, for buttons created with the BS_PUSHBUTTON or BS_USERBUTTON style, the message posted can be changed to WM_HELP or WM_SYSCOMMAND by additionally specifying either the BS_HELP or BS_SYSCOMMAND styles, respectively, when creating the button. A button control that has a style other than BS_PUSHBUTTON or BS_USERBUTTON sends WM_CONTROL messages to its owner when the user selects it.

When the user selects a push button using the mouse pointer, the system automatically highlights the button. The button's window procedure tracks the movement of the pointer until the user releases the button. If the user moves the pointer so that it is outside the button boundary, the system turns off the highlight. The push button control does not post a WM_COMMAND message until the user releases the pointer button, and then, only if the button is released inside the push button boundary. When the owner window receives a WM_COMMAND message from a push button, the low word of the first parameter in the message contains the identifier of the button as specified either in the dialog template or in the WinCreateWindow function when the button was created.

An application should avoid duplicating identifiers for menu items and button controls, because both the items and the controls post identifiers to owner windows as WM_COMMAND messages. However, the application can determine whether a WM_COMMAND message came from a menu or a push button control by looking for the value CMDSRC_MENU or CMDSRC_PUSHBUTTON in the low word of the message's second parameter.

When the user selects any button other than a push button, that button sends a WM_CONTROL message. The application can examine SHORT1FROMMP(mp1) in the WM_CONTROL message to find the button identifier, and can examine SHORT2FROMMP(mp1) to determine the notification code for the control message. The notification code can be one of the following:

Button Notification Codes and Descriptions
Code Description
BN_CLICKED The user selected the button.
BN_DBLCLICKED The user double-clicked the button.
BN_PAINT A user-defined button needs to be drawn. Buttons with the BS_USERBUTTON style send this notification code to instruct the owner window to draw the button control. The second message parameter of the WM_CONTROL message contains a pointer to a USERBUTTON structure that contains the information necessary for drawing the button.

When the user selects a check box or radio button, the button control sends the WM_CONTROL message with the BN_CLICKED notification code to the owner window. In response, the owner window should set the display state of the button by sending the appropriate message back to the button.

An application need not respond to WM_CONTROL messages sent by an auto-check box or an auto-radio button; the system automatically sets the states of these buttons.

Button States

An application can query and set the highlighted and checked states of its buttons by sending messages to them. An application can obtain the handle of a button by calling WinWindowFromID, using the parent window handle and the identifier of the button. In the case of a dialog window, the parent window would be the dialog window, and the identifier would be the button identifier from the dialog template.

Button-control text is stored as window text. An application can set and retrieve this text by using the WinSetWindowText and WinQueryWindowText functions. To set the size, position, and visibility of a button control, an application uses the standard window functions.

Custom Buttons

An application can customize the appearance of a button by using the BS_USERBUTTON style in combination with other button styles. The owner window receives WM_CONTROL messages for these custom buttons whenever they must be drawn, highlighted, or disabled.

When a button must be drawn, the owner window receives a WM_CONTROL message with the high word of the first parameter equal to BN_PAINT. The second parameter is a pointer to a USERBUTTON structure that contains information the application needs to draw the button.

An application uses the hwnd member of the USERBUTTON structure in a call to the WinQueryWindowRect function to find the bounding rectangle for the button. The hps member is used as a presentation space for any drawing. The fsState member contains flags that tell an application how to draw the button: highlighted, unhighlighted, or disabled. The fsStateOld member contains flags that describe the current highlighted, unhighlighted, or disabled state of the button.

Using Button Controls

This section explains how to perform the following tasks:

  • Create a dialog template for a button resource
  • Create a button for a client window

An application creates a group by setting the WS_GROUP style bit for the first member of the group.

Using Buttons in a Dialog Window

You can define dialog-window buttons as part of a dialog template in a resource-definition file, as shown in the following Resource Compiler source-code fragment.

    DLGTEMPLATE IDD_BUTTON
    BEGIN
        DIALOG  "", 2, 10, 10, 235, 180, WS_VISIBLE, FCF_DLGBORDER
        BEGIN
            AUTORADIOBUTTON "Radio~1", ID_RADIO1, 15, 80, 45, 12, WS_GROUP
            AUTORADIOBUTTON "Radio~2", ID_RADIO2, 15, 60, 45, 12
            AUTORADIOBUTTON "Radio~3", ID_RADIO3, 15, 40, 45, 12
            AUTORADIOBUTTON "Radio~4", ID_RADIO4, 15, 20, 45, 12

            PUSHBUTTON "Button 1", ID_PUSH1,  20  100, 50, 14, WS_GROUP
            PUSHBUTTON "Button 2", ID_PUSH2,  75, 100, 50, 14, WS_GROUP
            PUSHBUTTON "Button 3", ID_PUSH3, 130, 100, 50, 14, WS_GROUP

            CHECKBOX "Check Box 1",     ID_CHECK1, 150, 65, 65, 12, WS_GROUP
            CHECKBOX "no toggle",       ID_CHECK2, 150, 40, 58, 12, WS_GROUP
            AUTOCHECKBOX "Check Box 3", ID_CHECK3, 150, 20, 65, 12, WS_GROUP

            DEFPUSHBUTTON "OK",         DID_OK,     75, 26, 46, 20, WS_GROUP
        END
    END

Each button in a dialog window has an identifier (for example, ID_RADIO1) that allows an application to identify the source of the WM_COMMAND and WM_CONTROL messages. An application can use the identifier as the second argument of the WinWindowFromID function to retrieve the button-window handle.

The dialog template also contains the text for each button. For push buttons, this text is displayed in a rectangular box. If the text is too long to fit in the box, the text is clipped. For radio buttons and check boxes, text is displayed to the right of the button. A user selects the button by clicking either the button or the text itself.

The WS_GROUP style identifies the beginning of each new group of buttons. In the preceding example, the four auto-radio buttons are in the same group, and each of the other buttons is in its own group. The auto-radio buttons in the first group can be selected one at a time only. An application must ensure that only one check box in a group is selected at a time. The order in which items can be selected in the group can wrap around from the end of the item list to its beginning.

Notice that the DEFPUSHBUTTON style in the preceding example has the identifier DID_OK. It is customary to include an OK button with this identifier in most dialog windows to provide a uniform user interface. The DEFPUSHBUTTON style draws a thick border around a button and allows a user to select the button by pressing the spacebar.

The dialog-window procedure for a dialog window that contains buttons must respond to WM_COMMAND and WM_CONTROL messages. A common strategy is to use auto-radio buttons and auto-check boxes to let the user set a list of capabilities for a command, and, then, let the user execute the command by choosing an OK push button. With this strategy, the dialog-window procedure ignores all WM_CONTROL messages that come from auto-radio buttons and auto-check boxes. When the dialog-window procedure receives a WM_COMMAND message for the OK push button, the procedure should query the auto-radio buttons and auto-check boxes to determine which options have been selected.

Using Buttons in a Client Window

An application can create a button control using an application client window as the owner. The following code fragment shows how an application can use buttons in client windows:

    #define ID_PBWINDOW 110
    HWND hwndButton,hwndClient;

    /* Create a button window. */
    hwndButton = WinCreateWindow(hwndClient,   /* Parent window  */
        WC_BUTTON,                             /* Class window   */
        "Test Button"                          /* Button text    */
        WS_VISIBLE |                           /* Visible style  */
        BS_PUSHBUTTON,                         /* Button style   */
        10, 10,                                /* x, y           */
        70, 60,                                /* cx, cy         */
        hwndClient,                            /* Owner window   */
        HWND_TOP,                              /* Top of z-order */
        ID_PBWINDOW,                           /* Identifier     */
        NULL,                                  /* Control data   */
        NULL);                                 /* parameters     */

Once created in the client window, the button control posts a WM_COMMAND message or sends a WM_CONTROL message to the client-window procedure. This window procedure should examine the message identifier to determine which button posted or sent the message.

An application that has client-window buttons can move and size the buttons when the client window receives a WM_SIZE message. An application can move and size a window by using the WinSetWindowPos function. An application can obtain a window handle for a button control by calling the WinWindowFromID function, specifying the handle of the parent window and the window identifier for each button.

Creating Buttons with Icons and Icon/Text Combinations

The following styles generate buttons containing images or icons:

  • BS_ICON
  • BS_MINIICON
  • BS_BITMAP

The image or icon is activated by specifying the image ID in the button text string. For example, to load an icon (#define ICON_ID 300) and display it with the button, the button text string is set to "#300".

Where text is to be combined with an image, BS_TEXT is selected. To display an icon (#define ICON_ID 300) with the words "My button", the button text string is set to "#300\tMy button". Notice that "\t" is used to separate text from the image ID.

The following code example creates a customized button with text.

// presparm.c  -- demonstrates presentation parameters//                creates a button as a child window
//                and sets its text color

#define  INCL_WIN
#define  INCL_GPI
#include <os2.h>
#include <string.h>
#include "presparm.h"
#include "migrate.h"

int main ( int argc, char *argv[]);

// Internal function prototypes


MRESULT EXPENTRY MyWindowProc( HWND hwnd, MSGID msg
                               , MPARAM mp1, MPARAM mp2 );
int main ( int argc, char *argv[]);

// global variables

    HAB  hab;                           // Anchor block handle

int main ( int argc, char *argv[])
{
    HMQ  hmq;                           // Message queue handle
    HWND hwndFrame;                     // Frame window handle
    HWND hwndClient;                    // Client window handle
    QMSG qmsg;                          // Message from message queue
    ULONG flCreate;                     // Window creation control flags
    hab = WinInitialize( 0 );
    hmq = WinCreateMsgQueue( hab, 0 );

    WinRegisterClass( hab, "presparm", MyWindowProc, 0L,  0 );

    flCreate = FCF_SYSMENU | FCF_SIZEBORDER | FCF_TITLEBAR |
               FCF_MINMAX | FCF_SHELLPOSITION | FCF_TASKLIST;

    hwndFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE, &flCreate,
        "presparm", "", 0L, 0, ID_WINDOW, &hwndClient );

    while( WinGetMsg( hab, &qmsg, 0, 0, 0 ) )
      WinDispatchMsg( hab, &qmsg );

    WinDestroyWindow( hwndFrame );

   WinDestroyMsgQueue( hmq );
    WinTerminate( hab );
    return 0;
}

//
MRESULT EXPENTRY MyWindowProc( HWND hwnd, MSGID msg
                               , MPARAM mp1, MPARAM mp2 )
{
    HPS     hps;                            // PS handle
    BTNCDATA btn;

    typedef struct _FORECOLORPARAM
    {
        ULONG   id;
        ULONG   cb;

        ULONG   ulColor;
    } FORECOLORPARAM;

    typedef struct _FONTPARAM
    {
        ULONG   id;
        ULONG   cb;
        CHAR    szFontNameSize[20];
    } FONTPARAM;

    struct  _PRES                           // pres. params
    {
        ULONG   cb;                         // length
        FORECOLORPARAM fcparam;             // foreground color
        FONTPARAM      fntparam;            // font name & size
    }   pres;
   static  HWND    hwndButton;              // button window handle
    static  POINTL  pt;                     // window size

    switch( msg )
    {
        case WM_CLOSE:
            WinPostMsg( hwnd, WM_QUIT, 0L, 0L );
            return ( (MRESULT) 0 );

    case WM_CREATE:

          // set the foreground color to CLR_RED in
          // the button's presentation parameters
            pres.fcparam.id = PP_FOREGROUNDCOLORINDEX;
            pres.fcparam.cb = sizeof ( pres.fcparam.ulColor );

          pres.fcparam.ulColor = CLR_RED;

          // set the font used by the button to 12 point Courier
            pres.fntparam.id = PP_FONTNAMESIZE;
            pres.fntparam.cb = 20;
            strcpy ( pres.fntparam.szFontNameSize, "24.Helv" );

            pres.cb = sizeof ( pres.fcparam ) + sizeof ( pres.fntparam )
            hwndButton = WinCreateWindow ( hwnd     // parent
                            , WC_BUTTON             // class
                            , "#300\tNumber One"    // window text
                            , BS_PUSHBUTTON  |
                              BS_ICON | BS_TEXT     // style
                            , 100, 100              // x, y
                            , 400, 400              // cx, cy
                            , hwnd                  // owner
                            , HWND_TOP              // sibling
                            , 255                   // ID
                            , NULL                  // ctrl data
                            , &pres );          // pres. params
                                                    // pmassert
            ( hwndButton, hab );
            return (MRESULT)FALSE;


        case WM_SIZE:
            pt.x = (LONG) SHORT1FROMMP ( mp2 );
            pt.y = (LONG) SHORT2FROMMP ( mp2 );
            WinSetWindowPos ( hwndButton, HWND_TOP
                            , (SHORT)pt.x / 3
                            , (SHORT)pt.y / 2
                            , (SHORT)pt.x / 2
                             , (SHORT)pt.y / 3
                             , SWP_SIZE | SWP_MOVE  | SWP_SHOW );
             return (MRESULT)0;


         case WM_PAINT:
             hps = WinBeginPaint ( hwnd , 0 , NULL );
             GpiErase ( hps );
             WinEndPaint ( hps );
             return ( (MRESULT) 0 );

         default:
             return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
     }
     return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );