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.

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.
|