von Martin Steigerwald
|
ARexx gilt als Skriptsprache zum Automatisieren wiederholter Vorgänge.
ARexx ermöglicht ARexx-fähige Anwendungen zu steuern, um das gewünschte
Ergebnis zu erreichen. So kann ein Skript YAM verwenden, um automatisch eine
E-Mail zu versenden, oder ein Bildverarbeitungsprogramm, um eine Bilderserie
zu skalieren.
Ein ARexx-Skript kann sich aber auch selbst dem Benutzer als Anwendung mit vollständiger
grafischer Oberfläche präsentieren. ARexx bietet von Haus aus keine
Unterstützung für grafische Oberflächen. Allerdings gibt es eine
ganze Reihe von ARexx-Funktions-Bibliotheken im Internet, die Funktionen zum
Erstellen grafischer Oberflächen bieten (s. [1]).
Wir verwenden für unser Beispiel die Bibliothek »RxMUI« von
Alfonso Ranieri. RxMUI erlaubt es, mit ARexx komplette MUI-Anwendungen zu programmieren.
»MUIRexx« von Russell Leighton bietet ebenfalls die Möglichkeit,
MUI-Oberflächen von ARexx aus anzusteuern, verwendet dabei aber nicht den
Ansatz einer typischen Funktionsbibliothek. Stattdessen wird MUIRexx als Programm
gestartet. Dann lässt es sich über den ARexx-Port von einem ARexx-Skript
ansprechen. Mit »RxMUI« erschien es leichter, vom ARexx-Skript die
Oberfläche abzufragen, etwa, ob ein bestimmter Schalter gedrückt wurde.
RxMUI hat eine ausführliche, allerdings englischsprachige Anleitung (s.
»So viele Klassen«).
»MultiTool« ist eine kleine Anwendung, die es erleichtert,
mehrere Dateien in einem Rutsch mit einem bestimmten Programm verarbeiten zu
lassen (s. »MultiTool in Aktion«). Dabei lassen sich häufig
definierte Aktionen vordefinieren. Drei Beispiele sind bereits definiert: Das
Entpacken eines Archives mit »xadUnFile« aus dem xadmaster-Paket,
das Entpacken einer Datei mit »xfdDecrunch« aus dem xfdmaster-Paket
und das Entfernen eines MacBinary-Headers mit »macwhack«. Der Anwender
kann mit einem Schalter (Cycle-Gadget) einfach eine der drei Aktionen auswählen
oder selbst einen Befehl und dessen Argumente in die entsprechenden Texteingabefelder
eintragen. Dann gibt man ein Quell- und ein Zielverzeichnis an und klickt auf
»Ausführen«, um alle Files aus dem Quellverzeichnis mit dem
gewünschten Befehl zu verarbeiten.
|
»MultiTool« ist dabei nur ein erster Ansatz, der sich vielfältig ausbauen lässt. So ist es zur Zeit noch nicht möglich, die vordefinierten Aktionen mit einer grafischen Oberfläche zu ändern. Auch wird die Verarbeitung der einzelnen Dateien nur in einem Shell-Fenster angezeigt. Eine grafische Fortschrittsanzeige gibt es nicht. Es bleibt also viel Raum, MultiTool nach eigenen Gutdünken zu erweitern.
Objektorientiert
Das bekannte Oberflächen-System »Magic User Interface«
(kurz: »MUI«) von Stefan Stuntz ist objektorientiert aufgebaut.
Eine Anwendung setzt sich demnach aus mehreren Objekten zusammen. Diese Objekte
haben Eigenschaften, die man verändern kann, und Methoden, die man ausführen
kann.
Üblicherweise ist dies mindestens ein Anwendungs-Objekt und ein Fenster-Objekt. Das Fenster enthält in der Regel einige vom Benutzer ansteuerbare Oberflächen-Elemente wie Schalter oder Texteingabefelder. Unser Beispiel hat zusätzlich ein Pull-Down-Menü, das aus zwei Objekten besteht: Dem »menustrip«-Objekt, also der Menüleiste, in die ein »menu«-Objekt, ein Menü namens »Projekt« eingehängt wird. Dieses Menü wird direkt im Anwendungs-Objekt als Menü der Anwendung eingefügt. MUI ordnet die Oberflächen-Elemente dynamisch an und berücksichtigt dabei die verwendete Schrift ebenso wie die Fenstergröße, die der Benutzer festlegt.
Um das zu ermöglichen, werden die Positionen und Größen von Oberflächen-Elementen nicht absolut in Pixel angegeben. Stattdessen wird die Anordnung der Elemente festgelegt, indem deren Positionen zueinander definiert werden. So definiert unsere Beispiel-Anwendungen ein horizontales Objekt mit zwei Spalten. In der ersten Spalte ist jeweils ein Label, das beschreibt, worum es beim Schalter oder Eingabefeld in der zweiten Spalte geht (s. Kasten »Struktur der MUI-Anwendung»). Die Struktur von MultiTool als MUI-Anwendung ergibt sich aus dieser Objekt-Hierarchie (s. Kasten »Struktur der MUI-Anwendung«). Mit Hilfe von Benachrichtigungen (Notifies) wird die Abfrageschleife von MultiTool über Ereignisse der grafischen Oberfläche informiert. Die Ablauf-Struktur von MultiTool ergibt sich aus dem Aufbau des ARexx-Skripts: Zunächst werden im Programm einige Variablen definiert, zwei Funktionsbibliotheken geöffnet, »RxMUI« und »rexxsupport«, und die vordefinierten Aktionen bereitgestellt.
Dann wird die Prozedur »GUI« aufgerufen, um die grafische
Benutzer-Oberfläche aufzubauen (engl. GUI = Graphical User Interface).
Ist dies erfolgreich, wird die Prozedur »Abfragen« aufgerufen, um
auf Ereignisse zu warten: Wird »Beenden« gewählt, wird MultiTool
einfach beendet. Die MUI-Oberfläche wird dabei automatisch von RxMUI und
MUI geschlossen und freigegeben.
|
Wählt der Benutzer eine andere Aktion wird die Prozedur »Aktion_aktualisieren«
aufgerufen. Diese setzt den Inhalt der beiden Eingabefelder »Befehl«
und »Argumente« auf die für die vordefinierte Aktion passenden
Inhalte, z.B. »xadUnFile« mit den passenden Parametern für
das Entpacken eines Archivs. Dabei wird mit Platzhaltern gearbeitet, die später
durch Namen der Quell- und Zieldatei oder des Quell- und Zielverzeichnisses
ersetzt werden: »%qz« steht für das Quellverzeichnis, »%qd"
für die Quelldatei, »%zz« steht für das Zielverzeichnis
und »%zd« für die Zieldatei.
Wählt der Benutzer »Ausführen« wird die Prozedur »Ausfuehren«
aufgerufen. Diese holt sich Quell- und Zielverzeichnis sowie Befehl und Argumente
aus der MUI-Oberfläche. Sie prüft ob Quell- und Zielverzeichnis angegeben
sind und ob es zwei unterschiedliche Verzeichnisse sind.
Ist das der Fall, liest die Prozedur über showdir() von der
»rexxsupport.library« eine Liste aller Dateien im Quellverzeichnis.
Nun wird jede einzelne Quelldatei in einer Schleife abgearbeitet: Die Platzhalter
bei den Argumenten werden durch ihre Inhalte ersetzt und dann wird der Befehl
mit den Argumenten ausgeführt.
Der ausführlich dokumentierte Quelltext von MultiTool ist über 300
Zeilen lang. Sie finden MultiTool auf der Amiga-Magazin-CD, auf den Magazin-Internetseiten
und im AmiNet. Wir besprechen zwei wesentliche Ausschnitte aus dem Quelltext:
die Prozedur »GUI«, die die MUI-Oberfläche erstellt, und die
Prozedur »Abfragen«, die die Oberfläche abfragt.
|
Der Prozedur werden vom Hauptprogramm einige Parameter übergeben
(Listing 1, Zeile 10). »aktionen« ist eine durch "|"
getrennte Liste aller Aktionen wie z.B. »Datei entpachen«. Diese
wird für den Auswahlschalter »Aktionen« gebraucht. »aktion.befehl«
und »aktion.argumente« beinhalten die Vorgabewerte für die
entsprechenden Texteingabefelder, beim Programmstart die Werte der ersten vordefinierten
Aktion. »app. version« und »app.copyright« enthalten
Versions- und Copyright-Informationen über MultiTool.
Zuerst wird ein Anwendungs-Objekt »anw« definiert (Zeile 12-18).
Für dieses werden einige Informationen gesetzt: Der Name der Anwendung,
die Versionsinfo, das Copyright usw. Die Versionsinformation und die Beschreibung
können Sie sehen, wenn Sie MultiTool starten und dann im »Exchange«-Programm
den Eintrag für MultiTool anwählen. MultiTool ist wie die meisten
MUI-Anwendungen ein vollständiges Commodity (s. »Auch
ein Commodity«)! In Zeile 20 bis 30 wird für die MUI-Anwendung
ein Pull-Down-Menü definiert. Dieses wird direkt in die Menüleiste
»anw.menustrip« des Anwendungsobjekts eingehängt. Das Menü
heißt »Projekt« und enthält die Funktionen »Ausführen...«,
»Ikonifizieren«, »Über...«, »Beenden«.
Schließlich wird noch angegeben, welches das Hauptfenster der Anwendung
sein soll (»anw.
SubWindow«).
RxMUI arbeitet bei der Definition von MUI-Objekten mit ARexx-Stammvariablen.
Eine Stammvariable wie »anw« enthält danach Untereinträge
wie «anw.description« für die Beschreibung oder »anw.menustrip«
für die Menüleiste. Kann ein Objekt mehrere Unterobjekte enthalten,
dann werden diese fortlaufend durchnummeriert, z.B. »gruppe.0« für
das erste GUI-Element oder »gruppe.1« für das zweite GUI-Element.
Als nächstes wird nun das Fenster definiert (Zeile 35-39). Als Hauptfenster
bekommt es die ID »MAIN«. Sie können noch weitere Fenster definieren,
z.B. als »anw.SubWindow.1« oder »anw.SubWindow.2« Beispiel
ein Fenster, um beim Ausführen der definierten Aktion auf alle Dateien
des Quellverzeichnisses den Fortschritt anzuzeigen, oder ein Einstellungsfenster
für die vordefinierten Aktionen. Das Fenster hat den Titel »MultiTool«
und enthält die Gruppe »gruppe«.
In dieser Gruppe sind nun die einzelnen Schalter definiert (Zeile 41-43). Diese
sind alle Kinder der Gruppe »gruppe«. Man könnte Sie auch als
»gruppe.0«, »gruppe.1« usw. schreiben. Um nicht bei
jeder Änderung die einzelnen GUI-Elemente neu durchnummerieren zu müssen,
empfielt es sich, die RxMUI-Funktion »child« zu verwenden, die das
GUI-Element einfach hinten dranhängt. Zu jedem Schalter bis auf den »Ausführen«-Schalter
gehört ein Label, das dessen Funktion beschreibt. Label und Schalter sind
nebeneinander angeordnet. Dies lässt sich am besten mit einer zweispaltigen
horizontalen Gruppe erreichen. Das ist so ähnlich wie eine HTML-Tabelle,
das Layout der einzelnen Elemente übernimmt MUI.
Nun werden die einzelnen Label und Schalter definiert: Der Auswahl-Schalter
Aktionen, die Eingabefelder Befehl und Argumente, die Eingabefelder mit Dateiauswahl-Schalter
»Quellverzeichnis« und »Zielverzeichnis«, und zuletzt
der Schalter »Ausführen«. Dieser hat kein Label, stattdessen
wird mit »HSpace()« einfach ein horizontaler Platzhalter verwenden.
|
Bei den Texteingabefeldern mit Dateiauswahl-Schalter, der beim
Anklicken ein ASL-Dateiauswahl-Dialogfenster öffnet, handelt es sich um
die so genannten »popasl«-Objekte. Diese werden einzeln definiert.
Damit ist die MUI-Anwendung fertig definiert und alle deren Bestandteile. Mit
der Funktion NewObj("application", "anw") wird nun das Anwendungsobjekt
samt aller Unter-Objekte eingerichtet (Zeile 77-78).
Doch wie erfährt das Programm von wesentlichen Ereignissen? In MUI wird
das gewöhnlich durch Benachrichtungen (Notifies) geregelt. Davon definiert
MultiTool auch einige (Zeile 80-103). Bei einer Benachrichtung verbindet man
zwei MUI-Objekte miteinander, in der Regel das Objekt, das abgefragt werden
soll, mit dem Anwendungs-Objekt, dem die Information mitgeteilt werden soll.
So besagt diese Benachrichtung, dass der Anwendung die fest definierte ID »quit«
mitgeteilt werden soll, wenn das Fenster »fenster« geschlossen wird
(Zeile 80-82).
res=Notify("fenster","closerequest",1,"anw","ReturnID","quit")
Das heißt, dass beim Fenster »fenster« die Eigenschaft
»closerequest« (Schließaufforderung) abgefragt und wenn dieses
Ereignis eingetreten ist, die Methode »ReturnID« mit dem Parameter
»quit« aufgerufen wird. »ReturnID« wird für festgelegte
MUI-Ereignisse verwendet. Auch für den Menü-Eintrag »Projekt/Beenden«
wird diese Methode mit dem Parameter »quit« festgelegt (s.Zeile
84-86).
Für eigene Ereignisse verwenden Sie stattdessen »Return« und
eine eindeutige Textkennung für das Ereignis. Für den Menü-Eintrag
»Projekt/Ausführen« (»m_ausfuehren«) und den Schalter
»Ausführen« (»ausfuehren«) wird beidesmal die Textkennung
»ausfuehren« an das Anwendungsobjekt weitergegeben. Wenn mit dem
Auswahlschalter »Aktion« eine andere Aktion gewählt wird, wird
»aktion« zurückgegeben. Diese Ereignisse werden dann später
vom ARexx-Skript abgefragt.
|
||||||||||||||||||||||
Zusätzlich gibt es noch zwei Benachrichtungen, die von RxMUI
bzw. MUI intern gehandhabt werden: »Projekt/Über...« (»m_ueber«)
verwendet die Methode »About« vom RxMUI-Anwendungsobjekt »anw»,
um ein kleines Infofenster anzuzeigen. »Projekt/Ikonifizieren...«
(»m.ikonifizieren«) setzt das Anwendungs-Objekt »anw«
auf ikonfiziert. Den Rest erledigt MUI. Die Ikonfizierbarkeit von MultiTool
ist schon inklusive.
Zuletzt wird das Hauptfenster der Anwendung geöffnet, damit der Benutzer
auch etwas zu sehen bekommt und Eingaben machen kann (Zeile 109-110).
Die RxMUI-Funktion »NewHandle« handhabt dies. Ihr übergibt man als Parameter das Anwendungsobjekt und eine Stamm-Variable, die das so genannte »Handle« beinhalten soll sowie bei Bedarf eine Maske von Signalen auf die zusätzlich geprüft werden soll. MultiTool übergibt »anw« als Anwedungsobjekt, »h« als Handle und keine Signale (Zeile 8).
In die »Handle«-Stammvariable schreibt die Funktion die Information hinein, ob sich etwas ereignet (»h.EventFlag«) hat und was sich ereignet hat (»h.Event« = Ereignis) und außerdem noch, welche Benutzer-Signale empfangen wurden (»h.Signals«). Als zusätzliches Signal könnte z.B. nach der Tastenkombination »Ctrl-C« geprüft werden. Diese Funktion ist in MultiTool nicht enthalten.
Für MultiTool interessant ist das Ereignis. Die Funktion NewHandle wartet bis ein solches Auftritt oder ein Signal empfangen wurde. Das Skript fragt ab, ob »h. EventFlag« gesetzt wurde. Wenn ja, ist ein Ereignis aufgetreten. Je nach Ereignis in »h.Event« wird nun das Programm beendet, die eingestellte Aktion ausgeführt oder aber die beiden Texteingabefelder »Befehl« und »Argumente« aktualisiert, wenn im Auswahl-Schalter »Aktion« eine andere Aktion gewählt wurde.
Literatur:
| [1] | Die ganze Vielfalt, Martin Steigerwald, Amiga Magazin, 8/2002 |
| [2] | Schritt für Schritt, Martin Steigerwald, Amiga Magazin 11/2002 |
lb
© 2003 All Rights Reserved. Alle Rechte vorbehalten Franzis'
Verlag GmbH Kommentare, Fragen, Korrekturen und Kritik bitte an Webmaster
AMIGA schicken.
Zuletzt aktualisiert am 23. 1. 2003.