Managing Shell Functionality

Wednesday Jul 23rd 2003 by Nancy Nicolaisen

The key to creating user friendly (and comprehensible) apps for Windows CE lies in managing the appearance of the shell. Here you will add an application's icon to the toolbar and see how to manage the MRU list.

In this example, we'll learn a couple of useful techniques for managing the appearance of the shell. First, you'll see how to add an application's icon to the toolbar, along with a tour of the related APIs and data structures. Next, you'll see how to manage the MRU list. Making the most of shell features is key to creating user friendly (and comprehensible) apps.

Adding Application Icons to the Taskbar

By adding an application icon to the HPC or HPC Pro taskbar, you provide the user a means of quickly starting an application any time she wants because the taskbar is always visible on these platforms.

Adding the icon is somewhat more involved than the shell operations you've seen so far, as you must initialize a NOTIFYICONDATA structure to do so. Here are the members of the structure and their meanings:

Table 1—NOTIFYICONDATA Structure Members and Their Meanings

Member Name Meaning
DWORD cbSize; Size of the structure in bytes
HWND hWnd; Handle to a window that receives notification messages
UINT uID; Application's ID for the taskbar icon
UINT uFlags; Any combination of:
NIF_ICON—The hIcon member is valid
NIF_MESSAGE—The uCallbackMessage member is valid
NIF_TIP—The szTip member is valid
UINT uCallbackMessage; Application defined message ID. System sends this message to the window specified by the hWnd member, in response to mouse click events over the icon's bounding rectangle
HICON hIcon; Handle to the icon to add, delete, or modify
WCHAR szTip[64]; Tool tip string

Here's the structure declaration:

//declaration of structure
    NOTIFYICONDATA  nidNotifyIcon;

It's a good practice to fully initialize any structure we pass as a function parameter, so always null initialize the structure's space with memset() before filling in the meaningful structure members.

        memset( &nidNotifyIcon, 0x0, sizeof(NOTIFYICONDATA));

Next, we initialize the structure members, setting the NIF_ICON flag to indicate that we are manipulating an icon. Notice that we use LoadImage() rather than LoadIcon() to retrieve the bitmap for the icon. LoadImage() loads a 16 x 16 bit image, which is suitable for display on the toolbar. LoadIcon() retrieves a large icon bitmap, which will cause the next operation to fail.

        nidNotifyIcon.cbSize = sizeof(NOTIFYICONDATA);
        nidNotifyIcon.hWnd   = GetParent( hWnd );
        nidNotifyIcon.uFlags = NIF_ICON;
        nidNotifyIcon.hIcon  =
                      (HICON) LoadImage(hInst, 
                              IMAGE_ICON, 16, 16, 0);
        nidNotifyIcon.uID   = 10;
Porting Tip: If you have difficulty getting your application to add icons to the toolbar, double check to make sure bitmaps are exactly 16 x 16.

To add the icon to the toolbar, call Shell_NotifyIcon():

        Shell_NotifyIcon( NIM_ADD, &nidNotifyIcon ))

The parameters, in the order shown, are a flag specifying the icon operation and the address of the initialized NOTIFYICONDATA structure. You may pass only one flag value in each call to the function. Here are the possible values and for the Shell_NotifyIcon() flag parameter:

Table 2—Shell_NotifyIcon() Flags and Their Meanings

Flag Name Meaning
NIM_ADD Add the icon
NIM_DELETE Delete the icon
NIM_DELETE Modify the icon

To delete an icon from the taskbar, use the same NOTIFYICONDATA structure initialization, but pass the NIM_DELETE flag:

        Shell_NotifyIcon( NIM_DELETE, &nidNotifyIcon );

Adding Documents to the Most Recently Used List

Add documents to the MRU by calling SHAddToRecentDocs().

  SHAddToRecentDocs( SHARD_PATH, TEXT("\\MyDocuments\\Hello.txt"));

The parameters, in the order shown, are the flag SHARD_PATH, which indicates that we are adding the document using its fully qualified, null terminated pathname; and the pathname as a literal string. CE has an upper limit of ten MRU documents, and if you try to add more the function will fail. You can't delete individual documents from the MRU list. To empty the entire list, pass a zero for the pathname parameter:

      //delete all files from the MRU list
        SHAddToRecentDocs( SHARD_PATH, 0 );

The SysMenuGadgets techniques you've seen in the last three installments work well on the larger CE platforms, but they aren't entirely in the spirit of the palmtop devices. If you choose to target the smallest devices, you'll want to pare your application's shell down to a much more concise set of behaviors.

Looking Ahead

In the next installment, we'll explore shell behavior in the palmtop platforms, creating the FullScreenDialog example program.

About the Author

Nancy Nicolaisen is a software engineer who has designed and implemented highly modular Windows CE products that include features such as full remote diagnostics, CE-side data compression, dynamically constructed user interface, automatic screen size detection, entry time data validation.

In addition to writing for, she has written several books including Making Win 32 Applications Mobile.

# # #

Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved