Kontext Menüs gehören zum State of the Art.
Es ist auch nicht weiter schwer ein Menü zu laden ünd per TrackPopupMenu auf den Bildschirm zu zaubern. Entsprechender Code sieht dann meistens so aus:
void CMyView::OnContextMenu(CWnd* pWnd, CPoint pt)
{
// Get the menu
CMenu popups;
if (!popups.LoadMenu(_T("AGV-IDR_MACRO_EDITOR_CONTEXT")))
AfxThrowResourceException();
CMenu* pSubMenu= popups.GetSubMenu(0);
ASSERT(pSubMenu);
if (!pSubMenu)
AfxThrowResourceException();
pSubMenu->TrackPopupMenu(0,pt.x,pt.y,this);
}
Oft sind in dem Menü einfache IDs von Commands verwendet worden, die irgendwo im View, Dokument, Frame oder der Applikation implementiert sind. Der Programmierer wundert sich nun warum seine Menüpunkte nicht ausgegraut werden. Alle Menüpunkte für alle IDs sind aktiv. Und man wundert sich noch mehr. Manche Commands (außerhalb des Views) werden nicht ausgeführt.
Was läuft hier falsch?
❗ Die Antwort liegt einzig und alleine im Aufruf von TrackPopupMenu! Der letzte Parameter gibt an, an wen die entsprechenden Nachrichten (WM_COMMAND, WM_INITPOPUPMENU und andere) gesendet werden. Naheliegender Weise gibt der Entwickler hier das Fenster an, in dem er das Popup Menü anzeigen will. Hier liegt der Hase im Pfeffer.
Ein normales Fenster und ein View hat keine Verwendung (Handler) für WM_INITPOPUPMENU. Solch ein Handler wäre aber für das Command Routing der MFC notwendig um die Menu-Items ein- und auszuschalten.
Das CMainFrame hat solch einen Handler, und kann damit umgehen. Also einfach das CMainFrame als Zeiger übergeben und … es funktioniert wie erwartet. Warum auch nicht. Die IDs aus dem normalen Menü werden ja auch über genau den selben Weg des Command Routings behandelt.
Die entscheidende Codezeile sieht dann so aus:
pSubMenu->TrackPopupMenu(0,pt.x,pt.y,AfxGetMainWnd());
Wird da eigentlich mittlerweile als pt was vernünftiges übergeben, wenn man das Kontextmenü per Keyboard aktiviert, oder muß man das immer noch von Hand korrigieren?
Ich liebe Anwendungen, die das Kontextmenü an 0,0 aufklappen. 😀
Nein! Daran hat sich nichts geändert.
Aber ich muss Dich korrigieren:
Wenn die entspechende Taste für Kontextmenüs verwendet wird, dann werden die Koordinaten -1,-1 überliefert undnicht 0,0!
Inteligente Programme 🙂 verwenden dann nicht die Mauscursor Koordinaten sondern die Koordinaten des aktiven selektierten Items (z.B. aktuelle List Control Zeile).