Die meisten Windows-Anwendungen lassen sich über Pulldown-Menüs bedienen. Auf diese Weise kann man dem Benutzer eine umfangreiche Palette von Funktionen bereitstellen, ohne daß dafür Schaltflächen im Fenster vorhanden sein müssen. Der wertvolle Platz auf dem Bildschirm läßt sich damit für andere Dinge freihalten.
Als die ersten Computer-Terminals eingeführt wurden und sich die Benutzer mit Computer-Software auseinanderzusetzen begannen, stellten sogar die Entwickler von großen Mainframe-Systemen fest, daß man dem Benutzer in irgendeiner Form Menüs anbieten sollte, aus denen sich die vom Computer auszuführenden Funktionen auswählen lassen. Diese frühen Menüs waren im Vergleich mit heutigen Standards primitiv und ließen sich nur schwer bedienen. Seit diesen Anfangstagen haben sich die Menüs enorm verbessert. Außerdem haben sich bestimmte Standards für die Gestaltung und Bedienung durchgesetzt, die das Einarbeiten in neue Programme erleichtern.
Die Softwareentwickler, die den Gedanken der grafischen Benutzeroberflächen (Graphical User Interface - GUI) umsetzen, zielen mit einheitlichen Verhaltensmustern der Elemente einer Anwendung darauf ab, Computersysteme und Anwendungen verständlicher und benutzerfreundlicher zu gestalten. Menüs zur Auswahl der Anwendungsfunktionen bilden dabei einen Teil der grafischen Benutzeroberfläche, der sich leichter erlernen läßt, wenn alle in gleicher Weise arbeiten. Im Ergebnis wurden eine Reihe von Menüstilen entwickelt.
Als erste Menüstile wurden Pulldown- und überlappende Menüs standardisiert. Bei diesen Menüs sind die Kategorien in einer Zeile am oberen Rand des Anwendungsfensters angeordnet. Wenn man eine dieser Kategorien auswählt, öffnet sich ein Menü unter der Kategorie. Hier kann man aus einer Anzahl von Menüeinträgen (oder Befehlen) wählen, die verschiedene Funktionen in der Anwendung auslösen.
Eine Variante dieses Menüstils ist das überlappende Menü, beim dem sich ein weiteres Untermenü rechts neben einem Menüeintrag öffnet. Dieses Untermenü ist dem Pulldown-Menü ähnlich und weist eine Reihe von Einträgen auf, die Anwendungsfunktionen auslösen. Dem Menüentwickler sind keine Grenzen gesetzt, wie tief er die überlappenden Menüs verschachtelt. Allerdings wurde schnell klar, daß mehr als zwei überlappende Menüebenen unhandlich sind.
Schließlich wurde ein dritter Menüstil entwickelt, das sogenannte Popup- oder Kontextmenü - ein Menü, das sich mitten in der Anwendung öffnet und frei über den gesamten Arbeitsbereich der Anwendung verschiebbar ist. Die Bezeichnung Kontextmenü rührt daher, weil das spezielle Menü vom markierten Objekt oder Arbeitsbereich abhängig ist, wo sich der Cursor oder Mauszeiger gerade befindet.
Wenn ein Benutzer in einer Anwendung vorrangig mit der Tastatur arbeitet, beispielsweise bei einer Textverarbeitung, ist eine sinkende Produktivität festzustellen, wenn er die Hände von der Tastatur nehmen muß, um einen Menübefehl mit der Maus auszuwählen. Aus diesem Grund sehen die Softwareentwickler bestimmte Tastenkombinationen für verschiedene Menübefehle vor (insbesondere für die am häufigsten genutzten Menüauswahlen). Bei diesen speziellen Tasten und Tastenkombinationen spricht man von Schnelltasten (accelerator keys), Zugriffstasten und Hotkeys.
Die Hotkeys werden in einem Menübefehl durch unterstrichene Buchstaben gekennzeichnet. Wenn man die (Alt)-Taste zusammen mit der Taste des unterstrichenen Buchstabens drückt, wählt man den Menüeintrag aus, dem dieser Buchstabe zugeordnet ist. Auf diese Weise kann man durch die Anwendungsmenüs navigieren, ohne die Hände von der Tastatur nehmen zu müssen.
Für erfahrene Benutzer haben die Anwendungsentwickler Schnelltasten oder Zugriffstasten vorgesehen. Eine Zugriffstaste ist eine einzelne Tastenkombination, über die man eine Anwendungsfunktion direkt auslösen kann, statt sich durch die Anwendungsmenüs zu arbeiten. Erfahrene Benutzer können auf diese Weise zügiger arbeiten, weil sie häufig genutzte Anwendungsfunktionen nicht über den Umweg einer Menüauswahl aufrufen müssen. Damit sich der Benutzer die Zugriffstasten praktisch im Vorübergehen einprägen kann, sind die Tastenkombinationen rechts neben dem betreffenden Menüeintrag aufgeführt.
Es gibt zwar keine eigentlichen Standards, wie Menüs zu entwerfen sind, es haben sich aber eine Reihe von Konventionen durchgesetzt, die sich auf den Entwurf und die Organisation von Menüs beziehen. Diese Konventionen hat Microsoft in $$$Windows Interface Guidelines for Software Design für Entwickler von Windows-Anwendungen veröffentlicht. Die Absicht dieser Veröffentlichung ist es, die Entwicklung von einheitlichem Anwendungsverhalten zu erleichtern, um eines der Hauptziele grafischer Benutzeroberflächen zu erreichen. Die Konventionen lauten wie folgt:
Menüs sind in Visual C++-Anwendungen als Ressource definiert. Daher kann man sie im Editor von Visual C++ über die Registerkarte Ressourcen im Arbeitsbereich entwerfen. Wenn Sie eine dialogbasierte Anwendung neu erstellen, ist im Ressourcenzweig noch kein Menüordner vorhanden, was Sie aber ändern können.
Ein Menü läßt sich problemlos erstellen. Dazu sind folgende Schritte auszuführen:
1. Die Anwendung erstellen, die den Rahmen für das Menü bildet.
2. Dem Projekt eine Menüressource hinzufügen.
3. Die Menüressource anpassen, um die jeweiligen Menübefehle für die Anwendung einzubinden.
4. Das Menü mit Funktionalität ausstatten, indem man entsprechende Routinen mit den Menübefehlen verbindet.
Für die Beispielanwendung in diesem Kapitel erzeugen Sie eine einfache dialogbasierte Anwendung, die eine einzelne Schaltfläche und ein Menü enthält. Um die Anwendung zu erstellen, führen Sie die folgenden Schritte aus:
1. Erstellen Sie mit dem MFC-Anwendungs-Assistenten eine neue Anwendung. Nennen
Sie das Projekt Menus
.
2. Übernehmen Sie die Standardeinstellungen des Anwendungs-Assistenten in allen
Dialogfeldern. Als Titel des Dialogfelds geben Sie Menus
ein.
3. Wenn der Anwendungs-Assistent das Gerüst erstellt hat, löschen Sie alle Steuerelemente aus dem Dialogfeld.
4. Nehmen Sie in das Dialogfeld eine einzelne Schaltfläche auf. Als Namen legen Sie
für diese Schaltfläche IDC_EXIT
fest und geben als Beschriftung &Beenden
ein.
5. Fügen Sie mit dem Klassen-Assistenten für diese Schaltfläche eine Funktion hinzu.
Schreiben Sie in diese Funktion den Code, der die Funktion OnOK
aufruft. Wie Sie
wissen, bewirkt die Funktion OnOK
das Schließen der Anwendung.
Wenn Sie nicht mehr genau wissen, wie Sie die Funktion |
Nachdem Sie die zugrundeliegende Anwendung erstellt haben, können Sie für die Anwendung ein neues Menü erzeugen. Fügen Sie zuerst eine Menüressource in das Projekt ein. Dabei ruft Visual C++ automatisch den Menü-Editor auf, der Ihnen die Anpassung des Menüs erlaubt. Die folgenden Schritte zeigen, wie Sie ein Menü hinzufügen und anpassen:
1. Gehen Sie im Arbeitsbereich auf die Registerkarte Ressourcen.
2. Markieren Sie den Ordner der Projektressourcen am Beginn der Strukturansicht,
in unserem Beispiel Menus Ressourcen
.
3. Klicken Sie mit der rechten Maustaste, um das Kontextmenü zu öffnen.
4. Wählen Sie aus dem Kontextmenü den Befehl Einfügen.
5. Im Dialogfeld Ressource einfügen markieren Sie Menu
in der Liste Ressourcentypen
, wie es Abbildung 6.1 zeigt. Klicken Sie auf die Schaltfläche Neu.
Abbildung 6.1:
Das Dialogfeld Ressource einfügen
6. Der Menü-Editor öffnet den Bearbeitungsbereich des Visual Studios. Der erste Menübefehl ist hervorgehoben (siehe Abbildung 6.2).
Abbildung 6.2:
Ein leeres Menü
Die Menüressource ist nun angelegt, und Sie können sie mit Menübefehlen beleben. Einen Menübefehl fügen Sie in den folgenden Schritten hinzu:
1. Klicken Sie mit der rechten Maustaste auf den hervorgehobenen Bereich, und wählen Sie aus dem Kontextmenü den Befehl Eigenschaften.
2. Geben Sie den Titel des Menüs ein, im Beispiel &Datei
, und schließen Sie dann
das Dialogfeld Eigenschaften.
3. Die erste Position des Dropdown-Menüs ist hervorgehoben. Um den entsprechenden Menübefehl hinzuzufügen, klicken Sie wieder mit der rechten Maustaste auf den hervorgehobenen Bereich und wählen aus dem Kontextmenü den Befehl Eigenschaften.
4. Geben Sie eine ID und einen Titel für den Menübefehl ein. Für das Beispiel wählen
Sie IDM_FILE_HELLO
als ID und &Hello
als Titel. Schließen Sie das Dialogfeld.
Momentan verfügen Sie über ein Menü mit einem einzigen Menübefehl. Sie können nun weitere Menübefehle hinzufügen, indem Sie die obigen Schritte 3 und 4 für jeden hervorgehobenen Bereich wiederholen. In das Menü lassen sich auch Trennlinien einfügen. Es handelt sich dabei um eine waagerechte Linie, mit der man zwei funktionell unterschiedliche Bereiche von Menüauswahlen abgrenzt. Eine Trennlinie fügen Sie folgendermaßen hinzu:
1. Markieren Sie den Menübefehl, wo Sie die Trennlinie plazieren möchten. Im Beispiel sollte die zweite Menüposition im Dropdown-Menü hervorgehoben sein. Öffnen Sie das Dialogfeld Menübefehl Eigenschaften wie im Schritt 3 der obigen Folge. Schalten Sie nun einfach das Kontrollkästchen Trennlinie ein, wie es Abbildung 6.3 zeigt, und schließen Sie das Dialogfeld.
Abbildung 6.3:
Eine Trennlinie festlegen
Um das Beispielprogramm zu vervollständigen, nehmen Sie nach den gleichen Schritten wie oben beschrieben einen Menübefehl Beenden in das Menü Datei auf sowie ein zweites Menü namens Hilfe mit einem Menübefehl Info. Die folgenden Schritte, die der obigen Schrittfolge ähnlich sind, zeigen im Detail das Hinzufügen der zusätzlichen Elemente:
1. Öffnen Sie das Dialogfeld Menübefehl Eigenschaften für die dritte Position
im Dropdown-Menü, und legen Sie die ID als IDM_FILE_EXIT
(oder
IDM_DATEI_BEENDEN
, wenn Ihnen das lieber ist) und die Beschriftung mit &Beenden
fest. Schließen Sie das Dialogfeld.
2. Markieren Sie die zweite Position in der Menüleiste, und öffnen Sie das Dialogfeld
Menübefehl Eigenschaften. Legen Sie den Titel mit &Hilfe
fest, und schließen
Sie das Dialogfeld.
3. Öffnen Sie das Dialogfeld Menübefehl Eigenschaften für die erste Position im
Dropdown-Menü des zweiten Eintrags in der Menüleiste. Legen Sie die ID mit
ID_HELP_ABOUT
und den Titel mit &Info
fest. Schließen Sie das Dialogfeld.
Das Menü ist damit erstellt. Allerdings fehlt noch die Verbindung zur Anwendung.
Sie verfügen nun über ein Menü, das Sie in Ihrer Anwendung einsetzen können. Wenn Sie aber die Anwendung in der jetzigen Entwicklungsphase kompilieren und ausführen, erscheint das Menü nicht. Das Menü ist noch mit dem Dialogfeld zu verbinden. Das erreichen Sie in folgenden Schritten:
1. Öffnen Sie den Dialog-Editor, indem Sie auf das Hauptdialogfeld der Anwendung
im Ordner Dialog
des Arbeitsbereichs doppelklicken. Im Beispiel doppelklicken
Sie auf IDD_MENUS_DIALOG
.
2. Markieren Sie das gesamte Dialogfeld. Achten Sie darauf, daß keine Steuerelemente markiert sind, und öffnen Sie das Dialogfeld Dialogfeld Eigenschaften. (Sie öffnen hier die Eigenschaften für das Dialogfeld an sich und nicht für irgendein Steuerelement des Dialogfelds.)
3. Wählen Sie aus der Dropdown-Liste Menü das eben erstellte Menü aus, wie es Abbildung 6.4 zeigt.
Abbildung 6.4:
Das Menü mit dem Dialogfeld verbinden
Wenn Sie die Anwendung kompilieren und ausführen, ist das Menü mit dem Dialogfeld der Anwendung verbunden, wie es aus Abbildung 6.5 hervorgeht. Wie bei jeder anderen Windows-Anwendung können Sie Menübefehle auswählen. Allerdings gibt es einen kleinen Unterschied. Wenn Sie momentan einen der Menübefehle wählen, passiert überhaupt nichts. Sie müssen noch die Funktionalität für die Menübefehle realisieren.
Abbildung 6.5:
Das Menü ist nun Teil des Anwendungsdialogfelds
Nunmehr verfügen Sie über ein Menü als Teil der Anwendung. Es wäre nun angebracht, wenn man tatsächlich etwas Sinnvolles damit anstellen könnte. Bevor Ihr Menü irgendeine Aktion bewirken kann, müssen Sie - genau wie überall in Ihren Visual C++-Anwendungen - festlegen, was zu tun ist. Um das Menü der Beispielanwendung mit etwas Funktionalität auszustatten, führen Sie die folgenden Schritte aus:
1. Öffnen Sie den Menü-Editor für Ihr Menü.
2. Öffnen Sie den Klassen-Assistenten über das Menü Ansicht.
3. Es erscheint das Dialogfeld Hinzufügen einer Klasse (analog zum gestrigen Tag, als Sie ein zweites Dialogfeld aufgenommen hatten). Behalten Sie die Option Vorhandene Klasse auswählen bei, und klicken Sie auf OK (siehe Abbildung 6.6).
Abbildung 6.6:
Das Dialogfeld Hinzufügen einer Klasse
Als Sie gestern ein zweites Dialogfeld in Ihre Anwendung hinzugefügt haben, mußten Sie eine neue C++-Klasse für dieses Dialogfeld erstellen. Das Menü in der heutigen Lektion verbinden Sie mit einer vorhandenen C++-Klasse für das Dialogfeld, dem das Menü zugeordnet ist.
4. Markieren Sie die C++-Klasse des Hauptdialogfelds in der Klassenliste des Dialogfelds
Klasse auswählen. Im Beispiel markieren Sie CMenusDlg
, wie es Abbildung
6.7 zeigt. Damit teilen Sie Visual C++ mit, daß die gesamte Funktionalität, die Sie
von den verschiedenen Menübefehlen aufrufen, zur selben Dialogfeldklasse des
Fensters, mit dem das Menü verbunden ist, gehört.
Abbildung 6.7:
Das Dialogfeld Klasse auswählen
Für die Menüelemente, mit denen Sie Funktionen in Ihrer Anwendung auslösen möchten, können Sie über den Klassen-Assistenten Behandlungsfunktionen hinzufügen, wie Sie es von den Steuerelementen her kennen, die Sie im Dialogfeld plaziert haben.
In die Beispielanwendung nehmen Sie eine Funktion für das Objekt IDM_FILE_HELLO
(den Menübefehl Hello) für die Nachricht COMMAND
auf. Nennen Sie die Funktion OnHello
, und schreiben Sie den Code aus Listing 6.1 in diese Funktion.
Listing 6.1: Die Funktion OnFileHello
1: void CMenusDlg::OnFileHello()
2: {
3: // TODO: Code für Befehlsbehandlungsroutine hier einfügen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: // Meldung anzeigen
10: MessageBox("Hello Leute", "Hello");
11:
12: ///////////////////////
13: // EIGENER CODE, ENDE
14: ///////////////////////
15: }
Bereits vorhandene Behandlungsroutinen können Sie von Menübefehlen aufrufen, indem
Sie die vorhandene Funktion zum Menüereignis COMMAND
hinzufügen. Zu diesem
Zweck können Sie eine Funktion für die Objekt-ID des Menüs hinzufügen und den Namen
der vorhandenen Funktion spezifizieren, statt den vorgeschlagenen Funktionsnamen
zu übernehmen.
Um die Funktion OnExit
für den Menübefehl Beenden erneut zu verwenden, öffnen
Sie wieder den Menü-Editor und anschließend den Klassen-Assistenten. Fügen Sie
über den Klassen-Assistenten eine Funktion für das Objekt IDM_FILE_EXIT
für die
Nachricht COMMAND
hinzu. Übernehmen Sie diesmal nicht den vom Klassen-Assistenten
vorgeschlagenen Funktionsnamen, sondern geben Sie den Funktionsnamen
OnExit
ein. Damit verbinden Sie automatisch die vorhandene Funktion OnExit
, die
Sie bereits weiter oben für die Schaltfläche Beenden erstellt haben, mit dem Menübefehl
Beenden.
Um die Funktionalität des Beispiels abzurunden, fügen Sie noch eine Funktion für das
Objekt ID_HELP_ABOUT
für die Nachricht COMMAND
hinzu. Schreiben Sie in diese Funktion
den Code aus Listing 6.2.
Listing 6.2: Die Funktion OnHelpAbout
1: void CMenusDlg::OnHelpAbout()
2: {
3: // TODO: Code für Befehlsbehandlungsroutine hier einfügen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: // Instanz des Info-Fensters deklarieren
10: CAboutDlg dlgAbout;
11:
12: // Info-Fenster anzeigen
13: dlgAbout.DoModal();
14:
15: ///////////////////////
16: // EIGENER CODE, ENDE
17: ///////////////////////
18: }
Den Menübefehl Datei / Beenden haben Sie mit einer vorhandenen Funktion verbunden,
die Ihre Anwendung schließt. Für Datei / Hello haben Sie eine neue Funktion
hinzugefügt, die die Funktion MessageBox
aufruft, um eine einfache Meldung anzuzeigen.
Beim Menü Hilfe / Info ist eine weitere Funktion hinzugekommen, die
eine Instanz des Dialogfelds Info deklariert und die Methode DoModal
aufruft.
Wenn Sie die Anwendung kompilieren und ausführen, können Sie sich davon überzeugen,
daß alle Menüeinträge funktionieren. Wenn Sie Hilfe / Info wählen, wie es
Abbildung 6.8 zeigt, erscheint das Dialogfeld Info (siehe Abbildung 6.9). Wählen Sie
Datei / Hello, kommt die Meldung Hello Leute
(siehe Abbildung 6.10) auf den
Bildschirm. Und mit Datei / Beenden läßt sich die Anwendung schließen.
Abbildung 6.8:
Der Menüeintrag Hilfe / Info
Abbildung 6.9:
Das Dialogfeld Info
Abbildung 6.10:
Das Meldungsfeld Hello Leute
Die meisten Windows-Anwendungen verfügen über sogenannte Popup- oder Kontextmenüs. Diese ruft man auf, indem man mit der rechten Maustaste auf ein Objekt klickt. Die Bezeichnung Popup (etwa: aufspringen) rührt daher, daß diese Menüs mitten im Anwendungsbereich erscheinen und nicht an eine Menüleiste, den Fensterrahmen oder etwas anderes auf dem Bildschirm (ausgenommen den Mauszeiger) gebunden sind. Man spricht auch von Kontextmenüs, weil der Inhalt dieses Menüs vom Kontext abhängt, in dem es geöffnet wird. Die verfügbaren Befehle im Kontextmenü hängen von der momentanen Auswahl in der Anwendung oder der aktuellen Position des Mauszeigers auf einem bestimmten Objekt ab.
Um ein Kontextmenü in der Anwendung bereitzustellen, gibt es zwei Lösungsansätze. Entweder erstellen Sie ein Menü, das speziell als Kontextmenü vorgesehen ist, oder Sie verwenden eines der Pulldown-Menüs aus dem Hauptmenü, das Sie bereits erstellt haben. Wenn Sie ein Menü speziell als Kontextmenü entwerfen, überspringen Sie die oberste Ebene der Menüleiste, indem Sie ein Leerzeichen oder anderen Text, der nicht auf dem Bildschirm erscheint, als Titel eingeben. Wie das funktioniert, erfahren Sie im Abschnitt »Ein Kontextmenü hinzufügen« von Tag 11, wenn Sie ein benutzerdefiniertes Menü speziell als Kontextmenü erstellen.
Jeder Menübefehl eines Dropdown-Menüs läßt sich seinerseits als Kontextmenü verwenden.
Zu diesem Zweck müssen Sie einen Handle auf das Untermenü (das Dropdown-Menü)
ermitteln und dann die Funktion TrackPopupMenu
auf dem Untermenü
aufrufen. Die übrige Funktionalität des Kontextmenüs wurde bereits behandelt, als Sie
die anderen Menüs erstellt und kodiert haben. Um ein Kontextmenü in die Beispielanwendung
einzubauen, führen Sie die folgenden Schritte aus:
1. Fügen Sie mit dem Klassen-Assistenten eine Funktion für die Nachricht
WM_CONTEXTMENU
in das Dialogfeld der Anwendung ein.
2. Nehmen Sie in die Funktion den Code aus Listing 6.3 auf.
Listing 6.3: Die Funktion OnContextmenu
1: void CMenusDlg::OnContextMenu(CWnd* pWnd, CPoint point)
2: {
3: // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen
4:
5: ///////////////////////
6: // EIGENER CODE, ANFANG
7: ///////////////////////
8:
9: // Lokale Variablen deklarieren
10: CMenu *m_lMenu; // Zeiger auf Menü
11: CPoint m_pPoint; // Kopie der Mausposition
12:
13: // Mausposition in lokale Variable kopieren
14: m_pPoint = point;
15: // Position in Bildschirmkoordinaten konvertieren
16: ClientToScreen(&m_pPoint);
17: // Zeiger auf Fenstermenü holen
18: m_lMenu = GetMenu();
19: // Zeiger auf erstes Untermenü holen
20: m_lMenu = m_lMenu->GetSubMenu(0);
21: // Popup-Menü anzeigen
22: m_lMenu->TrackPopupMenu(TPM_CENTERALIGN + TPM_LEFTBUTTON,
23: m_pPoint.x, m_pPoint.y, this, NULL);
24:
25: ///////////////////////
26: // EIGENER CODE, ENDE
27: ///////////////////////
28: }
Die Funktion in Listing 6.3 erstellt zunächst eine Kopie der Mausposition. Es handelt sich dabei um eine relative Position im Fensterbereich. Dieser Wert ist in eine absolute Position bezüglich des gesamten Bildschirmbereichs für die Anzeige des Kontextmenüs umzuwandeln. Wenn Sie die Koordinaten des Mauszeigers nicht umwandeln, läßt sich nicht vorhersagen, wo das Kontextmenü erscheint.
Nachdem Sie die absolute Position berechnet haben, ermitteln Sie einen Zeiger auf
das Fenstermenü. Dieser Zeiger sollte immer ein lokaler Zeiger innerhalb der Funktion,
wo Sie ihn verwenden, sein, da sich der Ort des Menüs in der laufenden Anwendung
ändern kann. Über den Menüzeiger ermitteln Sie als nächstes einen Zeiger auf
das erste Dropdown-Menü (die Numerierung der Untermenüs beginnt mit 0, wie bei
allen anderen Elementen in C/C++). Nachdem Sie einen Zeiger auf das Untermenü
besitzen, können Sie ihn als reguläre Klasseninstanz von CMenu
behandeln.
Das letzte Teil in diesem Puzzle ist der Aufruf der Elementfunktion TrackPopupMenu
der Klasse CMenu
. Diese Funktion übernimmt fünf Argumente und bestimmt damit, wo
und wie das Kontextmenü anzuzeigen ist. Das erste Argument ist eine Kombination
von zwei Flags. Das erste Flag, TPM_CENTERALIGN
, zentriert das Kontextmenü bezüglich
des Mauszeigers. Statt dessen können Sie auch TPM_LEFTALIGN
oder
TPM_RIGHTALIGN
verwenden. Diese Flags richten den linken bzw. rechten Rand des
Kontextmenüs mit der Mausposition aus. Der zweite Teil dieser Flag-Kombination ist
TPM_LEFTBUTTON
. Dieses Flag bewirkt, daß das Kontextmenü über das Drücken der linken
Maustaste aufgerufen wird. Mit TPM_RIGHTBUTTON
läßt sich das Kontextmenü mit
der rechten Maustaste aktivieren.
Das zweite und dritte Argument der Funktion TrackPopupMenu
legen die Bildschirmposition
- nicht die relative Position im Fensterbereich - für das Kontextmenü fest. Das
vierte Argument ist ein Zeiger auf das Fenster, das die Nachrichten der Menübefehle
erhält. Das letzte Argument beschreibt ein Rechteck, in das der Benutzer klicken
kann, ohne das Kontextmenü zu schließen. Übergibt man hier NULL
, wird das Kontextmenü
geschlossen, wenn der Benutzer außerhalb des Kontextmenüs klickt. Mit diesem
Code können Sie in Ihrer Anwendung ein Kontextmenü gemäß Abbildung 6.11 realisieren.
Abbildung 6.11:
Das Kontextmenü in der Praxis
Zu den bereits von Anfang an vorhandenen Schnelltasten für die Auswahl von Menübefehlen gehören die Zugriffstasten. Wie bereits weiter vorn in diesem Kapitel erwähnt, sind Zugriffstasten spezielle Tastenkombinationen - gewöhnlich eine Kombination der (Strg)-Taste mit einer anderen Taste - oder Funktionstasten, die innerhalb der gesamten Anwendung eindeutig sind. Jede dieser Tastenkombinationen löst eine bestimmte Menüfunktion aus.
Die Funktionsweise der Zugriffstasten ist mit den Menüs vergleichbar. Es handelt sich ebenfalls um eine Anwendungsressource, die in einer Tabelle auf der Registerkarte Ressourcen des Arbeitsbereichs definiert ist. Jeder Tabelleneintrag verfügt über eine Objekt-ID und den Code für eine Tastenkombination. Nachdem Sie die Zugriffstasten definiert haben, können Sie den Objekt-IDs Funktionalität zuordnen. Einer Zugriffstaste läßt sich auch dieselbe Objekt-ID wie dem korrespondierenden Menüeintrag zuweisen, so daß in der Nachrichtenzuordnungstabelle der Anwendung nur ein Eintrag zu definieren ist.
Nachdem Sie alle Zugriffstasten definiert haben, können Sie die Tastenkombination
im Menübefehl angeben, damit der Benutzer über die jeweilige Tastenkombination informiert
ist. Hängen Sie ein \t
am Ende der Beschriftung eines Menübefehls an, und
geben Sie anschließend die Tastenkombination an. Die Zeichenfolge \t
erscheint in
der Menüanzeige als Tabulator, der die Beschriftung des Menüs von der Tastenkombination
absetzt.
Leider funktionieren Zugriffstasten nicht bei auf Dialogfeldern basierenden Fenstern, so daß sie in der heutigen Anwendung außen vor bleiben müssen. Wie man Zugriffstasten mit Menüs verbindet, lernen Sie in wenigen Tagen bei der Behandlung von SDI- und MDI-Anwendungen.
Schwerpunkt des heutigen Tages waren Menüs in Visual C++-Anwendungen. Sie haben gelernt, wie man mit den Werkzeugen von Visual C++ ein Menü für eine Anwendung erstellt und dann das Menü mit einem Fenster der Anwendung verbindet. Anschließend wurde gezeigt, wie man den verschiedenen Menübefehlen Funktionalität zuordnet. Gegen Ende der heutigen Lektion haben Sie erfahren, wie man einen Teil des Menüs als Popup- oder Kontextmenü verwenden kann. Schließlich wurde erwähnt, wie sich Zugriffstasten in die meisten Anwendungen einbinden lassen.
Frage:
Muß ich meine Menüs in der gleichen Weise benennen, wie es bei anderen Anwendungen
üblich ist? Zum Beispiel verfügen viele Anwendungen über die Menüs
Datei und Hilfe. Kann ich meine Menüs irgendwie anders bezeichnen?
Antwort:
Die Menübefehle in der Menüleiste können Sie beliebig benennen. Allerdings
gibt es allgemein anerkannte Konventionen, die alle dateiorientierten Funktionen
unter einem Menü Datei zusammenfassen und alle hilfebezogenen
Funktionen unter einem Menü Hilfe. Wenn Sie ein Menü mit Einträgen wie
Broccoli, Bohnen und Möhren haben, werden Sie das Menü wahrscheinlich
mit Gemüse bezeichnen, auch wenn man dafür Lebensmittel oder Pflanzen
verwenden könnte. Im allgemeinen sollten Sie darauf achten, daß sich die Benutzer
leicht in Ihre Anwendung einarbeiten können, so daß die Bezeichnungen
der Menüs möglichst die Einträge im Pulldown-Teil des Menüs charakterisieren.
Frage:
Warum kann ich nicht eine einzelne Taste als Zugriffstaste festlegen?
Antwort:
Eine einzelne Taste löst die Nachricht WM_KEY aus und nicht die Menünachrichten.
Als die Entwickler von Windows die Arbeitsweise von Zugriffstasten
festgelegt haben, gingen sie davon aus, daß einzelne Tasten normalerweise
eine Eingabe in die aktive Anwendung darstellen. Wenn einzelne Tasten als
Zugriffstasten erlaubt wären, könnte Windows nicht bestimmen, ob das Zeichen
eine Eingabe oder eine Schnelltaste darstellt. Durch die erforderlichen
Tastenkombinationen (mit Ausnahme der Funktionstasten) haben die Entwickler
sichergestellt, daß Windows diese Entscheidung nicht treffen muß.
1. Welche Nachricht sendet eine Menüauswahl an die Nachrichtenwarteschlange der Anwendung?
2. Wie verbinden Sie ein Menü mit einem Dialogfeld?
3. Welche vorhandene Klasse legen Sie für die Behandlung von Nachrichten für das Menü fest?
4. Durch welche Nachricht sollte man ein Kontextmenü auslösen?
1. Nehmen Sie in das Hauptfenster eine Schaltfläche auf, und lassen Sie sie dieselbe Funktion aufrufen wie der Menübefehl Hello.
2. Fügen Sie Ihrer Anwendung ein Kontextmenü hinzu, das das Dropdown-Menü Hilfe als Kontextmenü verwendet.