Jump to content

PMGuide - Button Controls: Difference between revisions

From EDM2
No edit summary
No edit summary
Line 548: Line 548:


</PRE>
</PRE>
[[Category:PM Guide]]

Revision as of 16:58, 19 May 2024

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:

┌───────────────────┬─────────────────────────────────────────┐
│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.

┌─────────────────────────┬───────────────────────────────────┐
│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:

┌─────────────────────────┬───────────────────────────────────┐
│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 ) );