System-Menü

Wenn wir bisher von Menüs gesprochen haben, so haben wir damit immer das Fenstermenü gemeint. Normalerweise besitzt jedes Rahmenfenster aber zusätzlich noch ein System-Menü. Das System-Menü wird geöffnet, in dem man in der Titelzeile das kleine Icon (ganz links) anklickt.

Das System-Menü

Und auch dieses Menü lässt sich anpassen. Dazu muss jedoch zuerst ein entsprechender CMenu-Zeiger auf dieses Menü geholt werden. Dies wird durch den Aufruf der CWnd-Methode GetSystemMenu(...) erreicht. Der Parameter der Methode bestimmt die von der Methode durchzuführende Aktion. Wird der Parameter auf FALSE gesetzt, so wird ein CMenu-Zeiger auf das System-Menü zurückgeliefert. Durch übergeben des Wertes TRUE lässt sich das System-Menü zurücksetzen, d.h. es erhält wieder seine ursprüngliche Konfiguration.

Anschließend kann durch den Aufruf der CMenu-Methoden wie z.B. AppendMenu(...) oder auch ModifyMenu(...) das System-Menü modifiziert werden.

ACHTUNG! Rufen Sie GetSystemMenu(...) immer als Methode des Rahmenfensters auf. Nur das Rahmenfenster besitzt ein System-Menü! Wollen Sie von einem Ansichtsobjekt aus das System-Menü verändern, so holen Sie sich zuerst mittels GetParent(...) einen Zeiger auf das Rahmenfenster.

Im nachfolgenden Beispiel wird dem System-Menü als erstes ein neuer Eintrag Piep mit der ID ID_PIEP hinzugefügt. Diese ID müssen Sie selbstverständlich selbst definieren. Sie können dies über das Menü Ansicht-Resourcensymbole tun. Anschließend wird der Menü-Eintrag Schließen des System-Menüs gesperrt, so dass die Anwendung nur noch über das Datei-Menü verlassen werden kann. Beachten Sie bitte, dass auch das Schließ-Icon (kleines Kreuz ganz rechts in der Titelzeile) damit gesperrt wird.

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
   
    // TODO: Speziellen Erstellungscode hier einfügen
    // Menue-Objekt fuer System-Menue holen
    CMenu* pSysMenu = GetSystemMenu(FALSE);
    // Zusaetzlichen Menuepunkt anhaengen
    pSysMenu->AppendMenu(MF_ENABLED,ID_PIEP,"Piep!");
    // Sperre Schliessen-Menupunkt und Schliessen-Icon!
    pSysMenu->ModifyMenu(SC_CLOSE,MF_BYCOMMAND|MF_DISABLED,SC_CLOSE);
    return 0;
}
Wollen Sie verhindern, dass das Fenster minimiert bzw. maximiert werden kann, so müssen Sie dazu den Fensterstil WS_MINIMIZEBOX bzw. WS_MAXIMIZEBOX in der Methode PreCreateWindow(...) entfernen. Ein Sperren der entsprechenden Menü-Einträge im System-Menü reicht dazu nicht aus!

Vielleicht haben Sie sich gewundert, woher die Konstante SC_CLOSE im obigen Listing beim Aufruf von ModifyMenu(...) kommt. Dazu kommen wir gleich noch.

Wir haben im Beispiel bis jetzt nur dem System-Menü einen neuen Eintrag Piep hinzugefügt. Was noch fehlt ist der Nachrichtenbearbeiter für diesen neuen Menü-Eintrag. Alle Menü-Einträge aus dem System-Menü erzeugen eine WM_SYSCOMMAND Nachricht, die durch den MFC-Bearbeiter OnSysCommand(...) verarbeitet wird. Dieser Nachrichtenbearbeiter muss zur Klasse des Rahmenfenster gehören! Er erhält als Parameter u.a. die ID des ausgewählten Menü-Eintrags. In der Online-Hilfe zu dieser Methode finden Sie übrigens auch die Konstanten für die vordefinierten Menü-Einträge, wie z.B. SC_CLOSE. Beachten Sie aber folgendes wenn Sie Ihrem Rahmenfenster die Methode OnSysCommand(...) hinzufügen:

Leiten Sie unbedingt alle nicht von der Anwendung verarbeiteten Nachrichten immer an die Basisklassen-Methode weiter! Wenn Sie dies nicht tun, so können Sie die Anwendung nur durch <STRG>+<ALT>+<DEL> (Dreifinger-Griff) beenden, da kein Popup-Menü mehr geöffnet wird. Also Vorsicht!

Das nachfolgende Listing zeigt eine mögliche Verarbeitung des Menü-Eintrags ID_PIEP auf.

void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
{
    // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen und/oder Standard aufrufen

    if (nID == ID_PIEP)
        MessageBeep(-1);
    else
        CFrameWnd::OnSysCommand(nID, lParam);
}

Das fertige Beispiel finden Sie unter 07Ressourcen\SysMenu.



Copyright © 2004

Senden Sie Emails mit Fragen oder Kommentaren zu dieser Website an: mailto:info@cpp-tutor.de
 Wolfgang Schröder, Lerchenweg 23, D-72805 Lichtenstein. Tel: +49 7129 6470