Session D-MENU
OO-Menüs: Und es geht doch
Peter Steinke
ProLib Software GmbH
Einleitung
Waren Sie in den
letzten Jahren schon mal Teilnehmer der DevCon? Dann kennen Sie vielleicht auch
die immer wiederkehrende Frage: Wird es diesmal einen objektorientierten
Berichts- oder Menügenerator geben? Eine Antwort kann auch ich Ihnen nicht
geben. Die Chancen sind jedoch schlecht, dass es in der nächsten Version von
Visual FoxPro große Veränderungen geben wird.......
In der Session
zeige ich Ihnen eine Möglichkeit, wie Sie (auch ohne auf die übernächste
Version warten zu müssen) die Menüs in VFP als Objekte in Ihrer Anwendung
einbinden können.
Getreu nach dem
Motto „Der Weg ist das Ziel“ zeige ich Ihnen nicht nur die Verwendung der
Klasse in einer Applikation, sondern auch die Entstehung der Klasse. Ich zeige
Ihnen meinen Weg, von der Analyse der Aufgabe über die Entwurf der Klasse bis
hin zu der Realisierung in Visual FoxPro.
Schritt 1: Ist Analyse und Aufgabenstellung
Analyse ist die Aufstellung aller Fakten in den
einfachsten Strukturen. Das Problem dabei besteht in der klaren Trennung
von Analyse und Programmierung.
Wie ist ein Menu aufgebaut?
In vielen Windowsanwendungen wird zwischen dem
Standardmenü und dem Shortcut- bzw. Rightclickmenü unterschieden. In der
Abbildung 1 und Abbildung 2 sehen Sie jeweils einen Vertreter.
Abbildung 1
Abbildung 2
Außer dem Layout beinhalten diese beiden Abbildungen
noch eine ganze Menge mehr Informationen. Es ist z.B. ist zu erkennen, dass ein
Menü aus verschiedenen Teilen besteht. Ausführliche Details zu den einzelnen
Teilen finden Sie auch in der Dokumentation.
Vorerst sind nur die folgenden Informationen
ausschlaggebend: Ein Standardmenü besteht aus einer Menüzeile. In dieser
Menüzeile sind die sogenannten „Pads“ eingebettet. Diese Pads können definierte
Aktionen auslösen. Im Normalfall aktiviert ein Pad ein Untermenü (auch Popup
genannt). Ein Popup setzt sich zusammen aus verschiedenen Zeilen. Eine solche
Zeile wird als „Bar“ bezeichnet. Ein Bar kann, wie ein Pad, verschiedene
Aktionen auslösen oder auch weitere Popups aktivieren. Abweichend dazu besteht
ein Shortcutmenü nur aus einem Popup und den dazu gehörenden Bars. Auch aus
diesen können noch weitere Popups aktiviert werden.
Zwei der gravierenden Unterschiede zwischen beiden
Menüarten sind die Positionierung und Verfügbarkeit. Die Menuzeile eines
Standardmenüs ist in den meisten Anwendungen immer sichtbar und befindet sich
am oberen Rand des Hauptfensters einer Anwendung. Ein Shortcutmenü hingegen
wird immer erst bei Bedarf an der aktuellen Mausposition aktiviert.
Welche Strukturen ergeben sich aus dem Aufbau?
Wie zuvor in der Dokumentation gelesen, besteht ein Menü
aus vier grundsätzlichen Elementen. Aber sind es denn wirklich vier
unterschiedliche Elemente?Betrachtet man einmal nur die Aufgaben der einzelnen
Elemente, ergeben sich zwei grundlegende Gruppen.
Der ersten Gruppe können die Menüzeile und das Popup
zugeordnet werden. Die Aufgabe beider Elemente besteht in der Anzeige und
Verwaltung von untergeordneten Elementen. Sie bilden also einen Container, in
der eine Sammlung vonElementen aus der zweiten Gruppe verwaltet werden.
Der zweiten Gruppe werden die untergeordneten Elemente
Pad und Bar zugeordnet. Die Aufgabe dieser beiden Elemente besteht im Ausführen
von Aktionen oder auch dem Aktivieren eines Popups. Weiterhin können die
Elemente in der zweiten Gruppe nicht ohne einen entsprechenden Container
existieren. Ein Pad kann nur in einer Menüzeile aktiviert werden, ein Bar kann
nur innerhalb eines Popups vorkommen.
Da es sich bei der ersten Gruppe um eine Sammlung
handelt, wird im folgenden Text die Bezeichnung „Menu - Collection“ verwendet.
Für die zweite Gruppe wird die Bezeichnung „Menu – Executer“ verwendet, da es
sich hierbei um ausführende Elemente handelt.
Welche Aufgaben sollen erfüllt werden?
Bei der Klärung dieser Frage ist es erforderlich, klar
zu unterscheiden zwischen „notwendig“ und „schön, wenn es funktionieren würde“.
Es ist nicht immer sinnvoll, alle Möglichkeiten vorzusehen. Gerade im ersten
Design ist es sinnvoll, sich auf das Wesentliche zu konzentrieren. Dadurch wird
verhindert, dass man schon frühzeitig die Übersicht verliert. Wurden im ersten
Design keine wesentlichen Fehler gemacht, dann sollte eine spätere Erweiterung
der Klasse problemlos möglich sein.
In der Tabelle sind die grundlegenden Aktionen eines
Menüs aufgelistet und den jeweiligen Elementen zugeordnet. In Klammer stehen
die Bezeichnungen, die im weiteren Text für die jeweilige Aktion verwendet
werden.
Beschreibung
der Aktion
|
Menu
|
Pad
|
Popup
|
Bar
|
---|
Erstellen und Löschen ( Create & Remove) von Elementen aus dem Menüsystem.
|
Ja
|
Ja
|
Ja
|
Ja
|
Anzeigen und Verstecken ( Show & Hide ) von Elementen
|
Ja
|
Ja
|
Ja
|
Ja
|
Auslösen von Ereignissen, wenn ein Element in dem Menü aktiviert bzw.
deaktiviert ( Activate & Deactivate ) wurde.
|
Ja
|
Ja
|
Ja
|
Ja
|
Hinzufügen und Entfernen von einzelnen untergeordneten Elementen ( Add &
Remove )
|
Ja
|
|
Ja
|
|
Ausführen von Aktionen ( Click )
|
|
Ja
|
|
Ja
|
Schritt 2: Mögliche Lösungswege
Alles in eine Klasse
Ziel dieser Klasse ist es, das komplette Menü zu
kapseln; nicht aber die einzelnen Elemente eines Menüs. Um auf die einzelnen
Elemente in einem Menü zugreifen zu können, werden verschiedene Methoden zur
Verfügung gestellt. Diese Methoden sind schwer einer klaren Struktur
zuzuordnen. Weiterhin entstehen recht schnell Methoden mit einer recht
komplexen Funktionalität. Die spätere Erweiterung durch Vererbung und
anschließende Anpassung kann sich bei diesen Klassen als sehr umfangreich und
fehleranfällig herausstellen.
Define Class all4one as Custom
...
*===========================================================
* Entsprechend dem übergebenen Parameter, wird
* das benötigte Menüelement erstellt
*===========================================================
Function Create( tcWhat)
Do Case
Case tcWhat = „CREATE_MENU“
*---------------------------------------------------------
* aktivieren des Systemmenüs
*---------------------------------------------------------
Set Sysmenu TO
Set Sysmenu AUTOMATIC
Case tcWhat =
„CREATE_PAD“
*---------------------------------------------------------
* erstellen eines Pads
*---------------------------------------------------------
Define Pad _msm_file Of _MSYSMENU Prompt "\<Datei"
Case tcWhat = „CREATE_POPUP“
*---------------------------------------------------------
* erstellen eines Popups
*---------------------------------------------------------
Define Popup PopFile
Case tcWhat = „CREATE_POPUP“
*---------------------------------------------------------
* erstellen eines Bar’s
*---------------------------------------------------------
Define _mfi_open Of PopFile Prompt „Öffnen“
EndCase
Return
...
EndDefine
|