This article will show you simple demo of creating and displaying popup menu using TrackPopupMenu api. You will learn the following items from this sample code.
Using Menu Creation Functions
You use menu creation function when you want to create or change a menu during run time. To create an empty menu bar, use the CreateMenu function; to create an empty menu, use the CreatePopupMenu function. To add items to a menu, use the AppendMenu and InsertMenu functions. When a menu contains more items than will fit in one column, the menu is truncated unless you force the line to break. You can cause a column break to occur at a specific item in a menu by assigning the MFT_MENUBREAK type flag to the item. Windows places that item and all subsequent items in a new column. You can also assign the MFT_MENUBARBREAK type flag to the item, which has the same effect as MFT_MENUBREAK, except that a vertical line appears between the new column and the old.
To display a shortcut menu, use the TrackPopupMenuEx function. Shortcut menus, also called floating pop-up menus or context menus, are typically displayed when the WM_CONTEXTMENU message is processed. The older TrackPopupMenu function is still supported, but new applications should use the TrackPopupMenuEx function.
If a menu is assigned to a window and that window is destroyed, Windows CE automatically destroys the menu, freeing the menu handle and the memory occupied by the menu. Windows CE does not automatically destroy a menu not assigned to a window. An application must destroy the unassigned menu by calling the DestroyMenu function.
Step-By-Step Example
- Create a standard exe project - Add one timer control and one commandbutton on the form1 - Add the following code in form1 |
Click here to copy the following block | Const MF_UNCHECKED = &H0& Const MF_CHECKED = &H8& Const MF_DISABLED = &H2& Const MF_GRAYED = &H1& Const MF_SEPARATOR = &H800& Const MF_STRING = &H0& Const MF_POPUP = &H10& Const MF_BYPOSITION = &H400& Const MF_BYCOMMAND = &H0& Const MF_HILITE = &H80
Const TPM_LEFTALIGN = &H0& Const TPM_RETURNCMD = &H100&
Private Type POINTAPI x As Long y As Long End Type
Private Declare Function ClientToScreen Lib "user32" ( _ ByVal hwnd As Long, _ lpPoint As POINTAPI) As Long
Private Declare Function CreatePopupMenu Lib "user32" () As Long
Private Declare Function TrackPopupMenu Lib "user32" ( _ ByVal hMenu As Long, _ ByVal wFlags As Long, _ ByVal x As Long, _ ByVal y As Long, _ ByVal nReserved As Long, _ ByVal hwnd As Long, _ ByVal lprc As Any) As Long
Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" ( _ ByVal hMenu As Long, _ ByVal wFlags As Long, _ ByVal wIDNewItem As Long, _ ByVal lpNewItem As Any) As Long
Private Declare Function DestroyMenu Lib "user32" ( _ ByVal hMenu As Long) As Long
Private Declare Function GetCursorPos Lib "user32" ( _ lpPoint As POINTAPI) As Long
Private Declare Function GetMenuState Lib "user32" ( _ ByVal hMenu As Long, _ ByVal wID As Long, _ ByVal wFlags As Long) As Long
Private Declare Function CheckMenuItem Lib "user32" ( _ ByVal hMenu As Long, _ ByVal wIDCheckItem As Long, _ ByVal wCheck As Long) As Long
Private Declare Function CheckMenuRadioItem Lib "user32" ( _ ByVal hMenu As Long, _ ByVal idFirst As Long, _ ByVal idLast As Long, _ ByVal idCheck As Long, _ ByVal uFlags As Long) As Long
Private Declare Function EnableMenuItem Lib "user32" ( _ ByVal hMenu As Long, _ ByVal wIDEnableItem As Long, _ ByVal wEnable As Long) As Long
Private Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA" ( _ ByVal hMenu As Long, _ ByVal wIDItem As Long, _ ByVal lpString As String, _ ByVal nMaxCount As Long, _ ByVal wFlag As Long) As Long
Private Declare Function HiliteMenuItem Lib "user32" ( _ ByVal hwnd As Long, _ ByVal hMenu As Long, _ ByVal wIDHiliteItem As Long, _ ByVal wHilite As Long) As Long
Private Declare Function EndMenu Lib "user32.dll" () As Long
Const ID_OPEN = 1001 Const ID_VIEW_ENABLE = 1002 Const ID_VIEW_100 = 1003 Const ID_VIEW_200 = 1004 Const ID_VIEW_FULL = 1005 Const ID_EXIT = 1006
Dim hMenu As Long, hSubMenu As Long Dim TimePassed As Integer
Private Sub Command1_Click() Dim pt As POINTAPI Me.ScaleMode = vbPixels
pt.x = Me.ScaleLeft pt.y = Me.ScaleHeight / 2 ClientToScreen Me.hwnd, pt
Timer1.Enabled = True ret = HiliteMenuItem(Form1.hwnd, hMenu, ID_OPEN, MF_BYCOMMAND Or MF_HILITE) Call TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, Me.hwnd, ByVal 0&) End Sub
Private Sub Form_Load() Timer1.Interval = 1000 Timer1.Enabled = False Command1.Caption = "Click to see Popup Timeout Demo (Timeout=5 sec)" hMenu = CreatePopupMenu() hSubMenu = CreatePopupMenu()
AppendMenu hMenu, MF_STRING, ByVal ID_OPEN, "Open" AppendMenu hMenu, MF_POPUP, hSubMenu, "Preview" AppendMenu hSubMenu, MF_STRING Or MF_CHECKED, ByVal ID_VIEW_ENABLE, "Enable Preview" AppendMenu hSubMenu, MF_STRING, ByVal ID_VIEW_100, "100%" AppendMenu hSubMenu, MF_STRING, ByVal ID_VIEW_200, "200%" AppendMenu hSubMenu, MF_STRING Or MF_DISABLED Or MF_GRAYED, ByVal ID_VIEW_FULL, "Full Screen Preview (Not supported)"
AppendMenu hMenu, MF_SEPARATOR, ByVal 0&, ByVal 0& AppendMenu hMenu, MF_CHECKED, ByVal ID_EXIT, "Exit"
End Sub
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single) Dim pt As POINTAPI Dim ret As Long, ClickedItem As Long
GetCursorPos pt
If Button = 2 Then Timer1.Enabled = True
ClickedItem = TrackPopupMenu(hMenu, TPM_RETURNCMD Or TPM_LEFTALIGN, pt.x, pt.y, 0, Me.hwnd, ByVal 0&)
Select Case ClickedItem Case ID_OPEN Case ID_VIEW_ENABLE If ToggleCheck(ClickedItem) = MF_CHECKED Then Call EnableOrDisable(ID_VIEW_100, True) Call EnableOrDisable(ID_VIEW_200, True) Else Call EnableOrDisable(ID_VIEW_100, False) Call EnableOrDisable(ID_VIEW_200, False) End If
Case ID_VIEW_100, ID_VIEW_200 ToggleRadio ClickedItem, ID_VIEW_100, ID_VIEW_FULL
Case ID_VIEW_FULL Case ID_EXIT Unload Me Exit Sub End Select MsgBox "You clicked on >> " & GetMenuCaption(ClickedItem) End If TimePassed = 0 Timer1.Enabled = False End Sub
Function ToggleCheck(MenuItemID As Long) As Long ret = GetMenuState(hMenu, MenuItemID, MF_BYCOMMAND) If (ret And MF_CHECKED) Then CheckMenuItem hMenu, MenuItemID, MF_BYCOMMAND Or MF_UNCHECKED ToggleCheck = MF_UNCHECKED Else CheckMenuItem hMenu, MenuItemID, MF_BYCOMMAND Or MF_CHECKED ToggleCheck = MF_CHECKED End If End Function
Function ToggleRadio(MenuItemID As Long, GroupStartAt As Integer, GroupEndAt As Integer) As Long Dim ret As Long ret = CheckMenuRadioItem(hMenu, GroupStartAt, GroupEndAt, MenuItemID, MF_BYCOMMAND) End Function
Function EnableOrDisable(MenuItemID As Long, IsEnabled As Boolean) As Long If IsEnabled = True Then EnableOrDisable = EnableMenuItem(hMenu, MenuItemID, MF_BYCOMMAND) Else EnableOrDisable = EnableMenuItem(hMenu, MenuItemID, MF_BYCOMMAND Or MF_DISABLED Or MF_GRAYED) End If End Function
Function GetMenuCaption(MenuItemID As Long) As String Dim strCaption As String strCaption = Space$(GetMenuString(hMenu, MenuItemID, vbNullString, 0, MF_BYCOMMAND) + 1)
If (Len(strCaption)) Then Call GetMenuString(hMenu, MenuItemID, strCaption, Len(strCaption), MF_BYCOMMAND) End If GetMenuCaption = strCaption End Function
Private Sub Form_Unload(Cancel As Integer) DestroyMenu hMenu End Sub
Private Sub Timer1_Timer() Me.Caption = TimePassed TimePassed = TimePassed + 1 Me.Caption = "Lookat the popup menu, it will disappear after [" & 5 - TimePassed & "] seconds" If TimePassed >= 5 Then Call EndMenu
TimePassed = 0 Timer1.Enabled = False Me.Caption = "APIDemo" End If End Sub |
|