vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbacknächstes Kapitel


Woche 1

Tag 6

Menüs

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.

Heute lernen Sie, wie man ...

Menüs

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.

Menüstile

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.

Tastenkombinationen - Menüauswahlen aktivieren

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.

Standards und Konventionen für Menüs

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 entwerfen

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.

Verschiedene Aspekte von Windows-Anwendungen liegen in Form von Ressourcen vor. Dazu gehören das Fensterlayout, Menüs, Symbolleisten, Bilder, Strings, Zugriffstasten usw. Alle diese Merkmale sind in einer sogenannten Ressourcendatei organisiert, auf die der Visual C++-Compiler zurückgreift, um diese Objekte aus deren Definitionen zu erzeugen. Die Ressourcendatei ist eine Textdatei mit der Dateierweiterung .rc. Sie enthält eine textuelle Beschreibung aller Objekte, einschließlich der IDs, Beschriftungen, Abmessungen usw.

Manche Ressourcen wie etwa Bilder und Klänge lassen sich nicht in Textform beschreiben, sondern müssen in einem Binärformat gespeichert werden. Diese Ressourcen sind in separaten Dateien abgelegt, wobei der Dateiname und der Standort in die Ressourcendatei eingebunden werden.

Ein Menü erstellen

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.

Die Anwendung erstellen

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 OnOK hinzufügen, sehen Sie sich am besten noch einmal das Beispiel im Abschnitt »Die Anwendung schließen« von Tag 2 an.

Ein Menü hinzufügen und anpassen

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.

Im Dialogfeld Menübefehl Eigenschaften legen Sie den Text fest, den der Benutzer in der Menüleiste bei laufender Anwendung sieht. Da das Kontrollkästchen Popup eingeschaltet ist (per Vorgabe bei allen Menüeinträgen auf der obersten Ebene der Menüleiste), löst dieses Menüelement keine Funktionen in der Anwendung aus, so daß man auch keine Objekt-ID zuweisen muß.

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.

Dieses Mal legen Sie im Dialogfeld Menübefehl Eigenschaften nicht nur den Text fest, den der Benutzer sieht, wenn er das Menü über die Menüleiste öffnet, sondern auch die Objekt-ID, über die die Zuordnung der Behandlungsroutinen zu den Menüereignissen erfolgt.

Hinweis zur deutschen Übersetzung

Als Objekt-ID können Sie beliebige Bezeichnungen eintragen - zum Beispiel auch IDM_DATEI_HELLO statt IDM_FILE_HELLO. Wenn Sie Funktionen hinzufügen, die sich auf die Objekt-IDs beziehen, greift Visual C++ auf diese Bezeichnungen zurück, um einen Namen für die Funktion vorzugeben. Bei deutschen Bezeichnern, die keine Umlaute enthalten, läuft alles problemlos ab. Wenn aber wie beim Menübefehl Öffnen Umlaute im Bezeichner enthalten sind, treten Konflikte bei der automatischen Vergabe der Funktionsnamen auf. Da die Standardbefehle für Menüs (wie IDM_ABOUTBOX) ohnehin in Englisch vorliegen, verwenden wir in diesem Buch für Objekt-IDs die englischen Bezeichnungen. Auf die Titel von Menübefehlen wirken sich die Umlaute dagegen nicht nachteilig aus und können sogar als Zugriffstasten spezifiziert werden.

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.

Das Menü mit dem Dialogfeld verbinden

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

Menübefehle mit Funktionalität ausstatten

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

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: }

Die Nachricht COMMAND erhält das Anwendungsfenster, wenn ein Menübefehl ausgewählt wird. Wenn man eine Funktion für diese Nachricht vorsieht, hat das die gleiche Wirkung, wie eine Funktion zur Auswahl des Menübefehls.

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

Kontextmenüs erstellen

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.

Ein Kontextmenü kann man über zwei verschiedene Nachrichten für Behandlungsfunktionen auslösen. Es liegt zunächst auf der Hand, die Nachricht WM_RBUTTONDOWN zu verwenden. Windows sendet diese Nachricht, wenn der Benutzer mit der rechten Maustaste klickt. Weiterhin kann man (und sollte man) die Nachricht WM_CONTEXTMENU verwenden, die speziell dafür vorgesehen ist, ein Kontextmenü zu initiieren. Dieses Ereignis entsteht bei einer Reihe von Benutzeraktionen: eine davon ist das Loslassen der rechten Maustaste, eine andere das Drücken der Kontextmenütaste auf einer der neueren Windows-Tastaturen.

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

Ein Menü mit Zugriffstasten

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.

Zusammenfassung

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.

Fragen und Antworten

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

Workshop

Kontrollfragen

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?

Übungen

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.



vorheriges KapitelInhaltsverzeichnisStichwortverzeichnisFeedbackKapitelanfangnächstes Kapitel


Ein Imprint des Markt&Technik Buch- und Software-Verlag GmbH.
Elektronische Fassung des Titels: Visual C++ 6 in 21 Tagen, ISBN: 3-8272-2035-1