February 25, 2021
Hot Topics:

Adapting Application Menus to the CE User Interface

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

In this tutorial, we introduce tools and techniques for porting a lavish desktop Windows user interface into a much more compact world - the one viewed through the three inch screen of a typical Pocket PC. CE's tiny screens demand a symbolic, metaphorical sort of communication with users, which is unlike the verbose styles encouraged by Win32 and MFC.

On the desktop, we use multiple layers of discursive menu captions and provide many ways to achieve a given result. By contrast, a good CE application is concise and focused, and this is immediately evident when we look at the appearance and function of a CE application's menu. Here are some useful porting guidelines for redesigning a typical Win32 application menu:

  • Never use a text caption if you can reasonably use a bitmap button instead
  • Minimize dropdown menu choices
  • Replace nested menus with dynamically constructed and destroyed command bars
  • Eliminate floating menus
  • Eliminate redundant user interface command mechanisms

Unsurprisingly, the CE menu API is an abbreviated subset of the Win32 menu constructs. CE meuns are based largely on the use of command bars and the controls they contain. In the MenuBar example, we'll show you how to program the full range of CE command bar controls. In this installment, you'll see how to:

  • Register and initialize the custom control library
  • Create the command bar
  • Dynamically modify a command bar based menu
  • Add Command Bar Buttons
  • Load button images
  • Use Standard Button Images
  • Evaluate code you are porting for inappropriate menu strategies

The MenuBar Example

Let's begin by examining the alternatives for menus that are determined to be inappropriate for direct porting from Win 32. Here is a listing of the files for the MenuBar Project, an example that demonstrates how to implement the functionality of complex or deeply nested menus using Command Bars.

MenuBar's WinMain()

A lot of the startup code for a Windows CE application is identical to that of Win32. Here's one notable exception, depicted in this code excerpt from WinMain():

    INITCOMMONCONTROLSEX icex; //this struct is used to init the                                //common controls dll    //init the structure     memset(&icex, 0x0, sizeof(INITCOMMONCONTROLSEX));    //windows ce requires explicit init of the common controls    icex.dwSize = sizeof (INITCOMMONCONTROLSEX);     //just load what we need     icex.dwICC = ICC_COOL_CLASSES;    InitCommonControlsEx (&icex);

You must explicitly register common controls classes before your program can use them. The InitCommonControlsEx() function takes the structure INITCOMMONCONTROLSEX as its only parameter. The value of icex.dwICC determines which group of controls is registered in this call. If you make more than one call to InitCommonControlsEx(), control registration is cumulative. You can OR the flags to register more than one group at time. ( e.g ICC_BAR_CLASSES | ICC_COOL_CLASSES )

Table 1 - Win CE supported control types flags

Control Type FlagsControls Registered
ICC_BAR_CLASSES Loads toolbar, status bar, trackbar and command bar classes.
ICC_COOL_CLASSES Loads rebar control class.
ICC_DATE_CLASSES Loads date and time-picker control class.
ICC_LISTVIEW_CLASSES Loads list view and header control classes.
ICC_PROGRESS_CLASS Loads progress bar control class.
ICC_TAB_CLASSES Loads tab control classes.
ICC_TREEVIEW_CLASSES Loads tree view control classes.
ICC_UPDOWN_CLASS Loads Up-Down control class.

Table 2- INITCOMMONCONTROLSEX Flags Not Supported By Windows CE

Non Portable Win32 Flags

One more thing, before we go on. Notice that I used memset() to initialize the structure contents to 0x0 and sizeof (INITCOMMONCONTROLSEX) to set the size of the structure in the icex.dwsize member. Even where the documentation says it isn't necessary, I have found that initializing and setting the size member of structures passed as parameters to be a very important defense against erratic behavior.

WinMain() calls MyRegisterClass(), and InitInstance(), both of which do routine and familiar tasks. There are a few differences to note that have to do with menu creation, however. Notice this line in MyRegisterClass(), where the members of the WNDCLASSstructure are being set.

//set the pointer to the menu resource name = 0    wc.lpszMenuName      = 0;

We set this window class parameter to 0 because we are going to take over the construction and display of the menu by creating a Command Bar control and positioning it where the menu would normally appear.

Also, note these lines at the end of InitInstance():

    //now show the window and make sure it gets painted    ShowWindow(hWnd, nCmdShow);    UpdateWindow(hWnd);   //if we have a command bar, show it now    if (hwndCB)      CommandBar_Show(hwndCB, TRUE);

The reason we have to explicitly tell the command bar to show itself is that Windows doesn't automatically handle it's update and display. In contrast to a Win32 style menu, a command bar has no "blueprint" in the resource file that tells Windows how to build it and where to put it. Also, it has to be painted onto the main window after that window becomes visible.

Page 1 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