Die Ressourcendefinition
POPUPMENU MENUEX CHARACTERISTICS 1 { POPUP "Dies ist ein Test", 123 { MENUITEM "&Erledigt", PM_ERLEDIGT MENUITEM "&Neuer Arbeitsgang", PM_NEWTASK MENUITEM SEPARATOR MENUITEM "E&igenschaften", PM_PROP } } |
Fensterfunktion
In der Fensterfunktion wird das Ereignis WM_CONTEXTMENU gefangencase WM_CONTEXTMENU: POINT pt; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); ScreenToClient(hWnd, &pt); if (popupContext(hWnd, POPUPMENU, pt)) { |
Im Gegensatz zu WM_LBUTTONDBLCLK kommen hier die Koordinaten der Maus in Screen- und nicht in Client-koordinaten. Für unsere Zwecke wird sie mit der Windowsfunktion ScreenToClient umgewandelt.
BOOL popupContext(HWND hwnd, int ResID, POINT pt) { RECT rc; GetClientRect(hwnd, &rc); if (PtInRect(&rc, pt)) { ClientToScreen(hwnd, &pt); popupDisplay(hwnd, ResID, pt); return TRUE; } return FALSE; // no menu is displayed. } |
Nachdem geprüft ist, ob der Cursor auch im Clientbereich des Fensters ist, kann nun das Menü erzeugt und bearbeitet werden.
static void popupDisplay(HWND hwnd, int ResID, POINT pt) { HMENU hmenu; // top-level menu HMENU hmenuTrackPopup; // pop-up menu hmenu = LoadMenu(GlobalInstance, MAKEINTRESOURCE(ResID)); if (hmenu == NULL) return; hmenuTrackPopup = GetSubMenu(hmenu, 0); TrackPopupMenu(hmenuTrackPopup, TPM_RIGHTBUTTON | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwnd, NULL); DestroyMenu(hmenu); } |
Mit LoadMenu wird das in der Ressource definierte Menü geladen. TrackPopupMenu kann nicht das Toplevel-Menü anzeigen. Dieses wird nur als Dummy benötigt. Stattdessen wird mit GetSubMenu der erste Menüpunkt für die weitere Bearbeitung ermittelt. Nach der Verfolgung der Maus wird das Menü wieder zerstört.
In der weiteren Bearbeitung wird durch das Auswählen eines Punktes ein WM_COMMAND ausgelöst.