Windows Programmierung: Menü
Willemers Informatik-Ecke

Die Ressourcendefinition

IDC_UTIL MENU DISCARDABLE 
BEGIN
    POPUP "&Datei"
    BEGIN
        MENUITEM "Ö&ffnen...",                  IDM_OPEN
        MENUITEM "&Speichern als...",           IDM_SAVEAS
        MENUITEM SEPARATOR
        MENUITEM "&Beenden",                    IDM_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About ...",                  IDM_ABOUT
    END
END

Dass ein Fenster ein Menü hat, wird bei der Registrierung der Fensterklasse angegeben.

Empfangen eines Menüereignisses

In der Fensterfunktion wird die Nachricht WM_COMMAND empfangen. Am einfachsten unterscheidet man die Menüpunkt, indem man das niedrigere Halbwort des wParamters verwendet. Hier steht dieselbe ID, die bei der Ressourcendefinition verwendet worden ist.

    case WM_COMMAND:
        Id = LOWORD(wParam); 
        switch (Id) {
        case IDM_ABOUT:
            break;
        case IDM_OPEN:
            break;

Haken an das Menü setzen

Im Fenster des Menüs ruft man die Funktion CheckMenuItem. Im letzten Parameter muss MF_CHECKED oder MF_UNCHECKED übergeben werden, je nachdem, ob man einen Haken will oder nicht. Es reicht nicht, dort 0 oder 1 zu übergeben. Hängt der Haken von einem booleschen Wert ab, geht man wie folgt vor, um das Menü-Item IDM_KONTEXTINDEX umzuschalten:

CheckMenuItem(GetMenu(hWnd), IDM_KONTEXTINDEX, BooleWert?MF_CHECKED:MF_UNCHECKED);
BooleWert = !BooleWert;

Um das Menü-Handle zu bekommen, ruft man GetMenu mit dem HWND des Fensters auf, das das Menü enthält.

Die Funktion GetMenuState kann ermitteln, ob ein Haken gesetzt ist, aber auch, ob ein Menueintrag enabled oder andere Eigenschaften hat. Der Rückgabewert muss gegen MF_CHECKED mit & maskiert werden, um zu ermitteln, ob der Haken gesetzt ist.

Das folgende Beispiel zeigt eine Funktion, die beim Eintreffen eines Haken-Menüeintrags verwendet werden kann. Es liefert den booleschen Wert zurück, ob der Haken nach dem Klick gesetzt ist und erledigt dabei gerade das Umschalten.

bool switchMenuItemCheck(HWND hwnd, int item)
{
    HMENU hMenu = GetMenu(hwnd);
    UINT istChecked = GetMenuState(hMenu, item, MF_BYCOMMAND);
    if (istChecked & MF_CHECKED) // absichtlich nur 1 &
    {
        CheckMenuItem(hMenu, item, MF_UNCHECKED);
        return true;
    } else {
        CheckMenuItem(hMenu, item, MF_CHECKED);
        return false;
    }
}

Menüpunkt deaktivieren

Im Fenster des Menüs ruft man die Funktion EnableMenuItem. Im letzten Parameter muss MF_ENABLED oder MF_GRAYED übergeben werden. Es gibt auch ein MF_DISABLED, das auch den Menüpunkt deaktiviert. Allerdings liefert dies keine optische Rückmeldung. In den allermeisten Fällen macht dies aber keinen Sinn.

EnableMenuItem(GetMenu(hWnd), IDM_SAVE, MF_GRAYED);
...
EnableMenuItem(GetMenu(hWnd), IDM_SAVE, MF_ENABLED);