GFA-Programmierung mit faceVALUE

Saubere GEM-Programme mit GFA-Basic? Dass das möglich ist, zeigen viele professionelle Anwendungen. Jedoch haben die meisten GFA-Programmierer den Aufwand bislang gescheut. Dank faceVALUE ist nun jeder in der Lage, GFA-Basic Programme nach den Regeln der modernen Programmierkunst zu erstellen, und das alles mit minimalem Aufwand. Wie es geht, zeigen wir Ihnen in dieser Artikelserie.

faceVALUE ist ein Applicationbuilder, also zu deutsch ein Programm-Erzeuger. Die Vorarbeit, die Sie selbst verrichten müssen, findet im Resource Construction Set (RCS) statt. Hier entwerfen Sie Ihre Menüs und Dialoge, speichern sie in einer Resourcedatei und laden diese dann in faceVALUE ein. Wenn Ihr Programm außer Menüs und Dialogen auch Fenster haben soll, sind hier noch Einstellungen für die Fensterverwaltung zu machen.

Außerdem können Sie festlegen, welche besonderen Prozeduren in Ihr Programm eingebunden werden sollen.

Ihr Programm kann durch faceVALUE zum Beispiel über GEM Klemmbrett-Unterstützung, Drag und Drop, Selectric Dateiauswahl, IMGs laden & speichern, Offscreen Bitmaps, animierte Mauszeiger, GDOS-Fonts, XFSL Fontselektor-Unterstützung und Image Popups verfügen. In einem extra Dialog kann festgelegt werden, welche Auflösung Ihr Programm benötigt, wieviel Farben erlaubt sind, ob es ein GDOS benötigt und ob es als Programm und/oder Accessory läuft.

Nachdem alles wie gewünscht eingestellt ist, erzeugt faceVALUE eine LST-Datei für GFA-Basic. Es analysiert dazu die Resourcedatei und baut daraus ein komplettes, lauffähiges Programmgerüst. Von all den Prozeduren müssen uns zum Glück nur wenige interessieren. Zunächst ist es nur die Prozedur user_rsc_interact(), das Verbindungsstück Ihres Programms mit der automatisch ablaufenden "faceVALUE Engine".

Das erste Programm

Wir beginnen ganz klein und erzeugen ein Programm mit einer Menüzeile: Laden Sie MINIMUM.RSC von der faceVALUE Diskette in Ihr RCS und passen Sie den Inhalt der Dialoge SYSTEM und FVT_ALST an. Im Dialog SYSTEM tragen Sie z.B. Ihren Namen und den Namen Ihres Programms ein.

Die Strings in FVT_ALST können Sie auf Deutsch übersetzen. Wenn Sie dies einmal gemacht haben, können Sie die RSC-Datei abspeichern, um Sie in allen späteren Programmen als Ausgangspunkt zu benutzen.

Nun ist der Baum MENÜ zu ändern, so dass er z.B. unter dem Punkt "faceVALUE" den Eintrag "Über mich..." und unter dem Punkt "Datei" den Eintrag "Beenden" hat. In der RSC-Datei MINIMUM ist beim Eintrag "Beenden" standardmäßig der Extended State 9 gesetzt. Dieser erweiterte Status sagt faceVALUE, dass beim Anklicken dieses Menüeintrags das Programm beendet werden soll.

Wenn Sie in allen Ihren Programmen diesen Extended State setzen, brauchen Sie sich nicht mehr darum zu kümmern, wie Ihr Programm über das Menü verlassen werden kann - es geht vollautomatisch.

Alle Bäume und Objekte haben laufende Nummern. Durch das Vergeben von Namen können später im Programm alle Bäume und Objekte auch nach größeren Umstellungen in der RSC-Datei identifiziert werden. Vergessen Sie daher nie, den Menüeinträgen (wie auch später allen Dialogbuttons), die im Programm abgefragt werden sollen, Namen zu geben. Nur dann können sie die Objekte später im Programm ansprechen. Verwenden Sie in diesem Beispiel die Namen "menuabou" und "menuquit" für die Menüeinträge "Über mich..." und "Beenden".

Speichern Sie die RSC-Datei unter TEST_1.RSC ab, starten Sie faceVALUE und laden Sie die RSC-Datei. Im Hauptdialog brauchen Sie nicht viel zu verändern. Sie können unter "Menü entry:" den Titel "Beispiel 1" eintragen.

Wählen Sie noch 'program and accessory', damit bestimmte Routinen, die wir später brauchen werden, mit eingebunden werden. Lassen Sie das LST-File erzeugen und mergen Sie es in den GFA-Basic-Interpreter ein. Nur noch die INLINE laden, und endlich können Sie das Programm starten.

faceVALUE hat das komplette Programmgerüst erzeugt, das Menü läuft bereits. Sie haben sicherlich bemerkt, dass Ihr Programm noch nicht auf das Anklicken der Menüeinträge reagiert. Als Ausnahme fällt der Menüpunkt "Beenden" auf, bei dem aber extra zu diesem Zweck das erweiterte Flag in der RSC-Datei gesetzt wurde.

faceVALUE konnte bei der Programm-generierung noch nicht vorraussehen, welche Schritte bei den verschiedenen Benutzeraktionen ausgeführt werden sollen. Hier sind Sie als Programmierer gefordert, und es stellt sich die Frage, wann Sie zum Zuge kommen.

Das faceVALUE-Konzept

Das Hauptprogramm wird nicht mehr von Ihnen geschrieben, sondern durch die faceVALUE-Engine (Engine: engl. Motor) ersetzt. Dies ist ein längst nicht so trivialer Umstand, als dass man sich nicht an ihn gewöhnen müsste. Nicht mehr Sie als Programmierer bestimmen, wann etwas passiert, sondern der Benutzer bestimmt es durch seine Aktionen. Die Engine nimmt Ihnen die wesentlichen Teile dieser Arbeit ab und kümmert sich um die Dinge, die bei allen Programme gleich behandelt werden: der Benutzer möchte Fenster verschieben, vergrößern, verkleinern, Popups öffnen usw. Bei allen anderen Problemen lässt die Engine den Programmierer ans Werk und springt die user-Proze-duren an. Das sind die Prozeduren, in denen Sie Hand anlegen sollten.

Werfen Sie einen Blick in die Prozedur user_rsc_interact (Listing 1). Diese Prozedur wird von der Engine angesprungen, wenn der Benutzer einen Menüpunkt oder ein Dialogobjekt angewählt hat. faceVALUE hat bereits SELECT-CASE-Verteiler für alle relevanten Bäume (unsere RSC-Datei enthielt nur den Menübaum) und deren Objekte angefertigt. Unter der Zeile 'CASE menuabou&' können Sie somit eintragen, was passieren soll, wenn der Eintrag "Über mich..." angeklickt wird.

Oder das andere Beispiel: Unter der Zeile 'CASE menuquit&' hat faceVALUE schon bei der Programmgenerierung zum Verlassen der Programms automatisch die Zeile exit_program!=TRUE eingefügt. Dies wurde wie oben beschrieben durch das Setzen des erweiterten Status '9' bewirkt. An dieser Stelle sei angemerkt, dass faceVALUE-Programme immer nur durch Setzen der globalen Variablen exit_programm! und nicht durch Befehle wie QUIT oder SYSTEM verlassen werden dürfen.

Unser Programm soll im nächsten Schritt auch auf das Anwählen des Menüpunktes 'Über mich...' reagieren. Möglich wäre eine simple Alertbox. Uns ist das ein wenig zu schlicht, daher gehen wir nochmal in das RCS-Programm und entwerfen eine Dialogbox PRGINFO, ähnlich der in Abbildung 1.

Geben Sie dem OK-Button den Namen "infook". Wenn Sie nun wieder eine LST-Datei erstellen (anschließendes INLINE Einladen nicht vergessen), enthält diese in der Prozedur user_rsc_interact() einen weiteren Eintrag prginfo& für diese Dialogbox und einen weiteren infook& für den OK-Button.

Um die Dialogbox auf den Bildschirm zu bringen, tragen Sie nun in der Zeile unter 'CASE menuabou&' den Funktionsaufruf @win_open_dialog() und unter der Zeile 'CASE infook&' den Aufruf @win_close() ein (siehe Listing 2). Der @win_open_dialog-Aufruf öffnet die Infobox als programmodalen Dialog.

Starten Sie ruhig das Programm, und probieren Sie den neuen Dialog einmal aus (Abbildung 2).

Zeitgemäße Fensterdialoge

Unter Multitaskingsystemen sind systemmodale Dialoge, wie Sie Ihnen vom GEM-Desktop her bekannt sind, wenig sinnvoll, da sie durch die Blockierung des Bildschirms das System praktisch lahmlegen. Die Lösung ist der Einsatz von Fensterdialogen. Das Menü, insbesondere die Accesories und die Fenster anderer Programme bleiben weiterhin anwählbar, so wie es der Infodialog zeigt.

Bei vielen Dialogen ist es sogar möglich, auch das eigene Programm nach dem Öffnen uneingeschränkt weiterlaufen zu lassen. Dann spricht man von unmodalen oder nonmodalen Dialogen. "Schwer zu programmieren" denken Sie? Mit faceVALUE weit gefehlt: Sie müssen als einziges den ersten Parameter von @win_open_dia-log() von 1 auf 2 setzen und schon haben Sie einen unmodalen Dialog. Die Funktion win_open_dialog() gibt beim Öffnen eines Dialogs das 'Fensterhandle', eine Nummer, die das Fenster des Dialoges eindeutig kennzeichnet, zurück. Dieses Handle merken wir uns in der Variable prgin-fo_dialog& und übergeben es in user_rsc_interact in dem CASE-Zweig für den OK-Button dieses Dialoges zum Schließen an die Prozedur @win_close(). Das Fenster kann daher durch Benutzung des OK-Buttons geschlossen werden. Sicher haben Sie bemerkt, dass faceVALUE den Fenstertitel des Dialoges dem Objekt mit der Nummer 1 entnommen hat. Dies klappt genau dann, wenn das erste Objekt eines Fensterdialoges vom Typ STRING ist.

Iconify inclusive

Ikonifizierung - also Ablegen von Fenstern als Symbole auf dem Desktop -ist ja bekanntlich ein heikles Thema. Nicht mit faceVALUE. In der RSC-Datei TREES.RSC auf der faceVALUE Diskette finden Sie einen Baum ICFYICON. Er enthält ein Iconify-Icon, das natürlich nach Ihren Bedürfnisen angepasst werden kann. Binden Sie diesen Baum in die RSC-Datei von TEST_1 ein und lassen Sie die Datei erneut durch faceVALUE laufen (und wieder gilt: INLINE laden nicht vergessen). Klappen Sie die Prozedur user_rsc_interact auf und ergänzen Sie die Befehle gemäß Listing 3. Der dritte Parameter von @win_open_dia-log() regelt das Iconify. Der Wert -l bedeutete, dass das Fenster vom Benutzer nicht iconifiziert werden kann. Ersetzen Sie diesen Parameter nun durch icfyicon&, und fertig.

Egal auf welchem System das Programm läuft, faceVALUE wählt selbständig die passende Iconifymethode. Dadurch ist Iconify unter MagiC und MultiTOS, mit ICFS und sogar auf SingleTOS möglich. Das Iconify wird automatisch durch die Engine durchgeführt, wenn die AES einen Iconify-Button in den Fenstern anbieten und der Benutzer diese anwählt. Außerdem ist das Iconify und 'Uniconify' jederzeit durch Nutzung der winjcc-nify-Prozeduren möglich. Jede RSC-Datei kann übrigens beliebig viele Bäume, mit Iconify-lcons enthalten, nur müssen alle Bäume natürlich verschiedene Namen haben.

Radiobuttons

Häufig werden in Dialogboxen Radiobuttons verwendet. In einem faceVALUE Programm ist die Verwendung dieses Buttontyps einfach. Zurück ins RCS-Programm: Ergänzen Sie in Ihrem letzten Beispiel unter dem Menüpunkt "Datei" einen Eintrag "Format..." unter dem Namen "menuform". Erstellen Sie eine neue Dialogbox mit dem Namen FORMAT (siehe Abbildung 3):

Als erstes Objekt (Objekt-Nummer 1) muss der Titel-String "Bitte wählen Sie ein Textformat" angelegt werden (ansonsten Abhilfe durch Neusortierung des Baums). Der Rahmen um die Buttons ist ebenfalls ein Objekt vom Typ Button, allerdings mit erweitertem Objekttyp 20. Der Rahmen darf natürlich nicht selektierbar sein. Der Text "im Button lautet in unserem Beispiel "Format" und wird im RCS leider noch wie bei einem normalen Button zentriert dargestellt und dadurch von den drei Radiobuttons verdeckt. faceVALUE stellt den Rahmen später so dar, wie Abbildung 4 erkennen lässt.

In diesen Rahmen ziehen Sie drei weitere selektierbare Buttons, bei denen das Flag 'radio' gesetzt und das Flag 'exit' (falls nötig) gelöscht werden müssen. Geben Sie nur dem ersten dieser Knöpfe einen Namen, z.B. 'formradi'. Wenn Sie in jedem Radiobutton noch den erweiterten Typ 18 setzen, werden runde Radiobuttons dargestellt (Abbildung 4).

Was jetzt noch fehlt, ist der OK-Knopf, ein Button mit den Flags 'selectable', 'exit' und 'default' wie im Infodialog. Durch den erweiterten Typ 18 karir, faceVALUE noch mehr: Die eckige Klammer '[' kann vor einen Shortcutbuchstaben gesetzt werden, der Button kann so über ALT + Buchstabe selektiert werden. Mit diesem Verfahren ist es auch möglich, normale Buttons mit Shortcuts auszustatten. Ändern Sie z.B. den Text des OK-Buttons in "[OK", und setzen Sie auch hier den erweiterten Typ auf 18. Die Dialogbox kann spater dann auch über ALT-0 verlassen werden.

In Listing 4 sehen Sie die Prozeduren user_var_init() und user_rsc_interact(), die mit allem nötigen Programmcodes für ein lauffähiges Programm aufgefüllt wurden.

Führen Sie vor dem Einsetzen der Programmschnipsel mit der neuen RSC-Datei wieder einen faceVALUE-Lauf durch. Der komplette Neulauf durch faceVALUE ist immer dann nötig, wenn neue Objekt- oder Baumtypen hinzukamen, da faceVALUE dann auch neue Quelltextzeilen zur Behandlung dieser Objekte und Bäume einfügen muss. Wenn keine neuen Typen hinzukamen, ist der Punkt 'Save as Update...' anwählbar, welcher nur den kleinen Teil des neuen Programmcodes generiert, der sich wirklich verändert hat (siehe faceVALUE-Handbuch).

In der Prozedur user_var_init() finden Sie die Variable formradi_var& wieder. Sie enthält (auch bei geschlossenem Dialog) die Nummer des Radiobuttons von den dreien, der gerade angewählt ist. Die Zeile in dieser Prozedur dient der Vorbelegung, kommentiert sind bereits die möglichen Werte. Z.B. steht 1 für den ersten Radiobutton "linksbündig", 2 steht für "zentriert" usw. Die Zustände lassen sich auf diese Weise einfach vorbelegen und abfragen. Ausprobieren!

Die Verwaltung von Checkboxen (ankreuzbaren Knöpfen) und Textobjekten ist genauso einfach. Ergänzen Sie im RCS-Prgramm einen Menüpunkt, um einen zweiten Dialog aufzurufen mit dem Namen "menuschr". Erstellen Sie eine Dialogbox wie in Abbildung 5 mit dem Namen SCHRIFT.

Setzen Sie dazu bei den Buttons den erweiterten Typ 18, und löschen Sie wieder das 'exit'-Flag wie bei den Radiobuttons. Einziger Unterschied zu den Radiobuttons: Die Checkbuttons haben ein gelöschtes Yadio'-Flag. Setzen Sie bei den Buttons "hochgestellt" und "tiefgestellt" zusätzlich das 'touchexit'-Flag. Den Sinn hierfür werden Sie später noch erkennen. Vergeben Sie allen Buttons Namen. Das Textfeld ist vom Objekttyp FTEXT, hat unter anderem das gesetzte Flag 'edi-table' und soll den Namen "gesptext" bekommen. Genaueres zu den Textfeldern erfahren Sie in der Dokumentation Ihres RCS-Programms.

Da Sie hier editierbaren Text benutzen, müssen Sie abschließend den Baum FVT_ASCI aus der Datei TREES.RSC von der faceVALUE Diskette mit einbinden, damit faceVALUE beim Drücken von Insert im Editierfeld eine ASCII-Tabelle anzeigen kann. Nach einem neuen faceVALUE-Lauf befindet sich in user_var_init() der Ausschnitt aus Listing 5, wo man voreinstellen kann, welche Buttons am Anfang angekreuzt dargestellt werden sollen, bzw. welcher Text im Editfeld stehen soll.

Darunter ein Auszug aus der Prozedur user_rsc_interact(), die demonstriert, wie eine mögliche Abfrage nach dem Drücken des OK-Buttons aussehen könnte. Wagen Sie an dieser Stelle ruhig nocheinmal ein RUN und testen Sie den neuen Dialog (Abbildung 6).

Offene Dialoge ändern

Bei der Benutzung des neuen Dialoges wird schnell klar, dass eine Schriftart, die zugleich hochgestellt wie auch tiefgestellt ist, keinen Sinn macht. Um diesem Dilemma zu entgehen, soll das Programm nun so ergänzt werden, dass das Setzen des Buttons 'hochgestellt' den Button 'tiefgestellt' zurücksetzt und umgekehrt. Vielleicht ist es Ihnen schon aufgefallen: Durch das Setzen des Touchexit-Flags bei diesen Knöpfen hat faceVALUE in der Prozedur user_rsc_interact() auch für diese Checkbuttons einen Eintrag angelegt. Wir können unter den Verteiler CASE hochgest& und CASE tiefgest& auf jede Zustandsänderung dieser Buttons reagieren und in unserem Fall eventuell den ändern Button zurücksetzen.

Das Ändern von Objekten in geöffneten Dialogen gestaltet sich etwas aufwendiger: Im ersten Schritt wird die Statusvariable des Objektes geändert, bei den Buttons hier wird sie also mit dem CLR-Befehl auf FALSE gesetzt. Alle anderen Schritte werden von der Prozedur 'rsc_ob_reset' übernommen (Listing 6). Damit die Engine den Wechsel der Statusvariable erkennt, ruft diese Prozedur zunächst rsc_setup_tree auf. Dieser Aufruf setzt die Daten in den Objektstrukturen der Objekte entsprechend ihrer Statusvariablen und wird auch vor dem Öffnen eines Dialoges automatisch durchgeführt.

In einem letzten Schritt muss das geänderte Objekt neu gezeichnet werden, damit die Änderungen auch wirklich auf dem Bildschirm sichtbar werden. Die Prozedur rsc_ob_reset durchsucht hierzu alle Fenster nach dem Objekt und zeichnet es in den betroffenen mit Hilfe von rsc_ob_draw neu. Auf die Problematik des 'Screenlockings', das durch die Prozeduren aes_screen_(un)lock realisiert wurde, wird im nächsten Teil ausführlicher eingegangen.

Außerdem erfahren Sie im nächsten Teil des Programmierkurses unter anderem etwas über Image-Popups, Image-Radiobuttons, animierte Icons und animierte Mauszeiger. Ich werde weiterhin die beiden Busydialoge erläutern.


Volker Janzen
Aus: ST-Computer 01 / 1997, Seite 59

Links

Copyright-Bestimmungen: siehe Über diese Seite