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.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read