Putting the Menu Together

GRAFMENU's WinMain function uses the StretchBitmap and GetBitmapFont functions when constructing the menu. GRAFMENU has two menus already defined in the resource script. These will become popups for the File and Edit options.

GRAFMENU begins by obtaining a handle to an empty menu:

hMenu = CreateMenu () ;

The popup menu for File (containing the four options New, Open, Save, and Save As) is loaded from the resource script:

hMenuPopup = LoadMenu (hInstance, "MenuFile") ;

The bitmap containing the word ”FILE“ is also loaded from the resource script and stretched using StretchBitmap:

hBitmapFile = StretchBitmap (LoadBitmap (hInstance, "BitmapFile")) ;

The bitmap handle and popup menu handle become parameters in the ChangeMenu call:

AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hMenuPopup, (LPSTR) (LONG) hBitmapFile) ;

The same procedure is followed for the Edit menu:

hMenuPopup = LoadMenu (hInstance, "MenuEdit") ;

hBitmapEdit = StretchBitmap (LoadBitmap (hInstance, "BitmapEdit")) ;

AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hMenuPopup, (LPSTR) (LONG) hBitmapEdit) ;

The popup menu for the three fonts is constructed from calls to the GetBitmapFont function:

hMenuPopup = CreateMenu () ;

for (i = 0 ; i < 3 ; i++)

{

hBitmapPopFont [i] = GetBitmapFont (i) ;

AppendMenu (hMenuPopup, MF_BITMAP,IDM_COUR + i,

(LPSTR) (LONG) hMenuPopupFont [i]) ;

The popup is then added to the menu:

hBitmapFont = StretchBitmap (LoadBitmap (hInstance, "BitmapFont")) ;

AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hBitmapFont,

(LONG) (LPSTR) hBitmapFont) ;

The window menu is complete. Now you can include hMenu in the CreateWindow call:

hwnd = CreateWindow (szAppName, "Bitmap Menu Demonstration",

WS_OVERLAPPED,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, hMenu, hInstance, NULL) ;

After hwnd is available, GRAFMENU can alter the system menu. GRAFMENU first obtains a handle to it:

hMenu = GetSystemMenu (hwnd, FALSE) ;

This loads the ”Help“ bitmap and stretches it to an appropriate size:

hBitmapHelp = StretchBitmap (LoadBitmap (hInstance, "BitmapHelp")) ;

This adds a separator bar and the stretched bitmap to the system menu:

AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;

AppendMenu (hMenu, MF_BITMAP, IDM_HELP, (LPSTR) (LONG) hBitmapHelp) ;

Remember that bitmaps are GDI objects and must be explicitly deleted before your program terminates. You accomplish this after GRAFMENU exits from its message loop:

DeleteObject (hBitmapHelp) ;

DeleteObject (hBitmapEdit) ;

DeleteObject (hBitmapFile) ;

DeleteObject (hBitmapFont) ;

for (i = 0 ; i < 3 ; i++)

DeleteObject (hBitmapPopFont [i]) ;

I'll conclude this section with a couple of miscellaneous notes:

In a top-level menu, Windows adjusts the menu bar height to accommodate the tallest bitmap. Other bitmaps (or character strings) are aligned at the top of the menu bar. The size of the menu bar obtained from:

GetSystemMetrics (SM_CYMENU)

is no longer valid after you put bitmaps in a top-level window.

As you can see from playing with GRAFMENU, you can use check marks with bitmapped menu items in popups, but the check mark is of normal size. If that bothers you, you can create a customized check mark and use SetMenuItemBitmaps.

Another approach to using non-text (or text in a font other than the system font) on a menu is the ”owner-draw“ item. The Windows Guide to Programming discusses this approach.