March 2, 2021
Hot Topics:

Adapting Application Menus to the CE User Interface

  • By Nancy Nicolaisen
  • Send Email »
  • More Articles »

Creating the Command Bar

The first time we create the command bar based menu is in response to the WM_CREATE Message, which we process in the message switch of WndProc().

case WM_CREATE:  hwndCB = CommandBar_Create( hInst,                               hWnd, 1);       CommandBar_InsertMenubar( hwndCB,                             hInst,                             IDM_MENU, 0);  CommandBar_AddAdornments(hwndCB, 0, 0);  break;

Here's something to keep in mind with command bars ( and also with their cousins, command bands.) Creating a command bar reserves some real estate and sets up a container in which you can place other controls and interface elements. Most of the work of your program will entail dealing with the objects you've placed in the command bar. You can only manipulate those objects by using the command bar's access functions to do so.

         hwndCB = CommandBar_Create(hInst, hWnd, 1);     

This line creates an empty command bar. The parameters, in the order shown, are the instance handle, the main window's handle, and the command bar's ID, which we set to 1. The return value is the handle to the command bar.

         CommandBar_InsertMenubar(hwndCB, hInst, IDM_MENU, 0);

This line sets a menu resource into the command bar. The parameters, in the order shown, are the handle to the command bar, the instance handle, the resource ID of the menu to load, and the zero based index of a button on the command bar. The menu will be loaded to the left of the button specified by the index. It is possible to load more than one menubar in a command bar, but this contravenes the Windows CE design guidelines, so it's not a good practice. According to the guidelines, there should be one menubar per command bar and it should be the leftmost element.

         CommandBar_AddAdornments(hwndCB, 0, 0);

This bit of code is a real powerhouse, and it has some implications of which it's worth being aware. "Adornments" are the optional controls that appear at the right hand side of a menu based on a command bar. Most command bars will include the Close button, and that is the one we are adding here. You may optionally include the OK and the Help buttons as well.

Table 3- CommandBar_AddAdornments Flags

Adornment FlagWhat It AddsCommand Message
CMDBAR_OKOK buttonWM_COMMAND (with IDOK as the message identifier

The Close, OK and Help buttons exist not only to provide the main window with messages, but can also replace the same buttons in a dialog box. This means that your dialogs can be smaller. Command bar elements each occupy a specific region on the command bar and this location is important to the internal management of the command bar's controls. Always add the command bar adornments last, that is to say, after all the rest of the command bar's control elements have been added. This will ensure they have sole claim to the real estate at the rightmost edge of the command bar.

Dynamically Modifying the Command Bar Based Menu

When we initially created the command bar menu, we loaded the menu resource IDM_. This resource file fragment shows the content of the View menu item.

    POPUP "View"    BEGIN        MENUITEM "Add Menu Buttons",            IDM_MENU_BTNS        MENUITEM "Add Combo",                   IDM_COMBO        MENUITEM "Add Dropdown Button",         IDM_DROP_BTN        MENUITEM "Add Check Button",            IDM_CHECK_BTN        MENUITEM "Add Radio Buttons",           IDM_RADIO_BTNS    END

The MenuBar example let's you "modify" the command bar menu on the fly, adding the different kinds of elements shown in menu choices. In fact, what we have to do is destroy the command bar and create a new one each time we get one of these requests from the user. First we'll go thru the code that creates and disp[lays the new kinds of command bar elements, then we'll look at how the menu items communicate with the main window.

Adding Command Bar Buttons

Here's some great news about this whole command bar based menu idea. The code for adding buttons to the command bar, any kind or number of buttons, is always the same. It looks like this:

    //Add the buttons    CommandBar_AddButtons(hwndCB, 4, &tbCmdButtons);

The parameters, in the order shown, are the handle to the command bar, the number of buttons to add, and the address of an array of TBBUTTON structures. As you may see, the TBBUTTON structure is the key to the process. Here's the declaration of the TBBUTTON structure.

typedef struct _TBBUTTON {          int iBitmap;   //Resource ID of button's bitmap image         int idCommand; //command Id for this button         BYTE fsState;  //Initial state of the button         BYTE fsStyle;  //Style flags encode button behaviors         DWORD dwData;  //point to optional user data         int iString;   //pointer to optional caption string} TBBUTTON

Managing the insertion of buttons into a command bar is mostly a matter of loading the images that are displayed on the buttons and correctly initializing an array of these structures.

Loading The Button Images

There are two basic kinds of images you can use on buttons: the ones you create and the ones you borrow. Let's look at the way to use images of your own first.

// Bitmap//IDB_ONE_TWO             BITMAP  DISCARDABLE     "one_two.bmp"

This fragment of the menubar.rc file associates the constant IDB_ONE_TWO with a bitmap file named one_two.bmp. IDB_ONE_TWO contains two contiguous bitmap images, each 16x16. Here are two important things to know about bitmap button images. They must be exactly 16x16 pixels or they won't load properly. Unlike in other versions of Windows, you don't get any breaks when you try to load images that aren't correctly sized. Also, you should be very conservative about the use of color in these bitmaps. There are many black and white CE devices in the hands of users. Loading unsupported color bitmaps into a menu bar may well be catastrophic. Choosing bitmap colors from a 2 bit grayscale palette will always work, everywhere.

We make these images available to the command bar like this:

   //add bitmaps for buttons   CommandBar_AddBitmap(hwndCB, hInst, IDB_ONE_TWO, 2, 0, 0);

The parameters, in the order shown, are the handle to the command bar, the instance handle, the resource ID of the bitmap, the number of bitmap images aggregated in the bitmap file, and two reserved parameters which must be set to 0.

Adding bitmaps to a command bar makes each individual bitmap part of a list. You reference individual bitmaps by their zero based index in the list. If you call CommandBar_AddBitmap() more than once, these indexes are cumulative. By this I mean that if we followed the function call above with one like this:

   //add 2 more bitmaps for buttons   CommandBar_AddBitmap(hwndCB, hInst, IDB_THREE_FOUR, 2, 0, 0);

After the second call returned, we'd have four bitmaps in the command bar's list . The index of the 1st bitmap in IDB_ONE_TWO would be 0, and the index of the first bitmap in IDB_THREE_FOUR would be 2.

Its very important to make sure you add a number of bitmaps at least equal the number of buttons specified in CommandBar_AddButtons().

Page 2 of 3

This article was originally published on October 30, 2002

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date