Creating a Toolbar

Creating a toolbar is simple: you fill out a button structure, create a large bitmap containing the buttons, and then call the CreateToolbarEx function. This function takes care of adding the bitmaps and buttons to the toolbar. Then, unless you want to do something special, you can just let the system handle the toolbar processing. 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 TBSTYLE_TOOLTIPS window style allows the toolbar to display ToolTips. Windows sends a WM_NOTIFY message to the toolbar whenever Windows needs to display text in a pop-up.

The following code snippet from the TOOLBAR sample creates a toolbar with 24 “buttons,” 8 of which are actual buttons. The bitmap provided for each button is 16-by-16 pixels. The total number of buttons (24) includes all separators. Because you will add a combo box, you must place separators as placeholders where the combo box will reside. Once you create the toolbar, you can create the combo box in the standard way and parent it to the toolbar window, which adds this nonbutton control to your toolbar.

TBBUTTON tbButtons [] =
{
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{0, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{1, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{2, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{3, IDM_CUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{4, IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{5, IDM_PASTE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{6, IDM_PRINT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{7, IDM_ABOUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}
};

TOOLINFO tbToolInfo;

char *szStrings[] = {"Nancy", "Dale", "Dennis", "Herman", "Ken", "Kyle",
"Nigel", "Renan", "Ruediger"};

static HWND hWndToolbar;

// Create the toolbar control.
hWndToolbar = CreateToolbarEx (
hWnd, // parent
WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS |
CCS_ADJUSTABLE, // window style
ID_TOOLBAR, // toolbar ID
8, // number of bitmaps
hInst, // mod instance
IDB_TOOLBAR, // resource ID for bitmap
(LPCTBBUTTON)&tbButtons, // address of buttons
24, // number of buttons
16, 16, // width & height of buttons
16, 16, // width & height of bitmaps
sizeof (TBBUTTON)); // structure size

if (hWndToolbar == NULL)
{
MessageBox (NULL, "Toolbar not created!", NULL, MB_OK);
break;
}

// Create the combo box and add it to the toolbar.
hWndCombo = CreateWindowEx (0L, // no extended styles
"COMBOBOX", // class name
"", // default text
WS_CHILD | WS_BORDER | WS_VISIBLE |
CBS_HASSTRINGS | CBS_DROPDOWN, // styles and defaults
0, 0, 100, 250, // size and position
hWndToolbar, // parent window
(HMENU)IDM_COMBO, // ID
hInst, // current instance
NULL); // no class data

if (hWndCombo)
{
// Add strings to the combo box.
for (idx = 0; idx < 9; idx++)
SendMessage (hWndCombo, CB_INSERTSTRING, (WPARAM)(-1),
(LPARAM)szStrings[idx]);
}

Using the MFC-supplied class CToolBarCtrl, I had to do a bit more work. The Create member function provided by MFC merely creates the toolbar; it doesn't load the bitmap or add the buttons. This is no big deal, however, because you simply need to call the AddBitmap and AddButtons member functions to add these items to your toolbar.

int CMfctoolView::OnCreate (LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate (lpCreateStruct) == -1)
return -1;

// Create the toolbar.
m_ToolBar.Create (
WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS |
CCS_ADJUSTABLE, // style
Crect (0, 0, 0, 0),
this,
ID_TOOLBAR);

// Add the bitmaps.
m_ToolBar.AddBitmap (8, IDB_BITMAP1);

// Add the buttons.
m_ToolBar.AddButtons (24, (LPTBBUTTON)&tbButtons);

// Create the combo box.
m_Combo.Create (
WS_CHILD | WS_BORDER | WS_VISIBLE | CBS_HASSTRINGS | CBS_DROPDOWN,
Crect (0, 0, 100, 250),
(CWnd *)&m_ToolBar,
ID_COMBO);

int idx;
for (idx = 0; idx < 8; idx++)
m_Combo.InsertString (-1, (LPCTSTR)szStrings[idx]);

return 0;
}

The preceding code does not specify a size for the toolbar. Instead, you can size the toolbar when the parent window (the client window for you C people, or the View window for MFC fans) handles the WM_SIZE message. In response to this message, you can use the TB_AUTOSIZE message (or the MFC AutoSize member function) to tell the toolbar to size itself.