Solved

Icons/Bitmaps on popup menu Items

Posted on 1997-05-07
7
619 Views
Last Modified: 2013-12-02
How do I add icons/bitmaps to popup menu items.
I want it to look like the popup menu you get when you
press the START button.
please provide two options:
    Large icons on menuitems and large bitmap on side
    small icons with bitmaps/icons on each menu item

0
Comment
Question by:monkeyboy050797
7 Comments
 

Author Comment

by:monkeyboy050797
ID: 1426065
Edited text of question
0
 
LVL 7

Expert Comment

by:tward
ID: 1426066
Knowledge Base

How to Implement a Bitmap Within a Visual Basic Menu

Article ID: Q71281
Creation Date: 11-APR-1991
Revision Date: 21-JUN-1995

The information in this article applies to:
•Standard and Professional Editions of Microsoft Visual Basic for Windows, versions 2.0 and 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
------------------------------------------------------------------------
THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

©1996 Microsoft Corporation

Additional reference words: 1.00 2.00 3.00
KBCategory: kbgraphic kbprg kbcode
KBSubcategory: APrgGrap
0
 

Author Comment

by:monkeyboy050797
ID: 1426067
This does not answer my question!

Let me try again.

If I use the solution above (which I've already found in MSKB)
the modifymenu() would just replace the caption string with a bitmap. This is not what I want to have happen. I am writing a program for win95/nt. just look at that happens when you press the START button, THAT IS WHAT I NEED TO REPLICATE.


0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 1

Expert Comment

by:bitz
ID: 1426068
This is a solution that isn't easy.  I suggest instead of using the Pop-up menus, us a custom form.  Trim the Title bar off by setting Caption = "" and Controlbox = False, MinButton = false, Maxbutton = false.  Then, use the image control and labels and such to make it look like a Menu.  Then set it's Coordinates at run time and use the .show method.
0
 

Author Comment

by:monkeyboy050797
ID: 1426069
Bitz,

Thank you very much, but I am sorry but your suggestion is not acceptable.

I do not mind a dificult solution.

THE END WILL JUSTIFY THE MEANS.

If you have the answer please help me.
I see I just got 15 more points. I will add that to the pot.


0
 

Author Comment

by:monkeyboy050797
ID: 1426070
Adjusted points to 225
0
 
LVL 5

Accepted Solution

by:
y96andha earned 220 total points
ID: 1426071
The popup menu on the start button is an owner-draw popup menu. An owner-draw popup menu cannot be created in Visual Basic unless you have a OCX or VBX that allows you to respond to specific windows messages. The message that you need be able to respond to is WM_MEASUREITEM and WM_DRAWITEM.

There is no built-in support for having both an icon and some text for a menu item. What you need to do is to tell Windows that it shouldn't draw the menuitems itself, instead it should send a message to your application (that's the WM_DRAWITEM) whenever a menu item must be drawn on screen. When your application receives that message, it receives the following structure with information on what should be done. You would then have to draw the text and the bitmap/icon using API calls.

typedef struct tagDRAWITEMSTRUCT {  // dis
    UINT  CtlType;
    UINT  CtlID;
    UINT  itemID;
    UINT  itemAction;
    UINT  itemState;
    HWND  hwndItem;
    HDC   hDC;
    RECT  rcItem;
    DWORD itemData;
} DRAWITEMSTRUCT;
 
 
The DRAWITEMSTRUCT structure provides information the owner window must have to determine how to paint an owner-drawn control or menu item. The owner window of the owner-drawn control or menu item receives a pointer to this structure as the lParam parameter of the WM_DRAWITEM message.

Members

CtlType
Specifies the control type. This member can be one of the following values:
 
Value      Meaning

ODT_BUTTON      Owner-drawn button
ODT_COMBOBOX      Owner-drawn combo box
ODT_LISTBOX      Owner-drawn list box
ODT_LISTVIEW      List view control
ODT_MENU      Owner-drawn menu item
ODT_STATIC      Owner-drawn static control
ODT_TAB      Tab control

CtlID
Specifies the identifier of the combo box, list box, button, or static control. This member is not used for a menu item.

itemID
Specifies the menu item identifier for a menu item or the index of the item in a list box or combo box. For an empty list box or combo box, this member can be -1. This allows the application to draw only the focus rectangle at the coordinates specified by the rcItem member even though there are no items in the control. This indicates to the user whether the list box or combo box has the focus. How the bits are set in the itemAction member determines whether the rectangle is to be drawn as though the list box or combo box has the focus.

itemAction
Specifies the drawing action required. This member can be one or more of the following values:
 
Value      Meaning

ODA_DRAWENTIRE      The entire control needs to be drawn.
ODA_FOCUS      The control has lost or gained the keyboard focus. The itemState member should be checked to determine whether the control has the focus.
ODA_SELECT      The selection status has changed. The itemState member should be checked to determine the new selection state.

itemState
Specifies the visual state of the item after the current drawing action takes place. This member can be a combination of the following values:
 
Value      Meaning

ODS_CHECKED      The menu item is to be checked. This bit is used only in a menu.
ODS_COMBOBOXEDIT      The drawing takes place in the selection field (edit control) of an ownerdrawn combo box.
ODS_DEFAULT      The item is the default item.
ODS_DISABLED      The item is to be drawn as disabled.
ODS_FOCUS      The item has the keyboard focus.
ODS_GRAYED      The item is to be grayed. This bit is used only in a menu.
ODS_SELECTED      The menu item's status is selected.

hwndItem
Identifies the control for combo boxes, list boxes, buttons, and static controls. For menus, this member identifies the menu containing the item.

hDC
Identifies a device context; this device context must be used when performing drawing operations on the control.

rcItem
Specifies a rectangle that defines the boundaries of the control to be drawn. This rectangle is in the device context specified by the hDC member. Windows automatically clips anything the owner window draws in the device context for combo boxes, list boxes, and buttons, but does not clip menu items. When drawing menu items, the owner window must not draw outside the boundaries of the rectangle defined by the rcItem member.

itemData
Specifies the application-defined 32-bit value associated with the menu item. For a control, this parameter specifies the value last assigned to the list box or combo box by the LB_SETITEMDATA or CB_SETITEMDATA message. If the list box or combo box has the LBS_HASSTRINGS or CBS_HASSTRINGS style, this value is initially zero. Otherwise, this value is initially the value that was passed to the list box or combo box in the lParam parameter of one of the following messages:
CB_ADDSTRING
CB_INSERTSTRING
LB_ADDSTRING
LB_INSERTSTRING
If ctlType is ODT_BUTTON or ODT_STATIC, itemData is zero.

0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now