Skip to main content

Past Blast

Featured Products

Stay in touch using the DEVBUSS RSS feeds.
 

News

eVB Popup Menu /Tap and Hold Menu using Windows CE API calls.

Written by Derek Mitchell  [author's bio]  [read 44665 times]
Edited by Derek

Page 1  Page 2 

Hello, and welcome to Popup Menus in eVB 101! This is sure to be an exciting lesson, so sharpen your pencils, get comfortable, and ready to go. Oh by the way, if you need to contact me, I can be reached at okseriously.com.

Unfortunately, due to one of the many many significant oversights by Microsoft in the development of eMbedded Visual Basic, popup menus are not natively supported, nor is there a Tap 'n' Hold event. That's ok, though because we can simulate the event, create the menu, and all is good. The first thing to do is build the menu to display. I'm going to take you through the creation of a sample application using all the functionality we can muster. It's then your job to apply what you've learned from this lesson to implement these features in your own application.

First, create a new PocketPC project, and add to it a command button (near the top), two labels (one small near the top, one as wide as the form near the bottom), and a timer. The only changes you should make to the controls are as follows:

  • Change the timer's name to mnuTimer, set its enabled property to false and it's interval property to 1000
  • Change the larger label's name to lblResult, and set it's caption to nothing
  • Change the form's name to frmMain

The rest of the controls should be left as they are in order to match the code I've pre- written. The next step is to add a module to the project, which is required to declare APIs publicly. In the module, insert the following code:

Option Explicit

Public CurX As Integer, CurY As Integer, MenuX As Integer, MenuY As Integer

Public Const MF_ENABLED = &H0&
Public Const MF_STRING = &H0&
Public Const MF_GRAYED = &H1&
Public Const MF_CHECKED = &H8&
Public Const MF_UNCHECKED = &H0&
Public Const MF_SEPARATOR = &H800&

Public Const TPM_CENTERALIGN = &H4
Public Const TPM_RIGHTALIGN = &H8
Public Const TPM_BOTTOMALIGN = &H20
Public Const TPM_VCENTERALIGN = &H10
Public Const TPM_TOPALIGN = &H0&
Public Const TPM_LEFTALIGN = &H0&
Public Const TPM_RETURNCMD = &H100&

Public Declare Function CreatePopupMenu Lib "Coredll" () As Long

Public Declare Function AppendMenu Lib "Coredll" Alias "AppendMenuW"
(ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long,
ByVal lpNewItem As String) As Long

Public Declare Function TrackPopupMenuEx Lib "Coredll" (ByVal hMenu As
Long, ByVal un As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal hWnd
As Long, lpTPMParams As Long) As Long

Function ShowPopupMenu(intPosLeft As Integer, intPosTop As Integer) As Integer
' Create the handle to the popup menu
Dim hMenu As Long
hMenu = CreatePopupMenu

' Build menu by adding each item
AppendMenu hMenu, MF_ENABLED Or MF_STRING, 1, "First Option"
AppendMenu hMenu, MF_ENABLED Or MF_STRING, 2, "Second Option"
AppendMenu hMenu, MF_SEPARATOR, 0, ""
AppendMenu hMenu, MF_GRAYED Or MF_STRING, 3, "Grayed Option"
AppendMenu hMenu, MF_ENABLED Or MF_STRING Or MF_CHECKED, 4, "Checked Option"
AppendMenu hMenu, MF_GRAYED Or MF_STRING Or MF_CHECKED, 5,
"Checked/Grayed Option"

' Return result to calling procedure
ShowPopupMenu = (TrackPopupMenuEx(hMenu, TPM_LEFTALIGN Or TPM_TOPALIGN
Or TPM_RETURNCMD, intPosLeft, intPosTop, frmMain.hWnd, 0))

End Function

I'll give a quick tour through that code before we move on. Other than the declares, the ShowPopupMenu is the only function in this module. The two parameters passed to it determine where the menu shows up. I'll discuss this more when I cover calling the function. Basically all you need to know about it now is that each of those AppendMenu calls is for a different menu option. The first parm is the handle to the menu and should always be hMenu (or whatever you set equal to the CreatePopupMenu above). The second parm is for flags, which I will cover next. Third is the index number, and the last parm is the menu text itself. The last statement in the function sets the function return value to the index number of the menu item that was selected, which I'll also discuss later.

Flags and what they mean:
First of all, you can use as many flags as you want, each separated by the keyword "Or", however there are some flags that cannot be used in conjunction with one another, all of which are self-evident.
I'm taking this part directly out of the MSDN docs on the AppendMenu API:

  • MF_CHECKED - Places a check mark next to the menu item.
  • MF_ENABLED - Enables the menu item so it can be selected, and restores it from its grayed state.
  • MF_GRAYED - Disables the menu item and grays it so it cannot be selected.
  • MF_SEPARATOR - Draws a horizontal dividing line. This flag is used only in a drop-down menu,
    submenu, or shortcut menu. The line cannot be grayed, disabled, or highlighted. The lpNewItem and uIDNewItem parameters are ignored.
  • MF_STRING - Specifies that the menu item is a text string; the lpNewItem parameter points to
    the string.
  • MF_UNCHECKED - Does not place a check mark next to the item (default).

The ones that cannot be used together are MF_CHECKED and MF_UNCHECKED; as well as MF_GRAYED and MF_ENABLED. You will also notice several other flags if you look at the AppendMenu API help in MSDN – they are flags for regular menus and appear to be ignored in popup menus, however feel free to further experiment with them AT YOUR OWN RISK!!! (Just kidding, you won't break anything by experimenting.)

There are also flags for the TrackPopupMenuEx API. The TPM_RETURNCMD is required to make it send out the correct value when an option is selected. The other two are used to define how the menu will be aligned relative to the stylus. Again, from MSDN help on TrackPopupMenuEx.

Use one of these three to determine how it will align horizontally:

  • TPM_CENTERALIGN - If this flag is set, the function centers the shortcut menu horizontally relative to the coordinate specified by the x parameter.
  • TPM_LEFTALIGN - If this flag is set, the function positions the shortcut menu so that its left side is aligned with the coordinate specified by the x parameter.
  • TPM_RIGHTALIGN - Positions the shortcut menu so that its right side is aligned with the coordinate specified by the x parameter.

Use one of these three to determine how it will align vertically:

  • TPM_BOTTOMALIGN - If this flag is set, the function positions the shortcut menu so that its bottom side is aligned with the coordinate specified by the y parameter.
  • TPM_TOPALIGN - If this flag is set, the function positions the shortcut menu so that its top side is
    aligned with the coordinate specified by the y parameter.
  • TPM_VCENTERALIGN - If this flag is set, the function centers the shortcut menu vertically relative to the coordinate specified by the y parameter.

Of course you should only use one from each group above, but I expect it would be rare to use anything but TPM_LEFTALIGN and TPM_TOPALIGN.

Next Page