Tip 188: Adding New Commands to the Control Menu
December 5, 1995
Abstract
This article explains how to add a new command to your Microsoft? Visual
Basic? Control menu.
Adding New Commands
When developing a Microsoft? Visual Basic? application, you may need to
customize the application's Control menu. For example, you may want to add
an Always On Top command to the Control menu that gives the user the
ability to have the application window always displayed on top of other
windows.
To add a new command to the Control menu, you need to perform several
steps. First, you need to use the Microsoft Windows? application
programming interface (API) GetSystemMenu function to retrieve the handle
of the Control menu. (Note that this tip applies to Windows 95 only.) The
following code is the Declare statement for this function:
Private Declare Function GetSystemMenu Lib "user32"
(ByVal hWnd As Long, ByVal bRevert As Long) As Long
The GetSystemMenu function requires two arguments. The hWnd argument is
the handle of the window that owns the Control menu. In this case, this
argument is the handle of your application's window. The bRevert argument
tells the GetSystemMenu function which of two actions you want to perform.
If the bRevert argument is set to True, the GetSystemMenu function will
reset the Control menu back to its original state (the Windows 95
default). Other applications, as well as your own, may have previously
modified the Control menu.
If the bRevert argument is set to False, the GetSystemMenu function will
return the handle of the current Control menu. This may or may not be the
original Control menu (the Windows 95 default).
In the example program below, you want to add a new command to the Control
menu. Therefore, you run the GetSystemMenu function with the bRevert
argument set to False.
Once you have the handle of the Control menu, you need to call the Windows
API AppendMenu function. The following code is the Declare statement for
this function:
Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA"
(ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem
As Long, ByVal lpNewItem As String) As Long
You can use the AppendMenu function to modify an existing menu's
structure. You can also use this function to modify the appearance of a
new menu command. In this case, however, you just want the command to
appear as normal (that is, a textual description).
The AppendMenu function requires the following four arguments:
hMenu A long value containing the handle of the menu you want to modify.
wFlags A long value that consists of one or more of the following flags
that define the appearance and behavior of the new menu command:
MF_BITMAP A bitmap is used as the command. The
lpNewItem argument must contain the bitmap's
handle.
MF_CHECKED A check mark is placed next to the command.
MF_DISABLED The command is disabled but not grayed.
MF_ENABLED The command is enabled.
MF_GRAYED The command is grayed.
MF_MENUBARBREAK The command is placed on a new line. If this
is a pop-up menu, the new command is placed
in a new column and a vertical line separates
the columns.
MF_MENUBREAK The command is placed on a new line. If this
is a pop-up menu, the new command is placed
in a new column.
MF_OWNERDRAW The command is an owner-drawn command.
MF_POPUP The command is a pop-up command. Selecting
this command displays a pop-up menu. The
pop-up menu's handle must be in the
wIDNewItem argument.
MF_SEPARATOR A horizontal dividing line is drawn in a
pop-up menu only.
MF_STRING The command is a string. The lpNewItem
argument must contain the string itself.
MF_UNCHECKED A check mark is not placed next to the
command. This is the default setting.
WIDNewItem A long value containing the new menu command's identifier. If
the wFlags argument is set to MF_POPUP, this argument contains
the pop-up menu's handle.
lpNewItem A string containing the content of the new menu command
according to the wFlags argument, as follows:
MF_BITMAP A bitmap handle.
MF_OWNERDRAW A 32-bit value specifying an application's
appearance and behavior instructions for the
owner-drawn command.
MF_STRING The command's text.
In the example program below, you use the AppendMenu function to add a
new command called "NewMenu" to the Control menu. However, in order to
perform some action when a user clicks NewMenu, you need to determine when
the application receives a Click event for that new menu command.
To do this, you need to use a third-party subclassing control such as
Message Blaster. The application's window will receive a WM_SYSCOMMAND
message each time the user clicks a command on the Control menu. The
subclassing control traps each WM_SYSCOMMAND received. If the command
corresponds to the new command (identified as SC_NEWMENU), you can perform
your own function. In all other cases, Windows 95 will process the menu
selection as normal.
Example Program
This program shows how to add a new command to your application's Control
menu.
1. Create a new project in Visual Basic. Form1 is created by default.
2. Add the following code to the General Declarations section of Form1
(note that each Declare statement must be typed as a single line of
code):
Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA"
(ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long,
ByVal lpNewItem As String) As Long
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal
bRevert As Long) As Long
Const WM_SYSCOMMAND = &H112
Const MF_STRING = &H0
Const SC_NEWMENU = 1
3. Add the following code to the Form_Load event for Form1:
Private Sub Form_Load()
Dim hw As Long
Dim hMenu As Long
hw = Me.hWnd
hMenu = GetSystemMenu(hw, False)
If AppendMenu(hMenu, MF_STRING, SC_NEWMENU, "&NewMenu") Then
MsgBlaster1.hWndTarget = hw
MsgBlaster1.AddMessage WM_SYSCOMMAND, POSTPROCESS
End If
End Sub
4. Add a Message Blaster control to Form1. MsgBlaster1 is created by
default.
5. Add the following code to the MsgBlaster1_Message event:
Private Sub MsgBlaster1_Message(ByVal hWnd As Long, ByVal Msg As Long, wParam As
Long, lParam As Long, nPassage As Integer, lReturnValue As Long)
If (wParam = SC_NEWMENU) Then
MsgBox "NewMenu menu command selected"
End If
End Sub
Run the example program by pressing F5. Form1 appears on the screen. Click
the form's Control menu. The new command, NewMenu, is shown on the Control
menu. When you click this new command, a message box appears indicating
that NewMenu was selected.
Return