Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / WTL
Article

Fun with Common Controls Bitmaps and Toolbars

Rate me:
Please Sign up or sign in to vote.
4.45/5 (10 votes)
29 May 2004CPOL5 min read 109.7K   2.1K   23   20
A WTL mix-in class for creating toolbar controls using common controls bitmaps instead of local resources.

Sample screenshot

Introduction

I've been lurking around The Code Project for years now, but this is my first contribution. It's a mix-in class to help a CFrameWindowImpl derived class build a toolbar using the standard WIN32 common controls bitmaps. This class can be used to avoid weighing that lean-and-mean WTL app down with bitmap resources for such commonplace toolbar buttons as print, save, etc. While this may seem like an awful lot of trouble for nothing, I'm a WTL newbie and I wanted to see if I could make my WTL app a little bit leaner. Also, for a variety of other reasons, I like using system resources and controls instead of custom objects. For instance, if a resource is updated when a new version of Windows comes out, an application that inherits from the system automatically inherits the new look, whereas an application that defines its own resource must often be rebuilt just to avoid looking dated.

Background

The common controls bitmap constants and the indices to the individual images within those bitmaps are documented in the Platform SDK in various locations depending on the SDK version. Two locations I know of are:

  1. User Interface Services/Shell and Common Controls/Common Controls/Toolbar Controls/Toolbar Control Reference/Toolbar Standard Button Image Index Values
  2. User Interface Services/Windows Controls/Individual Control Information/Toolbar Controls/Toolbar Controls Reference/Constants/Toolbar Standard Button Image Index Values

In some cases, these constants are incorrectly documented. They're defined in the Platform SDK's <commctrl.h> file, which is also where the TBBUTTON structure type is defined:

typedef struct _TBBUTTON {
    int iBitmap;
    int idCommand;
    BYTE fsState;
    BYTE fsStyle;
#ifdef _WIN64
    BYTE bReserved[6];          // padding for alignment
#elif defined(_WIN32)
    BYTE bReserved[2];          // padding for alignment
#endif
    DWORD_PTR dwData;
    INT_PTR iString;
} TBBUTTON, NEAR* PTBBUTTON, *LPTBBUTTON;

It includes some undocumented padding which varies in size depending on the target platform. To simplify TBBUTTON array initialization statements, I define the TBBPADDING macro in SysToolbarCtrl.h, and macros for buttons corresponding to the toolbar icons.

In order to make the demo a little more interesting than a simple frame window with a do-nothing toolbar, I've stolen (well, OK, "borrowed" may be a gentler way of putting it) some other peoples' ideas:

  • Leon Finker's IShellBrowser article
  • Ed Gadziemski's Pixview sample application, which sadly doesn't seem to be available on Code Project anymore. I used his CPix class, which uses IPicture to load and render image files. I guess there are plenty of other examples of how to use IPicture.

Using the code

There are four simple steps to using this code:

  1. This probably doesn't need to be said, but I'll say it anyway: include the header file SysToolbarCtrl.h in your mainframe class precompiler directives:
    #include "SysToolbarCtrl.h"
  2. Include CFrameWindowImpl and CSysToolbarCtrl in your mainframe's inheritance list:
    class CMainFrame : public CFrameWindowImpl<CMainFrame>,
            public CSysToolbarCtrl<CMainFrame>,
            ...
  3. Instead of calling CreateSimpleToolBarCtrl in your mainframe class' OnCreate method (or whatever technique you normally use to create your toolbar), declare and initialize a TBBUTTON array, then call CreateSysToolbarCtrl as follows:
    // init toolbar button array, including separators, if any.
    TBBUTTON tbb[] =
    {
        // File|New
        STBB_STD_FILENEW,
        // File|Save
        STBB_STD_FILESAVE,
        // separator
        STBB_SEPARATOR,
        // View|Parent folder
        STBB_VIEW_PARENTFOLDER(ID_VIEW_PARENTFOLDER),
        // separator
        STBB_SEPARATOR,
        // Help|About
        STBB(STD_HELP, ID_APP_ABOUT, IDB_STD_SMALL_COLOR)
    };
    
        // create the toolbar control
        HWND hWndToolBar = CreateSysToolbarCtrl(m_hWnd, tbb,
            sizeof(tbb)/sizeof(TBBUTTON), &m_CmdBar);

    The code uses some macros I defined to specify the toolbar buttons. The macros come in three basic forms, which all use STBB (System Tool Bar Button) as a prefix:

    • STBB_IMG_ID, where IMG_ID is the button's image identifier as defined in <commctrl.h>. This form assigns a default command ID to the button using the command IDs defined in <atlres.h>;
    • STBB_IMG_ID(CMD_ID), where IMG_ID is as described above, and CMD_ID is the command ID that should be associated with the toolbar button. This is used when there is no standard command ID in the <atlres.h> file that corresponds to the button image, as in the case of VIEW_PARENTFOLDER;
    • STBB(IMG_ID, CMD_ID, BITMAP_ID), where IMG_ID and CMD_ID are as described previously, and BITMAP_ID is the bitmap ID defined in <commctrl.h> that contains the button image identified by IMG_ID. This is the one to use when you want to override the default command ID for a particular toolbar button, as I do in the demo for Help|About.

    Use your favorite resource editor to define your menus as you normally would. You can include the command IDs defined by your resource editor in the system toolbar. If <atlres.h> pre-defines any command IDs you could use in your menus, those can be used as well. Needless to say, the specified command ID should have an associated handler somewhere in the application's message map, and may have a corresponding menu item as well. In the demo, I've only provided a handler for two of the buttons (View|Parent folder, and Help|About) but it should be enough to give you a general idea of how it all works.

    You can also include a pointer to a CCommandBarCtrl as a parameter, and CreateSysToolbarCtrl will put the bitmaps on the appropriate menu items. If you aren't using a command bar, passing NULL (the default value) will cause CreateSysToolbarCtrl to ignore this parameter.

  4. Last, but not least, don't forget to remove any references to the toolbar bitmap you no longer want, from your resource script (*.rc file). You might want to do this manually using a bare-bones text editor instead of Visual C++. Simply commenting out the unwanted line should work:
    ///////////////////////////////////////////////////////////////////////
    //
    // Bitmap
    //
    
    // IDR_MAINFRAME           BITMAP  MOVEABLE PURE   "res\\Toolbar.bmp"

    Now if you try to open the toolbar in the Visual C++ IDE, it will squawk at you and ask you if you want to create a bitmap for the toolbar. JUST SAY NO!

Points of Interest

  • The STD_HELP image is the arrow-question-mark traditionally used for context help. Where's the classic yellow question mark?
  • There is no image for VIEW_VIEWMENU on any system I've looked at, yet it's in <commctrl.h>. What gives?
  • For the enterprising reader, there are other system bitmaps available to make hot/cold image toolbars. Of course, the code would have to be modified somewhat, and that's beyond the scope of this article.
  • Yes, I know, I might be cheating when my IShellBrowser implementation gets a selected item's PIDL from the IShellView window. That's because I don't know the "right" way to do it.
  • I found a way to synch a tree control with the shell folder view, but it's an undocumented hack and I didn't include it in this article. It's really just a brute-force method, but if anybody's interested, email me and I'll send you the code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
A geek-of-all-trades who's masqueraded as a software engineer, metrologist, production engineer, BB stacker, and translator, just to name a few.

Comments and Discussions

 
Questioncan you give me more information about the application?The detailed steps Pin
skyfreedoms3-Jun-09 5:42
skyfreedoms3-Jun-09 5:42 
HI,
can you give me more information about the application?The detailed steps

thanks!

The best post to my email
AnswerRe: can you give me more information about the application?The detailed steps Pin
Jon Feider3-Jun-09 6:50
Jon Feider3-Jun-09 6:50 
GeneralCombining standard and propietary bitmaps Pin
Pablo Aliskevicius23-Mar-04 2:01
Pablo Aliskevicius23-Mar-04 2:01 
GeneralRe: Combining standard and propietary bitmaps Pin
Jon Feider30-Mar-04 14:17
Jon Feider30-Mar-04 14:17 
Generalnice work ..... Pin
hero24_m8-Nov-03 20:33
hero24_m8-Nov-03 20:33 
GeneralRe: nice work ..... Pin
Jon Feider8-Nov-03 22:34
Jon Feider8-Nov-03 22:34 
GeneralRe: nice work ..... Pin
hero24_m11-Nov-03 4:18
hero24_m11-Nov-03 4:18 
QuestionAnybody get this to work under XP? Pin
Jon Feider3-Nov-03 23:01
Jon Feider3-Nov-03 23:01 
AnswerRe: Anybody get this to work under XP? Pin
Member 66485811-Nov-03 12:31
Member 66485811-Nov-03 12:31 
GeneralRe: Anybody get this to work under XP? Pin
Jon Feider12-Nov-03 22:52
Jon Feider12-Nov-03 22:52 
GeneralI got it to build... Pin
Toby Jacob Rhodes3-Nov-03 5:08
Toby Jacob Rhodes3-Nov-03 5:08 
GeneralRe: I got it to build... Pin
Jon Feider3-Nov-03 6:09
Jon Feider3-Nov-03 6:09 
GeneralRe: I got it to build... Pin
Jon Feider3-Nov-03 6:17
Jon Feider3-Nov-03 6:17 
GeneralCannot build Pin
Stanislav Panasik2-Nov-03 22:51
Stanislav Panasik2-Nov-03 22:51 
GeneralRe: Cannot build Pin
Jon Feider3-Nov-03 6:06
Jon Feider3-Nov-03 6:06 
GeneralRe: Cannot build Pin
Stanislav Panasik3-Nov-03 7:02
Stanislav Panasik3-Nov-03 7:02 
GeneralRe: Cannot build Pin
Jon Feider3-Nov-03 7:11
Jon Feider3-Nov-03 7:11 
Generalatlres.h Pin
bruno leclerc2-Nov-03 21:05
bruno leclerc2-Nov-03 21:05 
GeneralRe: atlres.h Pin
Jon Feider2-Nov-03 21:20
Jon Feider2-Nov-03 21:20 
GeneralRe: atlres.h Pin
bruno leclerc2-Nov-03 21:29
bruno leclerc2-Nov-03 21:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.