WM_COMMAND Message

Platforms

Description & Usage

A window receives the WM_COMMAND message when the user selects an item in one of the window's menus. This includes any popup menus which the window owns. Upon receiving this message, the window should perform whatever task or operation the menu item was meant to perform.

Return Value

The WM_COMMAND message should always return 0.

Visual Basic-Specific Issues

None.

Parameters

wParam
The high-order word is the notification code of the message: 0 means the message was generated by selecting a menu item, whereas 1 means the message was generated by a keyboard accelerator. The low-order word contains the identifier of the menu item that the user selected. The LOWORD and HIWORD macros can extract these two values.
lParam
A handle to the control that sent this message, if any. If no control sent the message, this is 0.

Constant Definitions

Const WM_COMMAND = &H111

Example

' This code is licensed according to the terms and conditions listed here.

' Declarations and such needed for the example:
' (Copy them to the (declarations) section of a module.)
Public Declare Function CreatePopupMenu Lib "user32.dll" () As Long
Public Declare Function DestroyMenu Lib "user32.dll" (ByVal hMenu As Long) As Long
Public Type MENUITEMINFO
	cbSize As Long
	fMask As Long
	fType As Long
	fState As Long
	wID As Long
	hSubMenu As Long
	hbmpChecked As Long
	hbmpUnchecked As Long
	dwItemData As Long
	dwTypeData As String
	cch As Long
End Type
Public Const MIIM_STATE = &H1
Public Const MIIM_ID = &H2
Public Const MIIM_TYPE = &H10
Public Const MFT_SEPARATOR = &H800
Public Const MFT_STRING = &H0
Public Const MFS_DEFAULT = &H1000
Public Const MFS_ENABLED = &H0
Public Declare Function InsertMenuItem Lib "user32.dll" Alias "InsertMenuItemA" (ByVal _
	hMenu As Long, ByVal uItem As Long, ByVal fByPosition As Long, lpmii As _
	MENUITEMINFO) As Long
Public Type RECT
	left As Long
	top As Long
	right As Long
	bottom As Long
End Type
Public Type TPMPARAMS
	cbSize As Long
	rcExclude As RECT
End Type
Public Declare Function TrackPopupMenuEx Lib "user32.dll" (ByVal hMenu As Long, ByVal _
	fuFlags As Long, ByVal x As Long, ByVal y As Long, ByVal hWnd As Long, lptpm As _
	TPMPARAMS) As Long
Public Const TPM_LEFTALIGN = &H0
Public Const TPM_TOPALIGN = &H0
Public Const TPM_LEFTBUTTON = &H0
Public Type POINT_TYPE
	x As Long
	y As Long
End Type
Public Declare Function GetCursorPos Lib "user32.dll" (lpPoint As POINT_TYPE) As Long
Public Declare Function SetRectEmpty Lib "user32.dll" (lpRect As RECT) As Long
Public Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd _
	As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC = -4
Public Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal _
	lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam _
	As Long, ByVal lParam As Long) As Long
Public Const WM_COMMAND = &H111

' When the user clicks button Command1, have a very simple popup menu appear.  The
' menu only has two options, divided by a separator bar.  The menu is created when
' needed and is destroyed after its use.

' *** Place the following code inside a module. ***

' The following application-defined constants are used to name the menu item
' identifiers used by this example.  They are not actually part of the API; instead, they are
' used just to eliminate "magic numbers."
Public Const ID_ABOUT = 101
Public Const ID_SEPARATOR = 102
Public Const ID_EXIT = 103

' This is a pointer to Form1's previous window procedure.
Public pOldProc As Long

' This is actually the "declaration" of the LOWORD API macro.
Public Function LOWORD (ByVal dwValue As Long) As Integer
	LOWORD = dwValue Mod &H10000
End Function

' The following window procedure for window Form1 handles its messages.
' Specifically, it processes the WM_COMMAND message for the popup menu.
Public Function WindowProc (ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam _
		As Long, ByVal lParam As Long) As Long
	Dim retval As Long  ' return value
	
	Select Case uMsg
	Case WM_COMMAND
		' Do whatever the items on the popup menu requested.
		Select Case LOWORD(wParam)
		Case ID_ABOUT
			' Use the VB MsgBox function to display a short message in a dialog
			' box.  Using the API isn't necessary.
			retval = MsgBox("This example demonstrates how to use the API to " & _
				"display a pop-up menu.", vbOkOnly Or vbInformation, _
				"Windows API Guide")
		Case ID_EXIT
			' End this program by closing and unloading Form1.
			Unload Form1
		Case Else
			' Have the previous window procedure handle other items.
			retval = CallWindowProc(pOldProc, hWnd, uMsg, wParam, lParam)
		End Select
		WindowProc = 0
	Case Else
		' Pass this to the previous window procedure.
		WindowProc = CallWindowProc(pOldProc, hWnd, uMsg, wParam, lParam)
	End Select
End Function

' *** Place the following code inside Form1. ***

Private Sub Command1_Click()
	Dim hPopupMenu As Long    ' handle to the popup menu to display
	Dim mii As MENUITEMINFO   ' describes menu items to add
	Dim tpm As TPMPARAMS      ' identifies the exclusion rectangle
	Dim curpos As POINT_TYPE  ' holds the current mouse coordinates
	Dim menusel As Long       ' ID of what the user selected in the popup menu
	Dim retval As Long        ' generic return value
	
	' Create the popup menu that will be displayed.
	hPopupMenu = CreatePopupMenu()
	' Add the menu's first item: "About This Problem..."
	With mii
		' The size of this structure.
		.cbSize = Len(mii)
		' Which elements of the structure to use.
		.fMask = MIIM_STATE Or MIIM_ID Or MIIM_TYPE
		' The type of item: a string.
		.fType = MFT_STRING
		' This item is currently enabled and is the default item.
		.fState = MFS_ENABLED Or MFS_DEFAULT
		' Assign this item an item identifier.
		.wID = ID_ABOUT
		' Display the following text for the item.
		.dwTypeData = "&About This Example..."
		.cch = Len(.dwTypeData)
	End With
	retval = InsertMenuItem(hPopupMenu, 0, 1, mii)
	' Add the second item: a separator bar.
	With mii
		.fType = MFT_SEPARATOR
		.fState = MFS_ENABLED
		.wID = ID_SEPARATOR
	End With
	retval = InsertMenuItem(hPopupMenu, 1, 1, mii)
	' Add the final item: "Exit".
	With mii
		.fType= MFT_STRING
		.wID = ID_EXIT
		.dwTypeData = "E&xit"
		.cch = Len(.dwTypeData)
	End With
	retval = InsertMenuItem(hPopupMenu, 2, 1, mii)
	
	' Determine where the mouse cursor currently is, in order to have
	' the popup menu appear at that point.
	retval = GetCursorPos(curpos)
	
	' Make the exclusion rectangle empty because there's no need for it here.
	With tpm
		' Size of the structure.
		.cbSize = Len(tpm)
		' Make the exclusion rectangle empty.
		retval = SetRectEmpty(.rcExclude)
	End With
	
	' Display the popup menu at the mouse cursor.  The window procedure
	' defined in the module will process the selected item automatically.
	menusel = TrackPopupMenuEx(hPopupMenu, TPM_TOPALIGN Or TPM_LEFTALIGN Or _
		TPM_LEFTBUTTON, curpos.x, curpos.y, Form1.hWnd, tpm)
	
	' Destroy the popup menu now.
	retval = DestroyMenu(hPopupMenu)
End Sub

' When Form1 loads, tell it to use the custom window procedure.
Private Sub Form_Load()
	' Set the custom window procedure to process Form1's messages.
	pOldProc = SetWindowLong(Form1.hWnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub

' Before unloading, remove the custom window procedure.
Private Sub Form_Unload(Cancel As Integer)
	Dim retval As Long  ' return value
	
	' Replace the previous window procedure to prevent crashing.
	retval = SetWindowLong(Form1.hWnd, GWL_WNDPROC, pOldProc)
End Sub

See Also

WM_SYSCOMMAND

Category

Menus

Back to the Message list.
Back to the Reference section.


Last Modified: June 4, 2000
This page is copyright © 2000 Paul Kuliniewicz. Copyright Information Revised October 29, 2000
Go back to the Windows API Guide home page.
E-mail: vbapi@vbapi.com Send Encrypted E-Mail
This page is at http://www.vbapi.com/ref/w/wm_command.html