INF: Changing How Pop-Up Menus Respond to Mouse Actions

ID Number: Q65256

3.00 3.10

WINDOWS

Summary:

The TrackPopupMenu function allows an application to receive input

from a menu that is displayed anywhere within the application's client

area. This article demonstrates how to change the menu's default

behavior for mouse selections.

More Information:

The default action for floating pop-up menus maintained with

TrackPopupMenu is as follows:

1. If the menu is displayed in response to a keystroke, the pop-up

menu is visible until the user selects a menu item or presses ESC.

2. If the menu is displayed in response to a WM_*BUTTONUP message, it

acts as if it were displayed in response to a keystroke.

3. If the menu is displayed in response to a WM_*BUTTONDOWN message,

it is displayed as long as the user holds down the mouse button.

When the user releases the mouse button, the menu disappears.

Note: In the context of this article, the * in the WM_*BUTTONUP and

WM_*BUTTONDOWN messages can be L (left mouse button), M (middle mouse

button), or R (right mouse button).

An application can change the behavior of a floating pop-up menu

displayed in response to a WM_*BUTTONDOWN message to keep it visible

after the mouse button is released. However, when an application uses

the techniques described below, it changes the menu's user interface.

Specifically, to change menu selections with the mouse, the user must

first release the mouse button and then press it again. Dragging the

mouse between items with the button down, without releasing the button

at least once, will not change the selection.

To cause a floating pop-up menu to remain visible after it is

displayed in response to a WM_*BUTTONDOWN message, follow these four

steps:

1. In the application, allocate a 256 byte buffer to hold the key

state.

2. Call the GetKeyboardState function with a far pointer to the buffer

to retrieve the keyboard state.

3. Set the keyboard state for the VK_*BUTTON index in the keyboard

state array to 0.

4. Call SetKeyboardState with a far pointer to the buffer to register

the change with Windows.

The keyboard state array is 256 bytes. Each byte represents the state

of a particular virtual key. The value 0 indicates that the key is up,

and the value 1 indicates that the key is down. The array is indexed

by the VK_ values listed in Appendix A of the "Microsoft Windows

Software Development Kit Reference Volume 2" for version 3.0.

The code fragment below changes the state of the VK_LBUTTON to 0 (up)

during the processing of a WM_LBUTTONDOWN message. This causes

TrackPopupMenu to act as if the menu were displayed as the result of a

WM_LBUTTONUP message or of a keystroke. Therefore, the menu remains

visible even after the mouse button is released and the WM_LBUTTONUP

message is received. Items on this menu can be selected with the mouse

or the keyboard.

switch (iMessage)

{

case WM_LBUTTONDOWN:

static BYTE rgbKeyState[256];

GetKeyboardState(rgbKeyState);

rgbKeyState[VK_LBUTTON] = 0; // 0==UP, 1==DOWN

SetKeyboardState(rgbKeyState);

// Create the pop-up menu and call TrackPopupMenu.

break;

}

Additional reference words: 3.00 3.10