User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

    Using Popup Menus in Visual Basic 6



    Popup menus are a useful metaphor. Popup menus are sometimes referred to as speed menus, right-click menus, or context menus. Popup menus are generally invoked by right-clicking the mouse button. Based on the hover location of the mouse, most applications will display a specific menu. The users-focus, or context, determines which menu is shown hence the name context menu.

    Implementing popup menus in VB6 is not necessarily intuitive but it isn't hard either. There is no menu or popup menu item in VB6 that you can drag from the Toolbox onto a form—thankfully this deficit has been rectified in VB.NET. This article will demonstrate how to create menus using the Menu Editor in VB6 and how to use those menus as popups. Demonstrating the context aspect I will borrow from an October 2001 article and demonstrate how to display the popup menu when a user right-clicks over an icon in the System Tray.

    Creating Menus with the Menu Editor

    Menus are added to Windows applications using the Tool, Menu Editor (Ctrl+E shortcut) in VB6. The Menu Editor allows you to create menus by typing the Caption and Name of each menu item and initialize menu items by setting properties for each menu item in the Menu Editor dialog box (see figure 1).

    Referring to figure one, the menu item that has the focus is the item selected in the list in the bottom half of the Menu Editor dialog. Menu items at the extreme left edge are top-level menu items and each level of indentation represents an additional level of nesting.


    Figure 1: The Menu Editor is used to design menus in VB6.

    From figure 1 we can see that a top-level menu named Popup is selected. The caption that will be displayed is the value in the Caption field, in the example this is "Popup". If we were to add an ampersand to the value of the Caption property immediately before the first P in popup—&Popup—then the first P in popup would be the hotkey for the Popup menu. When the menu is displayed it would appear as follows: Popup. Further if the hotkey P were used then pressing Alt+P when the application containing the popup menu were run would cause the Popup menu to be displayed.

    Other properties for the Menu Editor are pretty intuitive. You can use the VB6 help if you are unfamiliar with other Menu Editor properties.

    If we were to check the Visible property for the menu shown then the Popup menu would appear as shown in figure 2 (when displayed).


    Figure 2: The Popup menu described in the Menu Editor in figure 1 shown in design mode dropped down.

    Menus that will be used as popup menus should not be displayed in the main menu bar when the application is running. Hence those menus that you will be using as popups should be made invisible by unchecking the Visible property in the Menu Editor as shown in figure 1.

    As a reminder, you write code for a menu item by clicking on menu items in design mode. Thus you will need to make the menu visible to create the click event handler for the menu, or you can create the click event handler in the code editor in the usual way.

    Displaying Menus as Popups

    To display a menu as a popup call the PopupMenu method for a Form or MDIForm. For example, to display our Popup menu you can write the following code:

    Call Me.PopupMenu(MenuPopup)
    

    (Recall from figure 1 that we named the Popup menu MenuPopup. Prefixing object names with the object type is a convention I use.)

    When you call the PopupMenu method the top-level menu item is not displayed. Applied to our example, if you displayed the MenuPopup object then only the MenuVisible item would be displayed.

    There are other optional arguments that you can pass to the PopupMenu method. You can pass a flags argument that describes the alignment of the popup menu and values that describe special responses to mouse-clicks. The X and Y arguments allow you to precisely position the popup menu, and the last argument allows you to specify a menu that will be displayed using a Bold font style. The general syntax for the PopupMenu method follows.

    object.PopupMenu menuname, flags, x, y, boldcommand
    

    Refer to the PopupMethod Menu help information in the Visual Basic Reference. The information for this article was taken from the April 2001 MSDN documentation.

    Adding a Popup to a System Tray Icon

    Listing 1 provides a slightly revised re-listing of the System Tray example from "Using the System Tray", October 2001. If you want information about the code in general read the referenced October 2001 article on www.codeguru.com in VB Tech Notes. For our purposes we will go over the revision of the System Tray Demo that employs a popup menu.

    Listing 1: Demonstrates a System Tray example from "Using the System Tray", October 2001, that has been revised to employ a popup menu.

    1:  ' FormMain.frm - Add an icon to the system tray.
    2:  ' Copyright (c) 2002. All Rights Reserved.
    3:  ' By Paul Kimmel. pkimmel@softconcepts.com
    4:  
    5:  Option Explicit
    6:  
    7:  ' Type passed to Shell_NotifyIcon
    8:  Private Type NotifyIconData
    9:    Size As Long
    10:   Handle As Long
    11:   ID As Long
    12:   Flags As Long
    13:   CallBackMessage As Long
    14:   Icon As Long
    15:   Tip As String * 64
    16: End Type
    17: 
    18: ' Constants for managing System Tray tasks, found in shellapi.h
    19: Private Const AddIcon = &H0
    20: Private Const ModifyIcon = &H1
    21: Private Const DeleteIcon = &H2
    22: 
    23: Private Const WM_MOUSEMOVE = &H200
    24: Private Const WM_LBUTTONDBLCLK = &H203
    25: Private Const WM_LBUTTONDOWN = &H201
    26: Private Const WM_LBUTTONUP = &H202
    27: 
    28: Private Const WM_RBUTTONDBLCLK = &H206
    29: Private Const WM_RBUTTONDOWN = &H204
    30: Private Const WM_RBUTTONUP = &H205
    31: 
    32: Private Const MessageFlag = &H1
    33: Private Const IconFlag = &H2
    34: Private Const TipFlag = &H4
    35:       
    36: Private Declare Function Shell_NotifyIcon Lib "shell32" _ 
        Alias "Shell_NotifyIconA" (ByVal Message As Long, _
        Data As NotifyIconData) As Boolean
    37: 
    38: Private Data As NotifyIconData
    39: 
    40: 
    41: Private Sub Form_Load()
    42:   AddIconToTray
    43:   Visible = False
    44: End Sub
    45: 
    46: Private Sub Form_Terminate()
    47:   DeleteIconFromTray
    48: End Sub
    49: 
    50: Private Sub AddIconToTray()
    51: 
    52:   Data.Size = Len(Data)
    53:   Data.Handle = hWnd
    54:   Data.ID = vbNull
    55:   Data.Flags = IconFlag Or TipFlag Or MessageFlag
    56:   Data.CallBackMessage = WM_MOUSEMOVE
    57:   Data.Icon = Icon
    58:   Data.Tip = "System Tray Demo - codeguru.com" & vbNullChar
    59:   Call Shell_NotifyIcon(AddIcon, Data)
    60: 
    61: End Sub
    62: 
    63: Private Sub DeleteIconFromTray()
    64:   Call Shell_NotifyIcon(DeleteIcon, Data)
    65: End Sub
    66: 
    67: Private Function GetWindowState(ByVal Value As Boolean) As Integer
    68:     
    69:   ' Abs(False) = 0 = vbNormal, Abs(True) = 1 = vbMinimized
    70:   GetWindowState = Abs(Value)
    71:   
    72:   ' Or
    73:   'If (Value = False) Then
    74:   '  GetWindowState = vbNormal
    75:   'Else
    76:   '  GetWindowState = vbMinimized
    77:   'End If
    78:   
    79:   
    80: End Function
    81: 
    82: Private Sub Form_MouseMove(Button As Integer, _
    83:   Shift As Integer, X As Single, Y As Single)
    84:   
    85:   Dim Message As Long
    86:   Message = X / Screen.TwipsPerPixelX
    87:   
    88:   Select Case Message
    89:     Case WM_LBUTTONDBLCLK
    90:       ToggleState
    91:     Case WM_RBUTTONDOWN
    92:       Call Me.PopupMenu(MenuPopup, , , , MenuVisible)
    93:   End Select
    94: 
    95:   
    96: End Sub
    97: 
    98: Private Sub ToggleState()
    99:   Visible = Not Visible
    100:   WindowState = GetWindowState(Not Visible)
    101: End Sub
    102: 
    103: Private Sub MenuVisible_Click()
    104:   ToggleState
    105: End Sub
    

    The menu described by figure 1 was added to the FormMain.frm from the SystemTrayDemo.vbp project. Line 91 from listing 1 adds the right mouse button constant to the Select Case statement. When the right mouse button is down over the icon in the System Tray the PopupMenu method is called displaying the MenuPopup menu.

    As a side note the code in ToggleState was refactored using Extract Method. The result is that the popup menu's click event handler can use the behavior to show or hide the form, and the left button double click can use this method too.

    Summary

    Visual Basic 6 uses the Menu Editor to create and describe menus. The Menu Editor dialog is used to describe your main menu as well as menus that will be used as popup, or context, menus.

    If you are going to use a menu as a popup menu then set its Visible property to false. When you are ready to show the menu call the Form.PopupMenu or MDIForm.PopupMenu method. The end result is a feature rich application that shows menus more appropriately displayed in a limited context.

    Finally I'd like to mention that this article demonstrates how several techniques can be layered into an application to create a better final product. In this article the Refactoring Extract Method was employed to reuse code that toggled the visible state of the form. Additionally we were able to combine the popup menu with the system tray example to create a context menu for the system tray icon, yielding a handsome fit and finish.

    About the Author

    Paul Kimmel is a freelance writer for Developer.com and CodeGuru.com. Look for cool Visual Basic .Net topics in his upcoming book Visual Basic .Net Unleashed.

    Paul founded Software Conceptions, Inc. in 1990. Contact Paul Kimmel at pkimmel@softconcepts.com for help building VB.NET applications or migrating VB6 applications to .NET.


    IT Offers


    Top Authors