Win32 Common Controls, Part 2: Status Bars and Toolbars

Nancy Winnick Cluts
Microsoft Developer Network Technology Group

March 1994

Revised: June 1995 (TBADDBITMAP32 structure and message removed)

Click to open or copy the files in the Toolbar sample application for this technical article.

Abstract

The next release of the Microsoft® Windows® operating system (called Windows 95) presents a new set of common controls to developers of Windows-based applications. These controls are provided in a new dynamic-link library (DLL) called COMCTL32.DLL. The controls allow developers to integrate existing applications into the new Windows 95 shell more thoroughly and seamlessly. COMCTL32.DLL is included with Windows 95 and will also be supported in Win32s® (running on Windows version 3.1) and in Windows NT™. Note that these controls are 32-bit only—they will not be supported in 16-bit Windows environments.

This article describes two new common controls: status bars and toolbars. It is the second in a series of articles introducing the new common controls. The other articles in the series cover the following topics:

Parts 2–6 of the series have associated code samples that demonstrate the use of the Win32® common controls.

WARNING   The Toolbar executable file associated with this article was built and tested using the Windows 95 Preliminary Development Kit. The executable will run only on Windows 95; it will not run under Windows 3.1 or Windows NT 3.5. If you have Windows 95 installed on your machine but you have problems running this sample, copy the project files to your system using the button above, rebuild the project, and run the executable.

Please note that this article is based on preliminary information that is subject to change before the final version of Windows 95.

Status Bars

A status bar is a horizontal window that is positioned, by default, at the bottom of a parent window. It is used to display status information defined by the application. If you wish to display more than one type of status information, you can divide the status bar into sections.

To create a status bar, call the CreateWindow or CreateWindowEx function and specify the STATUSCLASSNAME window class. After you create the status bar, you can divide it into sections, set the text for each section, and control the appearance of the window by using status bar messages.

The default window procedure automatically adjusts the size of the status bar whenever it receives a WM_SIZE message. Figure 1 shows a simple status bar that displays the current mouse position.

Figure 1. Example of a simple status bar

I found status bars particularly useful for displaying diagnostic messages when debugging my application. This works well for those times when you don't want to bother with a debugger, and you would normally display a message box showing the value of a particular parameter or indicating whether you reached a certain line in your code. I recommend that you use a status bar for this instead.

Status Bar Styles and Default Behavior

The only new style that was developed specifically for the status bar is the SBS_SIZEGRIP style, which places a sizing grip at the lower-right corner of the status bar. A sizing grip is similar to a sizing border—it is a rectangular area that the user can click and drag to resize the parent window.

Warning   If you decide to include a sizing grip, I recommend against combining the CCS_TOP common control style and the SBS_SIZEGRIP style. Combining the two styles renders the sizing grip nonfunctional. Because the system will still draw the sizing grip in the status bar, the user will try to use it and think that your application is at fault.

You can set the minimum height of a status bar's drawing area by sending the window a SB_SETMINHEIGHT message and specifying the minimum height in pixels. Note that the drawing area does not include the window's borders. If you want to set the border width for the status bar, you can send an SB_SETBORDERS message. This message passes the address of a three-element array that contains the width of the horizontal border, the width of the vertical border, and the width of the border that separates the sections of the status bar. All widths are specified in pixels. If you want to use the default width, pass a value of –1.

Creating a Status Bar Window

Use the CreateWindowEx function to create a status bar. The default values for the size of a status bar are (–100, –100, 10, 10). The following example creates the status bar that displays the current mouse cursor position (illustrated in Figure 1). The code resides in the window procedure for the status bar's parent window.

switch (message) 
{
   case WM_CREATE:
      hWndStatus = CreateWindowEx( 
            0L,                              // no extended styles
            STATUSCLASSNAME,                 // status bar
            "",                              // no text 
            WS_CHILD | WS_BORDER | WS_VISIBLE,  // styles
            -100, -100, 10, 10,              // x, y, cx, cy
            hWnd,                            // parent window
            (HMENU)100,                      // window ID
            hInst,                           // instance
            NULL);                           // window data
      if (hWndStatus == NULL)
         MessageBox (NULL, "Status Bar not created!", NULL, MB_OK );
      break;

   case WM_MOUSEMOVE:
      wsprintf(szBuf, "Mouse position: %d, %d", LOWORD(lParam), HIWORD(lParam));
      SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)(LPSTR)szBuf);
      break;
   .
   .
   .
}

In the code above, I used CreateWindowEx to emphasize that these new common controls are all windows—you create them, send messages to them, and receive notifications from them, as you would with any other window. A helper function called CreateStatusWindow allows you to create a status bar at the bottom of your screen. This helper function creates a status bar by calling CreateWindowEx and passing the default size and position as (–100, –100, 10, 10). CreateStatusWindow takes the following parameters:

Simple-Mode and Multiple-Part Status Bars

A simple-mode status bar has only one section. It is useful for displaying one-line descriptions of menu items as the user highlights each item. To create a simple-mode status bar from a multiple-part status bar, you must send an SB_SIMPLE message to the status bar, but bear in mind that simple-mode status bars do not support owner drawing.

A multiple-part status bar has multiple sections and can display a different line of text for each section. You can divide a status bar into parts by sending the window an SB_SETPARTS message, specifying the number of sections to create and the address of an integer array containing one element for each section. Each element specifies the client coordinate of the right edge of a section. A status bar can have a maximum of 255 sections.

The string that a status bar displays in simple mode is maintained separately from the strings it displays when it is not in simple mode. This means you can put the window in simple mode, set its text, and switch back to non-simple mode without having to reset the text.

Owner-Drawn Status Bars

You can customize status bars by adding owner-drawn sections, just as you would customize other built-in controls. Owner drawing allows you to display a bitmap instead of text or use different fonts in the sections of a status bar. To define a section of the status bar as owner-drawn, send the SB_SETTEXT message to the status bar, specifying the part and the SBT_OWNERDRAW drawing technique. When you specify SBT_OWNERDRAW, the lParam parameter becomes a 32-bit application-defined value that the application can use when drawing the part. At this point, you treat the control like any other owner-drawn control: you handle the WM_DRAWITEM message and use the information in the DRAWITEMSTRUCT that is passed along.

Status Bar Messages

This section lists the messages that you can send to status bars. You will notice that many of these messages can also be sent to header windows. In fact, the header window procedure calls the window procedure for status bars. For more information about header window controls, see the "Win32 Common Controls, Part 4: Header Windows and List View Windows" article in this series.

Several messages require or return a drawing operation type for the status bar. The values you can use to designate an operation type are listed in Table 1 below.

Table 1. Status Bar Drawing Operation Types

Type Meaning
0 The text is drawn so that it appears as part of the window—that is, the text appears lower than the plane of the window.
SBT_OWNERDRAW The application may draw the item (text or bitmap) when it receives a WM_DRAWITEM message. Note that the CtlType, itemState, and itemAction fields of the DRAWITEMSTRUCT structure are undefined for status bars.
SBT_NOBORDERS The text is drawn without borders.
SBT_POPOUT The text is drawn so that it appears raised, that is, the text appears higher than the plane of the window.
HBT_SPRING The item (text or bitmap) "springs"; that is, it has a minimum length but will grow if the window provides extra room. Multiple items (items in multiple-part toolbars) are allowed to spring—the extra room is distributed among the multiple parts. (This type was originally created for header controls, which is why the type name begins with "HBT" instead of "SBT".)

SB_GETBORDERS

wParam = 0;                       \\ not used
lParam = LPINT)aBorders;          \\ array that receives border values

Description: The SB_GETBORDERS message retrieves the current width of the horizontal and vertical borders of a status or header window. These measurements determine the spacing between the outer edge of the window and the rectangles within the window that contain text, and the spacing between rectangles.

Parameters: wparam is not used. lparam represents the address of an integer array with three elements. The first element receives the width of the horizontal border, the second receives the width of the vertical border, and the third receives the width of the border between rectangles.

Return value: TRUE if successful; FALSE otherwise.

SB_GETPARTS

wParam = nParts;                  \\ number of parts to retrieve
lParam = (LPINT) aRightCoord;     \\ array that receives right edge

Description: The SB_GETPARTS message gets the number of parts in a status bar and the coordinate of the right edge of the given number of parts.

Parameters: wparam identifies the number of parts for which the message will get coordinates. If this parameter is greater than the number of parts in the status bar, the message gets coordinates for the existing parts only. lparam represents the address of an integer array that has the same number of elements as parts specified by wParam. Each element in the array receives the client coordinate of the right edge of the corresponding part. If an element is set to –1, the position of the right edge for that part extends to the right edge of the status bar.

Return value: The number of parts in the status bar if successful; zero otherwise.

SB_GETTEXT

wParam = iPart;                   \\ index of the part
lParam = (LPSTR) szText;          \\ address of the buffer receiving the string

Description: The SB_GETTEXT message retrieves the text from the given part of a status bar or header window.

Parameters: wParam is the zero-based index of the part from which the message will retrieve text. lParam is the address of the buffer to receive the text, which is a null-terminated string.

Return value: SB_GETTEXT returns a 32-bit value consisting of two 16-bit values. The low-order word specifies the length, in characters, of the text. The high-order word specifies the type of operation used to draw the text. If the text has a type of SBT_OWNERDRAW, the message returns the 32-bit value associated with the text instead of the length and type. See Table 1 for a list of values you can use to indicate the operation type.

SB_GETTEXTLENGTH

wParam = iPart;                   \\ index of the part
lParam = 0;                       \\ not used

Description: The SB_GETTEXTLENGTH message retrieves the length, in characters, of the text from the given part of a status bar or header window.

Parameters: wParam is the zero-based index of the part from which the message will retrieve text. lParam is not used.

Return value: SB_GETTEXTLENGTH returns a 32-bit value consisting of two 16-bit values. The low-order word specifies the length, in characters, of the text. The high-order word specifies the type of operation used to draw the text. See Table 1 for a list of values you can use to indicate the operation type.

SB_SETBORDERS

wParam = 0;                       \\ not used
lParam = (LPINT) aBorders;        \\ array that contains the border values

Description: The SB_SETBORDERS message sets the widths of the horizontal and vertical borders of a status bar or header window. These borders determine the spacing between the outer edge of the window and the rectangles within the window that contain text, and the spacing between rectangles.

Parameters: wParam is not used. lParam is the address of an integer array that has three elements. The first element specifies the width of the horizontal border, the second specifies the width of the vertical border, and the third specifies the width of the border between rectangles. If an element is set to –1, the default width for the border is used.

Return value: TRUE if successful; FALSE otherwise.

SB_SETMINHEIGHT

wParam = minHeight;               \\ minimum height, in pixels, of the window
lParam = 0;                       \\ not used

Description: The SB_SETMINHEIGHT message sets the minimum height for a status bar or header window. The minimum height of the window is the sum of the minimum height (wParam) and the height of the vertical border of the window.

Parameters: wParam is the minimum height, in pixels, of the window. lParam is not used.

Return value: None.

SB_SETPARTS

wParam = nParts;                  \\ number of parts ( <= 255)
lParam = (LPINT)aWidths;          \\ address of array containing the widths

Description: The SB_SETPARTS message sets the number of parts in a status bar and gets the coordinate of the right edge of each part.

Parameters: wParam is the number of parts to set. This number cannot be greater than 255. lParam is the address of an integer array that has the same number of elements as parts specified by wParam. Each element in the array specifies the position, in client coordinates, of the right edge of the corresponding part. If an element is –1, the position of the right edge for that part extends to the right edge of the window.

Return value: TRUE if successful; FALSE otherwise.

SB_SETTEXT

wParam = iPart | uPart;      \\ index of part and type of drawing operation
lParam = (LPSTR) szText;     \\ address of the buffer receiving the string

Description: The SB_SETTEXT message sets the text in the given part of a status bar or header window. This message invalidates the portion of the window that has changed, causing the window to display the new text.

Parameters: wParam is the zero-based index of the part to set and the type of drawing operation, as listed in Table 1. If this value is 255, the status bar is assumed to be a simple window with only one part. lParam is the address of a null-terminated string that specifies the text to set. If wParam is SBT_OWNERDRAW, lparam represents 32 bits of data. The parent window must interpret and draw the data when it receives the WM_DRAWITEM message.

Return value: TRUE if successful; FALSE otherwise.

SB_SIMPLE

wParam = (BOOL)fSimple;           \\ TRUE for simple text
lParam = 0;                       \\ not used 

Description: The SB_SIMPLE message specifies whether a status bar displays simple text or displays all window parts set by a previous SB_SETPARTS message.

Parameters: If wParam is TRUE, the status bar displays simple text. If wParam is FALSE, the status bar displays multiple parts. lParam is not used.

Return value: FALSE if an error occurs.

Toolbar Windows

A toolbar is a horizontal window with buttons that is located at the top of the parent window. Users choose the toolbar buttons to carry out corresponding commands. You can create a toolbar by using the CreateWindowEx or CreateWindow function. You can add, delete, and manage the buttons in the toolbar by using toolbar messages. If you are familiar with toolbars from the Microsoft Foundation Class Library (MFC) or Visual Basic®, you will find the Win32 toolbar control very familiar. If you are not familiar with toolbars, do not despair—they are very easy to implement. Figure 2 shows a simple toolbar with four buttons. You will notice that the first three buttons (numbered so creatively) are placed side by side. There is a small space between the third button and the button with the open door (that's what it is supposed to look like, anyway). This space is called a separator and is used to logically group buttons on the toolbar.

Figure 2. Example of a simple toolbar

Toolbar Styles and Default Behavior

The window procedure for the toolbar automatically positions and sets the size of the toolbar window. By default, the toolbar appears at the top of its parent window's client area; however, you can place the toolbar at the bottom of the client area by specifying CCS_BOTTOM.

The only new window style associated with the new toolbar control is TBSTYLE_TOOLTIPS. This new style allows the toolbar to display ToolTips (that neat little box that pops up when you rest the mouse cursor on a toolbar button). The system will send a WM_NOTIFY message to the toolbar whenever it needs to display text in a pop-up. The code example below shows the implementation of the ToolTips feature.

Creating a Toolbar Window

As mentioned above, creating a toolbar is simple: You fill out a button structure, create a large bitmap containing the buttons, then call the CreateWindowEx function, specifying the TOOLBARCLASSNAME style. Once the toolbar is created, you need to send messages to add the buttons and bitmaps to the toolbar. Then, unless there is something special you want to do, you can just let the system take care of handling the toolbar processing. The following code creates a toolbar, loads the bitmaps for the toolbar, and adds the buttons to the toolbar.

// Fill out a structure describing the buttons in the toolbar.
TBBUTTON tbButtons[] = {
   { 0, IDM_OPT1, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
   { 1, IDM_OPT2, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
   { 2, IDM_OPT3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
   { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, -1},
   { 3, IDM_EXIT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}
};

// Declare a bitmap structure if working under Win32.
TBADDBITMAP tbBitamps;

// Initialize the members.
.
.
.
tbBitamps.hInst = hInstance; // current instance
tbBitmaps.nID = IDB_TOOLBAR; // ID of the bitmap resource
.
.
.
// Function that creates a Win32 toolbar.
// Parameters:
//    HWND hWndParent - Handle to the parent window.
//    LONG lNumBitmaps - Number of bitmaps for the toolbar.
//    TBADDBITMAP tbBItmaps - Bitmap structure for Win32.
//    LONG lNumButtons - Number of buttons on the toolbar.
//    TBBUTON tbButtons - Pointer to button structure.
//    DWORD dwStyle - Special toolbar window styles. Can be a combination
//       of generic common control styles or specific toolbar styles.
//    int iToolBarID - ID for the toolbar window.
// Returns:
//    Handle to the toolbar window if successful; otherwise NULL.
//
HWND MyCreateTooolBar ( HWND hWndParent, LONG lNumBitmaps, TBADDBITMAP tbBitmaps, LONG lNumButtons, TBBUTON tbButtons, WORD wStyle, UINT uToolBarID )
{
  HWND hWndToolBar;

  // Create the toolbar control.
  hWndToolBar = CreateWindowEx( 0L,   // No extended styles.
    TOOLBARCLASSNAME,                 // Class name for the toolbar.
    "",                               // No default text.
    WS_CHILD | WS_BORDER | WS_VISIBLE | dwStyle,    // Styles and defaults.
    0, 0, 100, 30,                    // Standard toolbar size and position.
    hWndParent,                       // Parent window of the toolbar.
    (HMENU)iToolBarID,                // Toolbar ID.
    tbBitmaps->hInst,                 // Current instance.
    NULL );                           // No class data.

  if (hWndToolBar)
  {
    // Load the bitmaps for the toolbar.
    if (SendMessage(hWndToolBar, TB_ADDBITMAP, lNumBitmaps, 
            (LONG) &tbBitmaps) == -1)  
        return (NULL);
    // Add the buttons to the toolbar.
    SendMessage(hWndToolBar, TB_ADDBUTTONS, lNumButtons, (LONG) &tbButtons);
    // The toolbar was created with the buttons successfully.
    // Return the handle to the toolbar.
    return (hWndToolBar);
  }
  // There was an error creating the toolbar; return NULL.
  return NULL;
}

Another method of creating a toolbar is to call the CreateToolBarEx function. This function performs the same actions that I outlined above in MyCreateToolBar. The CreateToolBarEx function takes the following parameters:

You can add ToolTips support to your toolbar by specifying the TBSTYLE_TOOLTIPS style and creating a STRINGTABLE that contains the text to display in your .RC file. Once you have done this, you process the WM_NOTIFY message that is sent to the parent window procedure of the toolbar, as shown in the code below.

// This code goes in your .RC file.
STRINGTABLE
BEGIN
    IDM_OPT1, "Option 1"
    IDM_OPT2, "Option 2"
    IDM_OPT3, "Option 3"
    IDM_EXIT, "Exit Tool bar Sample"
END

// This code goes in your .C file.
TOOLINFO tbToolInfo;

// Trap the WM_NOTIFY message.
case WM_NOTIFY:
    lpToolTipText = (LPTOOLTIPTEXT)lParam;
    if (lpToolTipText->hdr.code ==  TTN_NEEDTEXT)
    {
        // If the system needs text, load it from the resource.
        LoadString (hInst, 
            lpToolTipText->hdr.idFrom,    // string ID == cmd ID
            szBuf,
            sizeof(szBuf));
        // Point the structure to the string.
        lpToolTipText->lpszText = szBuf;
    }
    break;

To see how the code above behaves, click to open the Toolbar project files and run TOOLBAR.EXE.

Warning   The Toolbar executable file was built and tested using the Windows 95 Preliminary Development Kit. The executable will run only on Windows 95; it will not run under Windows 3.1 or Windows NT 3.5. If you have Windows 95 installed on your computer but you have problems running this sample, copy the project files to your system, rebuild the project, and run the executable.

Toolbar Structures

This section describes the new structures that you can use in Win32 to create and manipulate toolbars and their buttons. Each button that you add to a toolbar can have one of the styles listed in the table below. These button styles can be used in combination and are included in the TBBUTTON structure described below.

Table 2. Toolbar Button Styles

Style Use
TBSTYLE_BUTTON Creates a standard button.
TBSTYLE_CHECK Creates a button that stays pressed until released.
TBSTYLE_CHECKGROUP Creates a checked button that stays pressed until released or until another button in the group is pressed.
TBSTYLE_GROUP Creates a checked button that stays pressed until another button in the group is pressed.
TBSTYLE_SEP Creates a separator, which provides a small gap between button groups.

Once you specify your toolbar and its buttons, you may need to query the toolbar for information about the current state of a button. The current state is kept in a TBBUTTON structure, as described below. If you need to determine the state of a button dynamically, you can send the TB_GETSTATE message to the toolbar.

Table 3. Toolbar Button States

State Meaning
TBSTATE_CHECKED The button is checked.
TBSTATE_ENABLED The button is enabled.
TBSTATE_HIDDEN The button is hidden.
TBSTATE_INDETERMINATE The button is indeterminate.
TBSTATE_PRESSED The button is pressed.

TBBUTTON

typedef struct tagTBBUTTON {
    int iBitmap;       \\ index of the bitmap image of the button
    int idCommand;     \\ command identifier of the button
    BYTE fsState;      \\ button state flags, as listed in Table 3
    BYTE fsStyle;      \\ button style, as listed in Table 2
    DWORD dwData;      \\ application-defined data
    int iString;       \\ index of the help text string for the button
} TBBUTTON;

The TBBUTTON structure contains information about a button in a toolbar. TBBUTTON includes the following members:

ADJUSTINFO

typedef struct tagADJUSTINFO {
    TBBUTTON tbButton;        \\ structure containing button information
    char szDescription[1];    \\ TBD
};

The ADJUSTINFO structure contains information about a button in a toolbar that is being customized by the user. The structure includes the following members:

TBADDBITMAP

typedef struct tagTBADDBITMAP {
    HINSTANCE hInst;    \\ handle to the instance containing the bitmaps
    UINT nID;           \\ resource identifier for the bitmap
} TBADDBITMAP;

The TBADDBITMAP structure contains information about the bitmaps to add to a toolbar. It is used when writing a Win32 application. TBADDBITMAP includes the following members:

Toolbar Messages

The system and applications send messages to toolbars, just as they send messages to any other window. This section lists the messages that can be sent to toolbar controls and the values for the wParam and lParam for each message.

TB_ADDBITMAP

wParam = nButtons;                   \\ number of buttons in the bitmap
lParam = (LPTBADDBITMAP)lptbab;      \\ handle of the bitmap

Description: The TB_ADDBITMAP message adds a new bitmap to the list of bitmaps available for a toolbar. This message is for non-Win32 applications only.

Parameters: wParam represents the number of buttons in the bitmap. lParam is a pointer to the TBADDBITMAP structure.

Return value: The low-order word contains the index of the first button bitmap. The high-order word is not used if the call is successful; otherwise, the low-order word is –1.

TB_ADDBUTTONS

wParam = nButtons;                \\ number of buttons
lParam = (LPTBBUTTON)lpButtons;   \\ address of array of button structures

Description: The TB_ADDBUTTONS message adds one or more buttons to a toolbar.

Parameters: wParam represents the number of buttons to add to the toolbar. lParam is the address of an array of TBBUTTON structures containing information about the buttons to add. The array must contain the same number of elements as buttons specified by wParam.

Return value: TRUE if successful; FALSE otherwise.

TB_ADDSTRING

wParam = (HINSTANCE)hInst;        \\ module instance containing the string
lParam = (MAKELONG)(idString, 0); \\ string identifier or string buffer

Description: The TB_ADDSTRING message adds a new string to the list of strings available for a toolbar.

Parameters: wParam is the handle of the module instance with an executable file that contains the string resource. This parameter is zero if lParam points to one or more strings. lParam is the resource identifier for the string resource or the address of a buffer that contains one or more null-terminated strings to add to the list, depending on the value of wParam. The last string must be terminated with two NULL characters.

Return value: The index of the first new string if successful; otherwise –1.

TB_AUTOSIZE

wParam = 0;                       \\ not used
lParam = 0;                       \\ not used

Description: The TB_AUTOSIZE message causes a toolbar to be resized. An application sends this message whenever it does something (sets the button or bitmap size or adds strings) to change the size of a toolbar.

Parameters: wParam and lParam are not used.

Return value: None.

TB_BUTTONCOUNT

wParam = 0;                       \\ not used
lParam = 0;                       \\ not used

Description: The TB_BUTTONCOUNT message gets a count of the buttons currently in the toolbar.

Parameters: wParam and lParam are not used.

Return value: The number of buttons in the toolbar.

TB_BUTTONSTRUCTSIZE

wParam = cb;                  \\ size of the TBBUTTON structure in bytes
lParam = 0;                   \\ not used

Description: The TB_BUTTONSTRUCTSIZE specifies the size of the TBBUTTON structure. The system uses this size to determine the version of COMMCTRL.DLL that is being used. If an application uses CreateWindow to create the toolbar, it must send this message before adding any buttons to the toolbar. The CreateToolBarEx function automatically sends this message, and the size of the TBBUTTON structure is a parameter to the CreateToolbarEx function.

Parameters: wParam is the size, in bytes, of the TBBUTTON structure. lParam is not used.

Return value: None.

TB_CHECKBUTTON

wParam = idButton;             \\ command identifier of the button to check
lParam = MAKELONG(fCheck, 0);  \\ Check flag - TRUE to add, FALSE to remove

Description: The TB_CHECKBUTTON message checks or unchecks a given button. When a button has been checked, it appears pressed.

Parameters: wParam is the command identifier of the button to check. If lParam is TRUE, the check is added; if lParam is FALSE, the check is removed.

Return value: TRUE if successful; FALSE otherwise.

TB_COMMANDTOINDEX

wParam = idButton;                \\ command identifier of the button
lParam = 0;                       \\ not used

Description: The TB_COMMANDTOINDEX message gets the zero-based index for the button associated with the specified command identifier.

Parameters: wParam is the command identifier associated with the button. lParam is not used.

Return value: The zero-based index for the button.

TB_CUSTOMIZE

wParam = 0;                       \\ not used
lParam = 0;                       \\ not used

Description: The TB_CUSTOMIZE message displays the Customize Toolbar dialog box.

Parameters: wParam and lParam are not used.

Return value: None.

TB_DELETEBUTTON

wParam = iButton;              \\ zero-based index of the button to delete
lParam = 0;                    \\ not used

Description: The TB_DELETEBUTTON message deletes a button from the toolbar.

Parameters: wParam is the zero-based index of the button to delete. lParam is not used.

Return value: TRUE if successful; FALSE otherwise.

TB_ENABLEBUTTON

wParam = idButton;               \\ command identifier of the button
lParam = MAKELONG(fEnable, 0);   \\ flag - TRUE to enable, FALSE to disable

Description: The TB_ENABLEBUTTON message enables or disables the specified button. When a button has been enabled, it can be pressed and checked.

Parameters: wParam is the command identifier of the button to enable or disable. If lParam is TRUE, the button is enabled; if lParam is FALSE, the button is disabled.

Return value: TRUE if successful; FALSE otherwise.

TB_GETBUTTON

wParam = iButton;                \\ zero-based index of the button to get
lParam = (LPTBBUTTON)lpButton;   \\ buffer that receives the button information

Description: The TB_GETBUTTON message retrieves information about the given button.

Parameters: wParam is the zero-based index of the button for which to get information. lParam is the address of the TBBUTTON structure that receives the button information.

Return value: TRUE if successful; FALSE otherwise.

TB_GETITEMRECT

wParam = iButton;               \\ zero-based index of the button
lParam = (LPRECT)lprc;          \\ array that receives the rectangle values

Description: The TB_GETITEMRECT message gets the bounding rectangle of a button in a toolbar. This message does not get the bounding rectangle for buttons whose state is set to TBSTATE_HIDDEN.

Parameters: wParam is the zero-based index of the button for which to get information. lParam is the address of a RECT structure that receives the coordinates of the bounding rectangle.

Return value: TRUE if successful; FALSE otherwise.

TB_GETSTATE

wParam = idButton;                \\ command identifier of the button
lParam = 0;                       \\ not used

Description: The TB_GETSTATE message gets information about the state of the button, such as whether it is enabled, pressed, or checked.

Parameters: wParam is the command identifier of the button for which to get information. lParam is not used.

Return value: If the call is successful, the message returns the button state information as listed in Table 3. If the call is not successful, the message returns –1.

TB_HIDEBUTTON

wParam = idButton;                \\ command identifier of the button
lParam = MAKELONG(fShow, 0);      \\ TRUE to show and FALSE to hide

Description: The TB_HIDEBUTTON message hides or shows the specified button.

Parameters: wParam is the command identifier of the button to hide or show. If lParam is TRUE, the button is hidden; if lParam is FALSE, the button is shown.

Return value: TRUE if successful; FALSE otherwise.

TB_INDETERMINATE

wParam = idButton;                     \\ command identifier of the button
lParam = MAKELONG(fIndeterminate, 0);  \\ TRUE to set and FALSE to clear

Description: The TB_INDETERMINATE message sets or clears the indeterminate state of the specified button.

Parameters: wParam is the command identifier of the button whose indeterminate state is to be set or cleared. If lParam is TRUE, the indeterminate state is set; if lParam is FALSE, the indeterminate state is cleared.

Return value: TRUE if successful; FALSE otherwise.

TB_INSERTBUTTON

wParam = iButton;                 \\ zero-based index of the button
lParam = (LPTBBUTTON)lpButton;    \\ button information structure

Description: The TB_INSERTBUTTON message inserts a button in the toolbar.

Parameters: wParam is the zero-based index of a button. The TB_INSERTBUTTON message inserts the new button in front of the button identified by wParam. lParam is the address of a TBBUTTON structure containing information about the button to insert.

Return value: TRUE if successful; FALSE otherwise.

TB_ISBUTTONCHECKED, TB_ISBUTTONENABLED, TB_ISBUTTONHIDDEN, TB_ISBUTTONINDETERMINATE, TB_ISBUTTONPRESSED

wParam = idButton;                \\ command identifier of the button
lParam = 0;                       \\ not used

Description: These messages determine whether the given button is checked, enabled, hidden, indeterminate, or pressed.

Parameters: wParam is the command identifier of the button. lParam is not used.

Return value: Nonzero if the button if TRUE; otherwise, returns zero.

TB_PRESSBUTTON

wParam = idButton;                \\ command identifier of the button
lParam = MAKELONG(fPress, 0);     \\ TRUE to press and FALSE to release

Description: The TB_PRESSBUTTON message presses or releases the given button.

Parameters: wParam is the command identifier of the button to press or release. If lParam is TRUE, the button is pressed; if lParam is FALSE, the button is released.

Return value: TRUE if successful; FALSE otherwise.

TB_SAVERESTORE

wParam = (BOOL)fSave;             \\ TRUE to save and FALSE to restore
lParam = (LPSTR)lpszSectionFile;  \\ strings used to save the information

Description: The TB_SAVERESTORE message saves or restores the state of the toolbar.

Parameters: If wParam is TRUE, the information is saved; otherwise, it is restored. lParam is the address of two consecutive null-terminated strings. The first string specifies the name of a section in an initialization file. The second string specifies the name of the initialization file. If the second string is empty, the message uses the WIN.INI file by default.

Return value: None.

TB_SETBITMAPSIZE

wParam = 0;                              \\ not used
lParam = MAKELONG(dxBitmap, dyBitmap);   \\ width and height to set

Description: The TB_SETBITMAPSIZE message sets the size of the bitmapped images to be added to a toolbar. The size can be set only before adding any bitmaps to the toolbar. If an application does not explicitly set the bitmap size, the size defaults to 16-by-15 pixels.

Parameters: wParam is not used. lParam is the width and height, in pixels, of the bitmapped images.

Return value: TRUE if successful; FALSE otherwise.

TB_SETBUTTONSIZE

wParam = 0;                            \\ not used
lParam = MAKELONG(dxButton, dyButton); \\ width and height to set

Description: The TB_SETBUTTONSIZE message sets the size of the buttons to be added to a toolbar. You can set the button size only before you add any buttons to the toolbar. If an application does not explicitly set the button size, the size defaults to 24-by-22 pixels.

Parameters: wParam is not used. lParam is the width and height, in pixels, of the buttons.

Return value: TRUE if successful; FALSE otherwise.

TB_SETSTATE

wParam = idButton;                \\ command identifier of the button
lParam = MAKELONG(fState,0);      \\ state to set as listed in Table 3

Description: The TB_SETSTATE message sets the state for the given button.

Parameters: wParam is the command identifier of the button. lParam consists of the state flags, as listed in Table 3.

Return value: TRUE if successful; FALSE otherwise.

Toolbar Notification Messages

This section lists the notification messages that Windows sends to toolbar windows. The parent window of the toolbar receives these messages via a WM_COMMAND message. Unless otherwise noted, Windows ignores the return value from these messages. In all cases, the wParam contains the identifier for the toolbar.

Table 4. Toolbar Notification Messages

Message Description lParam
TBN_ADJUSTINFO Sent when the user is customizing a toolbar. Returns a handle to a global memory object containing an ADJUSTINFO structure. Button index
TBN_BEGINADJUST Sent when the user begins customizing a toolbar. 0—not used
TBN_BEGINDRAG Sent when the user begins dragging a button in a toolbar. Button command ID
TBN_CUSTHELP Sent when the user chooses the Help button in the Customize Toolbar dialog box. Customize Toolbar dialog box handle
TBN_ENDADJUST Sent when the user finishes customizing a toolbar. 0—not used
TBN_ENDDRAG Sent when the user stops dragging a button in a toolbar. Button command ID
TBN_QUERYDELETE Sent when the user attempts to delete a button while customizing a toolbar. Returns TRUE to delete the button, or FALSE to prevent the button from being deleted. Button index
TBN_QUERYINSERT Sent when the user attempts to insert a button while customizing a toolbar. Returns TRUE to insert the new button in front of the given button, or FALSE to prevent the button from being inserted. Button index
TBN_RESET Sent when the user resets a customized toolbar. 0—not used
TBN_TOOLBARCHANGE Sent when the user has customized a toolbar. Toolbar handle

Summary

Status bars and toolbars are very handy controls that are familiar to users and easy to implement. These controls are built into Windows 95, so you will no longer have to worry about whether your toolbar or status bar conforms to the way the operating system or other companies implement these controls. If you are planning to add status bars or toolbars to your existing application, I suggest that you give these new common controls a try. Adding value to your application can hardly get any easier than this.