Hauptmenüs, Kontextmenüs und Standarddialoge
Veröffentlicht: Dezember 2009
Von Richard Kaiser und Alexander Kaiser
Im Folgenden wird gezeigt, wie man Menüs und Kontextmenüs erzeugen und Standarddialoge (z.B. zum Öffnen von Dateien) anzeigen kann.
Dieser Artikel ist ein kurzer Auszug aus dem Buch „C++ mit Microsoft Visual C++ 2008“ (ISBN 978-3540238690), das C++ mitsamt den Visual C++-Erweiterungen (C++/CLI) umfassend darstellt. Der Verfasser dieses Buches ist ein erfahrener C++- und C#-Trainer, der auch für Firmenschulungen zur Verfügung steht.
Hauptmenüs und der Menüdesigner
Unter Windows werden einem Anwender die verfügbaren Befehle und Optionen oft in Form von Menüs angeboten. Ein Menü wird nach dem Anklicken eines Eintrags in der Menüleiste (unterhalb der Titelzeile des Programms, typische Einträge „Datei“, „Bearbeiten“ usw.) aufgeklappt und enthält Menüeinträge wie z.B. „Neu“, „Öffnen“ usw.
Die Komponente MenuStrip (Toolbox |Menüs & Symbolleisten) stellt ein Hauptmenü zur Verfügung. Sie ersetzt und erweitert die Funktionalität der MainMenu Komponente aus älteren Versionen von Visual Studio.
Ein MenuStrip wird wie jede andere Komponente ausgewählt, d.h. zuerst in der Toolbox angeklickt und dann durch einen Klick auf das Formular gesetzt. Dabei ist die Position auf dem Formular ohne Bedeutung: Zur Laufzeit wird das Menü immer unterhalb der Titelzeile des Formulars platziert und zur Entwurfszeit in einem Bereich unterhalb des Formulars.
Durch einen Klick auf menuStrip1 wird dann der Menüdesigner aufgerufen, mit dem man das Menü gestalten kann:
Dazu trägt man in die mit „Hier eingeben“ gekennzeichneten Felder die Menüeinträge so ein, wie man sie im laufenden Programm haben möchte. Mit den Pfeiltasten oder der Maus kann man die Menüeinträge auch noch nachträglich ändern.
Die folgenden Optionen werden in vielen Menüs verwendet:
- Durch das Zeichen & („kaufmännisches Und“, Umschalt+6) vor einem Buchstaben der Eigenschaft Text wird dieser Buchstabe zu einer Zugriffstaste. Er wird dann im Menü unterstrichen angezeigt.
- Über die Eigenschaft ShortcutKeys kann man im Eigenschaftenfenster Tastenkürzel definieren, die eine Menüoption auch ohne die Alt-Taste aktivieren.
- Der Text „-“ wird im Menü als Trennliniedargestellt.
· Verschachtelte Untermenüs erhält man durch Menüeinträge rechts von einem Menüeintrag.
Durch einen Doppelklick auf einen Menüeintrag im Menüdesigner (bzw. auf das Ereignis Click des Menüeintrags im Eigenschaftenfenster) erzeugt Visual Studio die Ereignisbehandlungsroutine für das Ereignis Click dieses Menüeintrags. Diese Funktion wird zur Laufzeit beim Anklicken dieses Eintrags aufgerufen:
private: System::Void speichernunterToolStripMenuItem_Click
(System::Object^ sender, System::EventArgs^ e)
{
}
Zwischen die geschweiften Klammern schreibt man dann die Anweisungen, die beim Anklicken des Menüeintrags ausgeführt werden sollen. Das sind oft Aufrufe von Standarddialogen, die anschließend vorgestellt werden.
Zwei weitere Möglichkeiten, die manchmal nützlich sind:
- Über das Kontextmenü eines Menüeintrags im Menüdesigner kann man dem Menüeintrag ein Bild zuweisen („Bild festlegen“).
- Über den Eintrag „Standardelemente einfügen“ des Kontextmenüs der Menüleiste bzw. von menuStrip1 kann man die üblichen Menüeinträge (Datei, Bearbeiten usw.) einschließlich Bildern, ShortCuts usw. einfügen.
Kontextmenüs
Ein Kontextmenü ist ein Menü, das einem Steuerelement zugeordnet ist und angezeigt wird, wenn man das Steuerelement mit der rechten Maustaste anklickt. Kontextmenüs werden auch als „lokale Menüs“ bezeichnet.
Kontextmenüs werden über die Komponente ContextMenuStrip (Toolbox|Menüs& Symbolleisten) zur Verfügung gestellt. Sie ersetzt und erweitert die Funktionalität der ContextMenu Komponente aus älteren Versionen von Visual Studio. Ein ContextMenuStrip wird wie ein MenuStrip auf ein Formular gesetzt und mit dem Menüdesigner gestaltet.
Die Zuordnung eines Kontextmenüs zu dem Steuerelement, bei dem es angezeigt werden soll, erfolgt über die Eigenschaft ContextMenuStrip des Steuerelements. Jedes Steuerelement, dem ein Kontextmenü zugeordnet werden kann, hat diese Eigenschaft. Die Zuordnung kann im Eigenschaftenfenster erfolgen: Im Pulldown-Menü der Eigenschaft ContextMenuStrip kann man alle bisher auf das Formular gesetzten Kontextmenüs auswählen. In der Abbildung
wird also der Textbox textBox1 das Kontextmenü contextMenuStrip1 zugeordnet.
Kontextmenüs bieten oft dieselben Funktionen wie Hauptmenüs an. Dann muss für das Ereignis im Kontextmenü aber keine Ereignisbehandlungsroutine mit denselben Anweisungen geschrieben werden. Stattdessen wählt man besser im Eigenschaftenfenster (Ansicht Ereignisse) die Ereignisbehandlungsroutine des Hauptmenüs aus. Hier werden alle bisher definierten Ereignisbehandlungsroutinen angeboten, die zu einem Ereignis passen.
Beispiel: Wenn ein Menü beim Anklicken einer Option „Neu“ eine Ereignisbehandlungsroutine neuToolStripMenuItem_Click aufruft, kann man diese im Eigenschaftenfenster des Kontextmenüs beim Ereignis Click auswählen:
Standarddialoge
Die Register Dialogfelder und Drucken der Toolbox enthalten Komponenten für die Standarddialoge unter Windows:
Diese Dialoge werden von Windows zur Verfügung gestellt, damit häufig wiederkehrende Aufgaben wie die Eingabe eines Dateinamens in verschiedenen Anwendungen auf dieselbe Art erfolgen können.
Beispiel Durch einen OpenFileDialog erhält man das üblicherweise zum Öffnen von Dateien verwendete Dialogfenster:
...
Ein OpenFileDialog wird im Unterschied zu vielen anderen Steuerelementen (z.B. Buttons) nicht automatisch nach dem Start des Programms angezeigt, sondern erst durch einen Aufruf seiner Methode ShowDialog:
DialogResultShowDialog();
Beispiel: Einen OpenFileDialog ruft man meist in der Ereignisbehandlungsroutine zur Menüoption Datei|Öffnen auf. Die folgenden Anweisungen setzen voraus, dass zuvor ein OpenFileDialog aus der Toolbox auf das Formular gezogen wurde:
private: System::Void öffnenToolStripMenuItem_Click
(System::Object^ sender, System::EventArgs^ e)
{
openFileDialog1->ShowDialog();
}
Beim Anklicken des Öffnen Buttons eines OpenFileDialog tritt das Ereignis FileOk ein. Die Ereignisbehandlungsroutine für dieses Ereignis erhält man durch einen Doppelklick auf den Dialog im Formulardesigner. In diese Funktion nimmt man dann die Anweisungen auf, die beim Anklicken des Öffnen Buttons ausgeführt werden sollen. Die Benutzereingaben im OpenFileDialog stehen als Werte von Eigenschaften zur Verfügung. Der ausgewählte Dateiname ist der Wert der Eigenschaft
property String^ FileName
Beispiel: In der folgenden FileOk-Funktion wird der Eigenschaft Text einer TextBox der Inhalt der Datei (Dateiname openFileDialog1->FileName) zugewiesen, die in dem OpenFileDialog ausgewählt wurde:
private: System::Void openFileDialog1_FileOk(
System::Object^ sender,
System::ComponentModel::CancelEventArgs^ e)
{ // ReadAllText: gibt die Datei mit dem als Parameter
// übergebenen Namen als String zurück
textBox1->Text=IO::File::ReadAllText(openFileDialog1->FileName);
}
Die Standarddialoge können vor ihrem Aufruf über zahlreiche Eigenschaften konfiguriert werden. Bei einem Open- und SaveFileDialog sind das unter anderem:
property String^ Filter // Maske für Dateinamen
property String^ InitialDirectory // das beim Aufruf angezeigte Verzeichnis
Bei der Eigenschaft Filter gibt Filter für die angezeigten Dateien angeben. Jeder Filter besteht aus Text, der im Dialog nach „Dateityp“ angezeigt wird, einem senkrechten Strich „|“ (Alt Gr <) und einem oder mehreren Mustern für die Dateinamen (z.B. „*.txt“), die durch Semikolons „;“ getrennt werden. Mehrere Filter können getrennt durch senkrechte Striche „|“ angegeben werden. Diese können dann im Pulldown-Menü nach „Dateityp“ ausgewählt werden.
Bei einem SaveFileDialog kann man mit der Eigenschaft
property String^ DefaultExt// ohne einen Punkt „.“
eine Zeichenfolge festlegen, die automatisch an den Dateinamen angefügt wird.
Beispiel: Den OpenFileDialog vom Anfang dieses Abschnitts erhält man mit den folgenden Zuweisungen vor dem Aufruf von ShowDialog:
openFileDialog1->InitialDirectory=
"c:\\Projekt1\\Projekt1";
openFileDialog1->Filter="C++ Dateien|*.CPP;*.H";
Da das Zeichen „\“ in C++ bei Strings im Quelltext eine besondere Bedeutung hat (Escape-Sequenz), muss es doppelt angegeben werden. Anstelle von „\\“ ist bei Pfadangaben in Windows auch „/“ möglich.
Beispiel: Die nächsten beiden Pfadangaben sind gleichwertig:
openFileDialog1->InitialDirectory = "c:\\Projekt1\\Projekt1";
openFileDialog1->InitialDirectory = "c:/Projekt1/Projekt1";
Die Standarddialoge des Registers „Dialogfelder“ der Toolbox:
OpenFileDialog | Zeigt Dateien aus einem Verzeichnis an und ermöglicht, eine auszuwählen oder einzugeben (Eigenschaft FileName), die geöffnet werden soll. |
SaveFileDialog | Um den Namen auszuwählen oder einzugeben, unter dem eine Datei gespeichert werden soll. Viele gemeinsame Eigenschaften mit OpenFileDialog, z.B. FileName, InitialDirectory, Filter usw. |
FolderBrowserDialog | Ähnlich wie ein OpenFileDialog, zur Auswahl eines Verzeichnisses. Das ausgewählte Verzeichnis ist der Wert der Eigenschaft SelectedPath. |
FontDialog | Zeigt die verfügbaren Schriftarten und ihre Attribute an und ermöglicht, eine auszuwählen (Eigenschaft Font). |
ColorDialog | Zeigt die verfügbaren Farben an. Die hier ausgewählte Farbe ist der Wert der Eigenschaft Color. |
Alle diese Dialoge, wie auch die des Registers „Drucken“, werden wie ein OpenFileDialog durch den Aufruf der Methode
DialogResultShowDialog();
angezeigt. Der Rückgabewert ist DialogResult::Cancel, wenn der Dialog abgebrochen wurde (z.B. mit dem „Abbrechen“ Button oder der ESC-Taste), und andernfalls DialogResult::OK (z.B. mit dem Button „Öffnen“ oder der ENTER-Taste). Im letzteren Fall findet man die Benutzereingaben aus dem Dialogfenster in entsprechenden Eigenschaften des Dialogs.
Beispiel: Bei allen Dialogen (auch bei einem Open- oder SaveFileDialog) kann man durch die Abfrage des Rückgabewerts von ShowDialog prüfen, ob der Dialog mit Öffnen abgeschlossen wurde. Die Benutzereingaben werden nur nach einer Bestätigung des Dialogs verwendet.
private: System::Void öffnenToolStripMenuItem_Click
(System::Object^ sender, System::EventArgs^ e)
{
if (openFileDialog1->ShowDialog()==
System::Windows::Forms::DialogResult::OK)
{ // der Dialog wurde bestätigt
textBox1->Text=IO::File::ReadAllText(
openFileDialog1->FileName);
}
}
Hier muss leider der relativ umständliche Ausdruck System::Windows::Forms::DialogResult::OK verwendet werden, da der Ausdruck DialogResult::OK mit einem Element der Formularklasse in Konflikt kommt.
Die Funktion in diesem Beispiel zeigt ein universell verwendbares Programmschema für Dialog-Aufrufe und die Verwendung der Daten aus dem Dialog: Falls ein Dialog ein FileOk-Ereignis hat, ist die Verwendung dieses Ereignisses aber meist einfacher als eine solche Abfrage. Dann braucht man beim Anklicken einer Menüoption oder eines Symbols auf einer Symbolleiste nur noch ShowDialog aufrufen. Falls ein solcher Dialog an verschiedenen Stellen im Programm aufgerufen werden soll, ist damit sichergestellt, dass jedes Mal dieselben Anweisungen ausgeführt werden.
Zurück: Buttons und Ereignisse | Weiter: Windows Forms-Anwendungen mit Standard-C++