Creating a Toolbar Bitmap

If you have never produced a toolbar before, one of the “mysteries” you need to solve is how to create the bitmaps for the buttons. If you are like me, you might expect to create a bitmap for each button, include the bitmaps in your application, and pass the identifiers to these bitmaps to set each button. Well, that's not the way it's done. You do create a bitmap for each button, but you then build a larger bitmap by stringing together all of the small ones.

But what if you want to get your grubby little hands on the bitmaps that Windows Explorer uses for its Open, Save, and other buttons? One way to do this is to run AppWizard and write a stub program that includes a toolbar. By default, AppWizard gives you the standard bitmaps in a file ever-so-creatively called TOOLBAR.BMP (located in the RES subfolder of your project folder). You can edit this file with the resource editor built into Visual C++ or with Microsoft Paint. (Be sure to create a 16-color bitmap rather than a 256-color bitmap.) Figure 1-4 (zoomed up to a readable size) shows the standard set of bitmaps that AppWizard supplies. The last bitmap provides an easy way for the user to get help on an item shown in the application's window. When you click this bitmap, the cursor changes from an arrow pointer to a combination of an arrow and a question mark. Pointing with the new cursor and clicking a control or a window displays a Help topic for that item. (The TOOLBAR sample doesn't support this feature.)

Figure 1-4.

An example of a toolbar bitmap.

Even if you don't use AppWizard, you aren't out of luck: the standard toolbar bitmaps are now built into COMCTL32.DLL. You can add these images to your toolbar by using the TB_ADDBITMAP message. The following code sample shows you how to include three of the standard file bitmaps (new, open, and save) and four of the view bitmaps (large icon view, small icon view, list view, and details view). The code fills out the TBBUTTON structure with the predefined indexes to the bitmaps you want:

// Toolbar buttons
TBBUTTON tbButtons [] =
{
{STD_FILENEW, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{STD_FILEOPEN, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{STD_FILESAVE, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},
{VIEW_LARGEICONS, IDM_LARGEICON, TBSTATE_ENABLED, TBSTYLE_BUTTON,
0L, 0},
{VIEW_SMALLICONS, IDM_SMALLICON, TBSTATE_ENABLED, TBSTYLE_BUTTON,
0L, 0},
{VIEW_LIST, IDM_LISTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON,
0L, 0},
{VIEW_DETAILS, IDM_REPORTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON,
0L, 0},
};

Next, in the code that will create the toolbar, the application calls the CreateToolbarEx function, specifying HINST_COMMCTRL as the HINSTANCE, IDB_STD_SMALL_COLOR as the bitmap identifier, and a pointer to the TBBUTTON structure. Notice that 11 bitmaps are specified because the IDB_STD_SMALL_COLOR bitmap contains 11 bitmaps. Notice also that four buttons are specified; this refers to the last four view buttons, which come from a different bitmap. When the toolbar is created, the view bitmaps are added through the TB_ADDBITMAP message. This message returns an index that is used to provide the correct index to the view bitmaps.

HWND CreateTheToolbar (HWND hWndParent)
{
HWND hWndToolbar;
TBADDBITMAP tb;
int index, stdidx;

hWndToolbar = CreateToolbarEx (hWndParent,
WS_CHILD | WS_BORDER | WS_VISIBLE | WS_CHILD | TBSTYLE_TOOLTIPS,
ID_TOOLBAR, 11, (HINSTANCE)HINST_COMMCTRL, IDB_STD_SMALL_COLOR,
(LPCTBBUTTON)&tbButtons, 4, 0, 0, 100, 30, sizeof (TBBUTTON));

// Add the system-defined view bitmaps.
// The hInst == HINST_COMMCTRL
// The nID == IDB_VIEW_SMALL_COLOR
tb.hInst = HINST_COMMCTRL;
tb.nID = IDB_VIEW_SMALL_COLOR;
stdidx = SendMessage (hWndToolbar, TB_ADDBITMAP, 12, (LPARAM)&tb);

// Update the indexes to the bitmaps.
for (index = 4; index < NUM_BUTTONS; index++)
tbButtons[index].iBitmap += stdidx;

// Add the view buttons.
SendMessage (hWndToolbar, TB_ADDBUTTONS, 4, (LONG) &tbButtons[4]);

return hWndToolbar;
}

TIP: When you create toolbar bitmaps, you'll often have trouble knowing exactly where you are in the image and getting the images to line up properly. With Windows 95, the images are actually taken out of the bitmap in such a manner that the originating bitmap doesn't have to exactly match the height and width based on the calls that load the bitmap—that is, you tell the CreateToolbarEx function how wide and how tall you want the individual bitmaps to be. This allows you to create a bitmap that will look something like the one shown here. In this bitmap, you can easily see the exact locations of the button boundaries as well as the identifiers for the different images.