How to Implement a Bitmap Within a Visual Basic Menu

ID: Q71281


The information in this article applies to:
  • Microsoft Visual Basic Standard and Professional Editions for Windows, version 3.0
  • Microsoft Visual Basic programming system for Windows, version 1.0


SUMMARY

No command provided by the Visual Basic language can add a bitmap to the menu system. However, you can call several Windows API functions to place a bitmap within the menu system of a Visual Basic program. You may also change the default check mark displayed.


MORE INFORMATION

There are several Windows API functions you can call that will display a bitmap instead of text in the menu system.

Below is a list of the required Windows API functions:

  • GetMenu% (hwnd%)
    
       hwnd%   -  Identifies the window whose menu is to be examined
       Returns:   Handle to the menu
     


  • GetSubMenu% (hMenu%, nPos%)
    
       hMenu%  - Identifies the menu
       nPos%   - Specifies the position (zero-based) in the
                 given menu of the pop-up menu
       Returns:  Handle to the given pop-up menu
     


  • GetMenuItemID% (hMenu%, nPos%)
    
       hMenu%  - Identifies the handle to the pop-up menu that
                 contains the item whose ID is being retrieved
       nPos%   - Specifies the position (zero-based) of the menu
                 whose ID is being retrieved
       Returns:  The item ID for the specified item in the pop-
                 up menu
     


  • ModifyMenu% (hMenu%, nPos%, wFlags%, wIDNewItem%, lpNewItem&)
    
        hMenu%  - Identifies the handle to the pop-up menu that
                  contains the item whose ID is being retrieved
        nPos%   - Specifies the menu item to be changed. The
                  interpretation of the nPos parameter depends
                  on the wFlags parameter.
        wFlags% - BF_BITMAP  =  &H4
        wIDNewItem% - Specifies the command ID of the modified menu item
        lpNewItem&  - 32-bit handle to the bitmap
        Returns:  TRUE (-1) if successful, FALSE (0) if unsuccessful
     


  • SetMenuItemBitmaps% (hMenu%, nPos%, Flags%, hBitmapUnchecked%, hBitmapChecked%)
    
        hMenu%  - Identifies menu to be changed
        nPos%   - Command ID of the menu item
        wFlags% - &H0
        hBitmapUnchecked% - Handle to "unchecked" bitmap.
        hBitmapChecked%)  - Handle to the "check" bitmap.
        Returns: TRUE (-1) if successful, FALSE (0) if unsuccessful.
     


There are two different ways to implement bitmaps within Visual Basic: the first method is to use static bitmaps; the other method is to use dynamic bitmaps.

A static bitmap is fixed and does not change during the execution of the program (such as when it is taken from an unchanging .BMP file). A dynamic bitmap changes during execution of your program. You may change dynamic bitmap attributes such as color, size, and text. The sample code below describes how to create both types of menus.

Define a menu system using the Menu Design window. Create a menu system such as the following:

    Caption      Control Name   Indented     Index
    --------------------------------------------------------
    BitMenu      TopMenu        No
    Sub Menu0    SubMenu        Once         0
    Sub Menu1    SubMenu        Once         1
    Sub Menu2    SubMenu        Once         2 

Create a picture control array with three bitmaps by creating three picture controls with the same control Name using the Properties list box.

    Control Name   Caption   Index     FontSize
    ----------------------------------------------------------------
    Picture1                  0           N/A
    Picture1                  1           N/A
    Picture1                  2           N/A
    Picture2                  N/A         N/A  'check BMP
    Picture3                  0           'set Picture3 FontSize all
                                           different
    Picture3                  1           9.75
    Picture3                  2           18
    Command1       Static
    Command2       Dynamic 

For each control index of Picture1, add a valid bitmap to the Picture property. Because these bitmaps will be displayed in the menu, you should use smaller bitmaps. Add a bitmap to the Picture2 Picture property that you want to be your check mark when you select a menu option.

Both types of bitmap implementations will need to have the following declarations in the declaration or global section of your code:

' Enter each Declare statement on one, single line:
Declare Function GetMenu% Lib "user" (ByVal hwnd%)
Declare Function GetSubMenu% Lib "user" (ByVal hMenu%, ByVal nPos%)
Declare Function GetMenuItemID% Lib "user" (ByVal hMenu%, ByVal nPos%)
Declare Function ModifyMenu% Lib "user" (ByVal hMenu%, ByVal nPosition%,
   ByVal wFlags%, ByVal wIDNewItem%, ByVal lpNewItem&)
Declare Function SetMenuItemBitmaps% Lib "user" (ByVal hMenu%,
   ByVal nPosition%, ByVal wFlags%, ByVal hBitmapUnchecked%,
   ByVal BitmapChecked%)
Const MF_BITMAP = &H4
Const CLR_MENUBAR = &H80000004 ' Defined for dynamic bitmaps only.
Const TRUE = -1, FALSE = 0
Const Number_of_Menu_Selections = 3 

The following Sub will also need to be defined to handle the actual redefinition of the "check" bitmap:

Sub SubMenu_Click (Index As Integer)
' Uncheck presently checked item, check new item, store
' index
   Static LastSelection%
   SubMenu(LastSelection%).Checked = FALSE
   SubMenu(Index).Checked = TRUE
   LastSelection% = Index
End Sub

Sub Command1_Click ()
  '* example to create a static bitmap menu
  hMenu% = GetMenu(hWnd)
  hSubMenu% = GetSubMenu(hMenu%, 0)
  For i% = 0 To Number_of_Menu_Selections - 1
    menuId% = GetMenuItemID(hSubMenu%, i%)
    x% = ModifyMenu(hMenu%, menuId%, MF_BITMAP, menuId%,
                    CLng(picture1(i%).Picture))
    x% = SetMenuItemBitmaps(hMenu%, menuId%, 0, 0,
                    CLng(picture2.Picture))
  Next i%
End Sub

'This code sample will change the actual menu bitmaps size,
'font size, color, and caption. Run the application and
'select the BitMenu and view the selections. Then click
'the form and revisit the BitMenu.
'---------------------------------------------------------

Sub Command2_Click ()
   '* Example to create a dynamic menu system
   hMenu% = GetMenu(hWnd)
   hSubMenu% = GetSubMenu(hMenu%, 0)
   For i% = 0 To Number_of_Menu_Selections - 1
   '* Place some text into the menu.

      SubMenu(i%).Caption = Picture3(i%).FontName +
                Str$(Picture3(i%).FontSize) + " Pnt"

   '* 1. Must be AutoRedraw for Image().
   '* 2. Set Backcolor of Picture control to that of the
   '*    current system Menu Bar color, so Dynamic bitmaps
   '*    will appear as normal menu items when menu bar
   '*    color is changed via the control panel
   '* 3. See the bitmaps on screen, this could all be done
   '*    at design time.

     Picture3(i%).AutoRedraw = TRUE
     Picture3(i%).BackColor = CLR_MENUBAR
   '* You can uncomment this
   '* Picture3(i%).Visible = FALSE

   '* Set the width and height of the Picture controls
   '* based on their corresponding Menu items caption,
   '* and the Picture controls Font and FontSize.
   '* DoEvents() is necessary to make new dimension
   '* values to take affect prior to exiting this Sub.

    Picture3(i%).Width = Picture3(i%).TextWidth(SubMenu(i%).Caption)
    Picture3(i%).Height = Picture3(i%).TextHeight(SubMenu(i%).Caption)
    Picture3(i%).Print SubMenu(i%).Caption

   '* - Set picture controls backgroup picture (Bitmap) to
   '*   its Image.
     Picture3(i%).Picture = Picture3(i%).Image
     x% = DoEvents()
   Next i%

    '* Get handle to forms menu.
   hMenu% = GetMenu(Form1.hWnd)

   '* Get handle to the specific menu in top level menu.
   hSubMenu% = GetSubMenu(hMenu%, 0)

   For i% = 0 To Number_of_Menu_Selections - 1

   '* Get ID of sub menu
     menuId% = GetMenuItemID(hSubMenu%, i%)

   '* Replace menu text w/bitmap from corresponding picture
   '* control
     x% = ModifyMenu(hMenu%, menuId%, MF_BITMAP, menuId%,
              CLng(Picture3(i%).Picture))  'append this to previous line

   '* Replace bitmap for menu check mark with custom check
   '* bitmap
     x% = SetMenuItemBitmaps(hMenu%, menuId%, 0, 0, CLng(picture2.Picture))
   Next i%
End Sub 


REFERENCES

"Programming Windows: the Microsoft Guide to Writing Applications for Windows 3," Charles Petzold, Microsoft Press, 1990

"Microsoft Windows Software Development Kit: Reference Volume 1," version 3.0

WINSDK.HLP file shipped with Microsoft Windows 3.0 SDK

Additional query words: 2.00 3.00

Keywords :
Version :
Platform :
Issue type :


Last Reviewed: May 25, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.