Using bitmaps in your menu (PB6, Jan 12,1999)

Back Up Next

Author: Eric Aling (14 feb 2000)
Accessed:
Download: Download menu.zip (8Kb) (menu.zip, 8kb)

In some cases, you may want to have bitmaps in your menu instead of text. Or you want to use other pictures for the 'checked' and 'unchecked' state of a menuitem. With the help of some windows APIs, you can easily do this. Here are the API declarations:

FUNCTION ulong LoadImageA(ulong hintance, string filename,uint utype,int x,int y,uint fload)  LIBRARY "USER32.DLL"
FUNCTION boolean SetMenuItemBitmaps(ulong hmenu,uint upos,uint flags,ulong handle_bm1,ulong handle_bm2)  LIBRARY "USER32.DLL"
FUNCTION int GetSystemMetrics(  int nIndex ) LIBRARY "USER32.DLL"
FUNCTION ulong GetMenuItemID(ulong hMenu,uint uItem) LIBRARY "USER32.DLL"
FUNCTION int GetSubMenu(ulong hMenu,int pos) LIBRARY "USER32.DLL"
FUNCTION ulong GetMenu(ulong hWindow) LIBRARY "USER32.DLL"
FUNCTION boolean ModifyMenu(ulong  hMnu, ulong uPosition, ulong uFlags, ulong uIDNewItem, long lpNewI) alias for ModifyMenuA LIBRARY "USER32.DLL"
FUNCTION boolean SetMenuDefault(ulong hmenu,uint upos,uint flags)  LIBRARY "USER32.DLL"

In our example we have a menu with two main items. Both have two sub menuitems. For our first menuitem, we want to use bitmaps instead of text. For the second, we want to change the checked/unchecked bitmaps. The following code can be placed in the open event of the window:

Long        ll_MainHandle
long        ll_SubMenuHandle
integer     li_MenuItemID
long        ll_X
long        ll_Y
long        ll_BitmapHandleA
long        ll_BitmapHandleB

// Win32 contants
Integer IMAGE_BITMAP    = 0
Integer LR_LOADFROMFILE = 16
Integer SM_CXMENUCHECK = 71
Integer SM_CYMENUCHECK    = 72
Integer MF_BITMAP            = 4
Integer MF_BYCOMMAND        = 0
Integer MF_BYPOSITION    = 1024

// Get a handle to the menu 
ll_MainHandle = GetMenu(Handle(this))

// Get a handle the the first menu item
ll_SubMenuHandle = GetSubMenu(ll_MainHandle,0)

// Load the images in their original sizes
ll_BitmapHandleA = LoadImageA(0,'ok.bmp',0,0,0,LR_LOADFROMFILE)
ll_BitmapHandleB = LoadImageA(0,'stop.bmp',0,0,0,LR_LOADFROMFILE)

There are two ways to get to the wanted menuitem, by using the relative position, or by using a direct handle to the menu item. Here we use the latter.

// get the menu id of the first submenu item and modify
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,0)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapHandleA)

li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,1)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapHandleB)

For the second menuitem, we want different bitmaps for the checked and unchecked state.

//Now get the handle of the second submenu..
ll_SubMenuHandle = GetSubMenu(ll_MainHandle,1)

// Get sizes for the bitmaps
ll_x = GetSystemMetrics(SM_CXMENUCHECK) 
ll_y = GetSystemMetrics(SM_CYMENUCHECK) 

// Load the images using the dimensions for the checked state
ll_BitmapHandleA = LoadImageA(0,'ok.bmp', IMAGE_BITMAP    ,ll_x,ll_y,LR_LOADFROMFILE)
ll_BitmapHandleB = LoadImageA(0,'stop.bmp',IMAGE_BITMAP    ,ll_x,ll_y,LR_LOADFROMFILE)
// change the menuitems
SetMenuItemBitmaps(ll_SubMenuHandle,0,MF_BYPOSITION,ll_BitmapHandleA,ll_BitmapHandleB)
SetMenuItemBitmaps(ll_SubMenuHandle,1,MF_BYPOSITION,ll_BitmapHandleB,ll_BitmapHandleA) 

Using the SetMenuDefault() function, you can make a menu item bold, which is done in the example.

Check out the example (PB6.5) and try the menu.

Back Up Next