windows_programming_notes.nbk: Home | Index | Next Page: WM_COPY | Previous Page: WM_COMPAREITEM


 WM_CONTEXTMENU

The WM_CONTEXTMENU message notifies a window that the user clicked the right mouse button (right clicked) in the window.

A window receives this message through its WindowProc function.

    LRESULT CALLBACK WindowProc(
      HWND hwnd,       // handle to window
      WM_CONTEXTMENU,  // the message to send
      WPARAM wParam,   // handle to window (HWND)
      LPARAM lParam    // horizontal and vertical position
    );

Parameters

Return Values

No return value.

Remarks

A window can process this message by displaying a shortcut menu using the TrackPopupMenu or TrackPopupMenuEx function. To obtain the horizontal and vertical positions, use the following code:

xPos = GET_X_LPARAM(lParam); yPos = GET_Y_LPARAM(lParam); If a window does not display a shortcut menu it should pass this message to the DefWindowProc function. If a window is a child window, DefWindowProc sends the message to the parent. Otherwise, DefWindowProc displays a default shortcut menu if the specified position is in the window's caption.

DefWindowProc generates the WM_CONTEXTMENU message when it processes the WM_RBUTTONUP or WM_NCRBUTTONUP message or when the user types SHIFT+F10. The WM_CONTEXTMENU message is also generated when the user presses and releases the VK_APPS key.

If the context menu is generated from the keyboard—for example, if the user types SHIFT+F10--then the x- and y-coordinates are –1 and the application should display the context menu at the location of the current selection rather than at (xPos, yPos).

Requirements

  Windows NT/2000 or later: Requires Windows NT 3.51 or later.
  Windows 95/98/Me: Requires Windows 95 or later.
  Header: Declared in Winuser.h; include Windows.h.

From [@url "http://blogs.msdn.com/oldnewthing/archive/2004/09/21/232369.aspx" @]:

Before we continue with our IContextMenu discussion, I need to take a little side trip and discuss the subtleties of the WM_CONTEXTMENU message.

First, a correction to the existing header file:

#undef HANDLE_WM_CONTEXTMENU
#define HANDLE_WM_CONTEXTMENU(hwnd, wParam, lParam, fn) \
    ((fn)((hwnd), (HWND)(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)), 0L)

Apparently, HANDLE_WM_CONTEXTMENU was overlooked when the header file gained multimonitor support.

The second subtlety of the WM_CONTEXTMENU message is the recognition that context menus can be invoked from the keyboard, not just by the mouse. If you have a 104-key keyboard, you will probably have a menu key to the right of your space bar. (Laptop owners: You're on your own. Laptop keyboards are hardly standardized.) Alternatively, you can type Shift+F10 to get the same effect.

When the user invokes a context menu from the keyboard, the x and y coordinates are both -1. In this case, you should display the context menu for the currently-selected item (or items, if a multiple selection is active). If you miss this detail, then you will end up hit-testing against (-1, -1) and probably not find anything.

Okay, now that these remarks on the WM_CONTEXTMENU message are out of the way, we can return to our discussion of the IContextMenu interface next time.


windows_programming_notes.nbk: Home | Index | Next Page: WM_COPY | Previous Page: WM_COMPAREITEM


Notebook exported on Monday, 7 July 2008, 18:56:50 PM Eastern Daylight Time