VOICE-Homepage: http://de.os2voice.org |
Juni 2004
Inhaltsverzeichnis
|
Von Thomas Klein © Juni 2004 |
Im heutigen Teil unserer Serie werden wir - entgegen meiner Ankündigung - nicht wieder sofort mit der Entwicklung in DrDialog einsteigen. Ich denke, es ist besser, wenn ich Ihnen einen "sanften" Übergang von der "reinen REXX-Programmierung" zurück zur DrDialog-Welt ermögliche: Seitdem wir mit der Umgebung und den Gegebenheiten vertraut waren, ist einige Zeit vergangen. Wir werden also kurz einige Fakten rekapitulieren und außerdem einen kurzen theorielastigen Teil zu bestimmten Eigenheiten von DrDialog erarbeiten und ich werde - ja, endlich! - eine kurze Vorstellung dessen geben, was ich als unser Beispielprojekt auserkoren habe und das uns über die nächsten Ausgaben beschäftigen wird. Aus diesem Grund werden wir uns also heute nochmals damit beschäftigen, wie die Arbeitsumgebung von DrDialog aussieht. Es wird uns einiges an Zeit und "grauen Zellen" retten, wenn ich in den kommenden Ausgaben davon ausgehen kann, daß Sie wissen, wo sich die richtigen Schaltflächen befinden...
Bevor wir aber loslegen, möchte ich Ihnen dringend raten, nochmals Chris Wohlgemuth's Leserbrief in der vorherigen Ausgabe des Newsletters zu lesen, der sich mit den rexxutil-Funktionen beschäftigt, und mich an dieser Stelle herzlich bei Chris für seinen Beitrag zu bedanken, der es uns ermöglicht, von seinem Erfahrungs- und Wissensschatz zu profitieren. Gerade wenn es sich um Computer und Programmierung handelt, gibt es einen Grundsatz, der für Sie, mich und uns alle gilt - egal, für wie gut wir uns in etwas halten möchten: Man lernt nie aus. Und dieses mal gebührt der Dank Chris, der uns ermöglicht hat etwas hinzuzulernen. Und ich kann es nicht oft genug sagen: Kommentare sind willkommen! Wenn Sie also erfahrener Entwickler (oder Anwender) sind und auf etwas stoßen, daß Ihrer Meinung nach nicht korrekt ist oder einer genaueren Beschreibung bedarf, dann lassen Sie es uns wissen, indem Sie einen entsprechenden Kommentar entweder an mich oder den Herausgeber senden, so wie Chris es tat. Dabei fällt mir ein: Hatte ich bereits erwähnt, daß Chris der einzige Entwickler "da draußen" ist, der immer noch dafür sorgt, daß sich der Funktionsumfang von DrDialog weiterentwickelt? Übrigens werden wir in einer der kommenden Ausgaben einen näheren Blick auf den Funktionsumfang seines Erweiterungspakets für DrDialog werfen.
In einem der ersten Teile unserer Serie hatten wir bereits besprochen, wie man DrDialogs Entwicklungsumgebung verwendet. Für diese und alle weiteren Ausgaben wollen wir nun einen "gemeinsamen Grundstein" legen, damit wir uns ständige Wiederholungen a la "wo ist..." sparen können.
Ich setze voraus, daß Sie wissen, wie Sie DrDialog selbst starten. Stellen wir nun also noch sicher, daß Sie wissen, wie die folgenden Funktionen bzw. Fenster in DrDialog aufgerufen werden:
Das
Fenster des "run time monitor"
Die Sammlung der Steuerelemente ("controls")
Das
Code-Notizbuch (respektive "Code-Editor")
Alle diese Schaltflächen sind erreichbar über die Menüleiste, unter dem Eintrag Tools um genau zu sein:
Beachten Sie, daß jedes dieser Fenster so eingestellt werden kann, daß es geöffnet bleibt, und ebenso, daß es direkt beim Start von DrDialogs integrierter Entwicklungsumgebung (IDE, "integrated development environment") geöffnet wird. Hierzu werden für das jeweilige Fenster die Einträge in dessen Systemmenü verwendet:
Das Fenster Dialoge:
Außerdem werden Sie - sobald Sie mehrere Dialogfenster im selben Programm verwenden - mit dem Fenster Dialoge arbeiten. Dieses Fenster wird über die Schaltfläche aufgerufen, die Sie links abgebildet sehen und die sich (genau wie die anderen oben besprochenen Fenster) entweder im Menüeintrag Tools oder (sofern geöffnet) dem Fenster Tools aufrufen läßt. Die anderen Fenster (wie z.B. Farbauswahl) werden wir für's erste nicht benötigen.
Bisher haben wir bereits die Style-Einstellungen von Dialogen besprochen und was sie bewirken.
Aber das betrifft nur so genannte "Designzeit"-Eigenschaften. Um mit mehreren Dialogen
im selben Programm zu arbeiten müssen wir wissen, was man zur "Laufzeit" mit Ihnen
anstellen kann - "aus dem Code heraus" sozusagen.
Um DrDialogs Verhalten verstehen zu können, müssen wir uns zuerst darüber klar
werden, daß nahezu alles, was wir in DrDialog programmieren, auf die eine oder andere Weise
mit Event-Handlern (Ereignisbehandlungsroutinen) verknüpft ist. Was geschieht eigentlich
innerhalb von DrDialog, wenn ein Programm gestartet wird? Wo ist der Anfang in all den
"losen Enden" von Code? Wie endet eigentlich ein Programm? Um das nun wiederum zu
verstehen, müssen zwischen zwei "Arten" von Code in DrDialog
unterscheiden:
Wie ihr Name vermuten läßt, sind Event-Handler-Codes an einen Event-Handler
geknüpft und werden automatisch aufgerufen, sobald das entsprechende Ereignis eintritt. Noch
wichtiger ist, daß (im Gegensatz zu VisualBasic bspw.) ein Event-Handler nicht manuell
aufgerufen werden kann - außer man löst das zugehörige Ereignis manuell aus (z.B.
das Öffnen eines Dialogs, um die Ereignisse INIT
und OPEN
auszulösen).
Das bedeutet, daß während wir eine einzelne Methode oder Eigenschaft eines
Steuerelements von einer beliebigen Stelle im code heraus ansprechen bzw. abfragen/ändern
können, wir bei DrDialog nicht in der Lage sind, eine Event-Handler-Routine aufzurufen...
"Hä?" werden Sie jetzt vielleicht fragen... gut, hier ein Beispiel:
Wir möchten einen Dialog erzeugen, der uns die aktuelle Uhrzeit in einem Textfeld
anzeigt. Zur Ladezeit des Textfeldes rufen wir also mittels der REXX-Funktion time()
einfach die aktuelle Uhrzeit ab. Im INIT
Event-Handler des Textfelds (angenommen,
dessen Name wäre txt_tst
) würden wir also codieren:
call txt_tst.text(time())
Probieren Sie's mal aus: Super. Es klappt.
Irgendwann im Laufe von Programmierung und Test des Programms stellen wir fest, daß unter
Umständen einiges an Zeit seit dem Programmstart verstrichen sein könnte und
beschließen, neben dem Textfeld eine Schaltfläche ("pushbutton") anzulegen,
um eine Aktualisierung der angezeigten Uhrzeit zu ermöglichen. Alles, was diese
Schaltfläche tun soll, ist genau das, was wir im Event-Handler INIT
des
Textfelds bereits codiert haben: Den Feldinhalt auf die aktuelle Uhrzeit zu setzen.
Nun gut denn - wir sind Programmierer und als solche faul und geizig. Warum also nicht einfach
den Event-Handler INIT
im CLICK
Ereignis der Schaltfläche
aufrufen? Ups... da fangen die Probleme an: Es gibt keinen "Aufruf", der das
ermöglicht. Der Event-Handler INIT
wird ausschließlich von DrDialogs
interner Ereignis-Warteschlange aufgerufen. Gut, gut.. dann... machen wir's doch einfach
anders herum: Wir tragen den Code im Event-Handler CLICK
des pushbuttons ein. Dann
ändern wir den INIT
event-handler des Textfeldes dahingehend, daß einfach
nur der Event-Handler CLICK
für den pushbutton aufgerufen wird... und: Mist -
wieder nix...
Aber es ist nicht tragisch: Es ist ja nur eine einzige Zeile Code. Wir könnten sie einfach in beide Event-Handler eintragen und "gut ist"... aber... was wäre, wenn es sich nicht um eine einzelne Zeile, sondern einen ganzen Anweisungsblock handelte? Möchten Sie wirklich identischen Code redundant an mehreren Stellen in Ihrem Programm verwenden? Das sieht doch irgendwie "doof" aus, oder? Außerdem ist es ziemlich aufwendig, wenn Sie beispielsweise einen Fehler in diesem Anweisungsblock entdecken - Sie müßten in dann an mehreren Stellen identisch korrigieren. Ach, das ist einfach nicht "raffiniert" genug! Und genau an dieser Stelle kommt der globale Code in's Spiel:
Der globale Code besteht aus (Unter-) Routinen und Funktionen, die nicht an einen bestimmten
Event-Handler gebunden sind. Sie können aus jeder beliebigen Stelle im Programmcode
aufgerufen werden - sei es aus einem Event-Handler oder aus einem anderen globalen
Codestückchen.
Die Lösung ist also, den Aufruf der time()
-Funktion in eine separate
Unterroutine zu legen und dann lediglich aus den beiden Event-Handlern diese Routine aufzurufen.
Um eine solche globale Routine (oder "Funktion") zu erstellen, müssen wir
zunächst im Codeeditor von den ereignisbezogenen Routinen zum globalen Teil umschalten,
indem wir die Schaltfläche mit dem "Globus" verwenden:
Der Codeeditor zeigt nun Indexzungen für jede bereits definierte globale Routine an. Wenn es (noch) keine solche gibt, ist das Fenster schlicht "ziemlich leer". Das Eingabefeld am oberen Bereich des Fensters dient zur Eingabe des Namens der Funktion, die Sie anlegen oder bearbeiten möchten. Geben Sie hier den Namen ein, den die Funktion tragen soll - beispielsweise "set_curr_date" (ohne die Anführungszeichen) und schließen Sie die Eingabe mit der Eingabetaste ab. Sie werden dann erkennen, daß der Codeeditor einen neuen Reiter mit diesem Namen anlegt.
Im Codeeingabebereich können Sie nun die Anweisungen eingeben, aus denen die Funktion bestehen soll. In unserem Fall wäre das:
call txt_tst.text(time())
...und schon falsch!
Diese Routine ist global. Das bedeutet also, daß sie von überall in
unserem Programm aus aufgerufen werden kann. Daraus folgt, daß die Funktion nicht
weiß, in welchem "Control-Kontext" sie sich jeweils gerade befinden könnte.
Sie benötigt also den "voll qualifizierten Namen" des Steuerelements, das
angesprochen wird, das heißt: Den Dialog, in dem sich das Element befindet, und den
Namen des Elements. Wir müssen also vor den Namen des Elements noch den Namen des Dialogs
setzen. Angenommen, der Name des Dialogs wäre MyDialog
, müßte es
also lauten
call MyDialog.txt_tst.text(time())
Schön. Sie werden sich vielleicht daran erinnern, daß man Dialogen nicht unbedingt einen Namen geben muß. In diesem Fall kann der Dialog immer noch gezielt angesprochen werden - nämlich über seine "ID-Nummer" in der Form "D100" beispielsweise ("D" ist der Präfix für Dialoge, 100 ist die ID-Nummer). Diese ID-Nummer eines Dialoges (oder auch Steuerelements) ist relativ leicht dadurch zu ermitteln, daß sie im Statusbereich am unteren Rand von DrDialogs Arbeitsbereichsfenster (dem "Hintergrund") angezeigt wird, sobald man den Mauszeiger auf das entsprechende Element bewegt:
Wenn unser Textfeld keinen Namen hätte, könnten wir es ebenfalls über seine ID-Nummer ansprechen: Steuerelemente verwenden den Präfix "C" (für "control" - Steuerelement) gefolgt von der ID-Nummer. Wäre die ID-Nummer des Textfelds z.B. "101", dann lautete sein voll qualifizierter Name:
D100.C101
Und daher würde der Aufruf in unserer globalen Funktion lauten:
call D100.C101.text(time())
Sobald Ihre globale Funktion vollständig ist, brauchen Sie sie nicht explizit irgendwie zu "speichern". DrDialog speichert sie automatisch, sobald man im Codeeditor einen anderen Bereich aufruft. Beachten Sie aber, daß DrDialog die Funktion automatisch löscht, wenn sich keinerlei Code darin befindet. Sie müßten Sie dann zunächst erst wieder wie oben beschrieben anlegen. Aber, wenn ja ohnehin kein code darin ist... kein Problem.
Bevor wir fortfahren, sollten wir noch besprechen, wie diese globale Funktion denn in den beiden Event-Handlern aufgerufen wird. Alles, was Sie dafür tun müssen, ist, die Anweisung
call set_curr_date
in beiden Event-Handlern einzutragen.
Das war jetzt vielleicht nicht das beste Beispiel, um die Vorzüge einer separaten, globalen
Funktion zu erläutern. Stellen Sie sich einfach vor, diese Funktion würde statt einer
Zeile ein ganzes Dutzend oder mehr Befehle enthalten. Beachten Sie auch, daß wir auf diese
Weise volle Kontrolle über das Verhalten der Funktion haben und daher auch in der Lage
wären, sie mit zusätzlichen Parametern aufzurufen, wenn wir das wollten. Damit
könnten wir also die Funktion so ausbauen, daß Sie in Abhängigkeit von
unterschiedlichen übergebenen Parameterwerten auf unterschiedliche Weise arbeitet.
Das war also ein Beispiel für eine globale Funktion bzw. Routine und wie man sie anlegt. Nun, da Sie wissen, was die Unterschiede zwischen Event-Handlern und globalen Routinen sind, können wir uns wieder der eingangs erwähnten Frage widmen: Wie startet eigentlich ein mit DrDialog erstelltes Programm?
Nun, DrDialog schaut zunächst nach, ob sich im globalen Teil des Programms (also unter
den globalen Funktionen) eine Funktion befindet, die INIT
heißt: Wenn eine
solche Funktion vorhanden ist, wird sie ausgeführt und somit zum
"Ursprungs-Event-Handler", wenn Sie so wollen.
Gibt es keine solche Funktion, lädt DrDialog das Dialogfenster mit der kleinsten ID-Nummer.
Da die Existenz eines Dialogs mit dem INIT
-Ereignis beginnt, wird also der
INIT
-Event-Handler zum Ursprungs-Event-Handler Ihres Programms.
Und das Programmende? Hier gibt es ebenfalls zwei Methoden: Eine "manuelle" und die
in DrDialog "eingebaute":
Die eingebaute Methode besteht aus DrDialogs Überwachung der eigenen Fensterliste: Wenn das
letzte existierende Dialogfenster geschlossen wird, wird auch das Programm beendet.
Die manuelle Methode besteht aus lediglich einem einzigen Befehl: "Exit" (ohne die
Anführungszeichen) beendet das Programm. Vorsicht: Damit wird das Programm unverzüglich
beendet - benehmen Sie sich also ordentlich, was eventuell geöffnete Dateien angeht! Und
bitte verwenden Sie den exit-Befehl nicht irgendwo, tief im Code Ihres Programms. So etwas tun
"schludrige" Programmierer. Versuchen Sie immer, die Programmlogik auf eine
"kontrollierte" Art und Weise zu beenden.
Man kann zwar nie wissen, aber im Prinzip sollten Sie mit DrDialog nie in die Verlegenheit
kommen, den EXIT-Befehl verwenden zu müssen, sofern Ihre Programmlogik "intakt"
ist.
Aber wie bei jeder Regel, gibt es auch hier eine Ausnahme:
Angenommen, Sie möchten in Ihrem Programm überhaupt keine Dialoge verwenden, da es
lediglich Batchverarbeitung ausführt, die keinerlei Eingaben oder sonstige Aktionen von
Seiten des Anwenders erfordert, dann sollten Sie lieber "reines REXX" einsetzen statt
DrDialog. Wenn Sie dennoch unbedingt DrDialog verwenden wollen, müssen Sie sich mit einer
speziellen Eigenschaft dieser Umgebung auseinander setzen, die wir bereits in einem der ersten
Teile der Serie besprochen haben: DrDialog erzeugt grundsätzlich ein
Standard-Dialogfenster. Wenn Sie dieses löschen, wird sofort ein neues erzeugt.
Das liegt an DrDialogs rein ereignisgesteuerter Ausrichtung, die darauf beruht, daß alles
mit einem Dialogfenster beginnt. Natürlich könnten Sie die Style-Eigenschaft des
Dialogs auf "invisible" (unsichtbar) setzen, damit das Fenster gar nicht erst angezeigt
würde und alles nötige in eine globale Routine INIT
packen, mit der Ihr
Programm dann startet... aber das wird so nicht klappen: Das Programm wird nämlich nicht
beendet, wenn die letzte Anweisung Ihrer INIT
-Routine abgearbeitet wurde. Nein -
stattdessen wird nach Ausführung der letzten Anweisung das "vernachlässigte"
Dialogfenster aktiv werden - egal, ob Sie es versteckt hatten oder nicht. Hoppla. Um dieses
"Problem" zu umgehen, verwenden Sie einfach den EXIT
-Befehl als letzte
Anweisung in Ihrer Verarbeitungskette - das sollte dem Ding eine Lehre sein! Oder besser:
Verwenden Sie einfach pures REXX, wenn Sie keine Dialoge benötigen.
Das wären also ein paar Hinweise zum Arbeiten ohne jegliche Dialoge gewesen. Was ist
aber, wenn man mehrere Dialoge im selben Programm benötigt - beispielsweise einen
Hauptdialog, einen "Optionen"-Dialog und eventuell einen Logo- bzw.
Produktinformationsdialog? Worauf muss man achten?
Dafür muß man wissen, wie Dialoge aus dem Code heraus gesteuert werden können:
Öffnen, Schließen, Sperren der Anwendung auf einen einzelnen Dialog... tja, um mit
unseren Erwartungen mithalten zu können, ist es unabdingbar zu begreifen, wie DrDialog sich
hinsichtlich Ereignisverarbeitung und Dialogsteuerung verhält. (Das ist der etwas
"theorielastige" Teile, den ich eingangs erwähnte. Obwohl er vielleicht nicht
unterhaltsam ist, sollten wir ihn dennoch "durchkauen", um einige wichtige Grundlagen
für's Arbeiten mit DrDialog zu schaffen...)
DrDialog arbeitet ereignisorientiert und verwendet eine Nachrichten- bzw.
Ereigniswarteschlange ("queue"). Das bedeutet im Prinzip, daß Ereignisse
zunächst in einer Warteschlange abgelegt werden und dann nacheinander in der Reihenfolge des
Auftretens abgearbeitet werden. Eigentlich ist das dasselbe, was andere Programmiersprachen unter
graphischen, multitaskingfähigen Betriebssystemen auch tun. Das, was DrDialog hier von den
anderen unterscheidet, ist die Art und Weise, wie diese Warteschlange "implementiert"
ist:
Ich versuche, es einmal so zu erklären, wie ich es mir vorstelle - wenn jemand da
draußen es besser (oder "richtig" ?) beschreiben kann, soll er es uns unbedingt
wissen lassen! Na, jedenfalls... DrDialog verwendet den REXX-Interpreter des Betriebssystems,
wodurch ihm nur eine einzige Warteschlange zur Verfügung steht. Da die GUI-bezogenen
Ereignisse (z.B. Klicken einer Schaltfläche) von seiner eigenen Umgebung gesteuert und
verarbeitet werden und diese ebenfalls die eine Warteschlange mitverwendet, ergeben sich
leichte "Abweichungen" in dem uns eventuell bekannten Verhaltensmuster. Wenn Sie
beispielsweise VisualBasic kennen, dann werden Sie wissen, daß Befehle und Ereignisse
hinsichtlich der Reihenfolge Ihres Auftretens gleich behandelt werden: Wenn an einer beliebigen
Stelle im Programm ein Dialogfenster geöffnet wird, führt VB unmittelbar die komplette,
eventuell verschachtelte Verarbeitung aller zugehörigen Ereignisse aus und kehrt dann zu dem
Befehl zurück, der auf die Öffnen-Anweisung des Dialogs folgt. Um Ihnen das einmal zu
veranschaulichen, nehmen wir als Beispiel die folgende willkürliche Befehlssequenz:
- irgendein Befehl 1 - ÖFFNE Dialog "A" - irgendein Befehl 2
VB würde das wie folgt ausführen:
- Verarbeitung von "irgendein Befehl 1" - Aufruf für "Öffne Dialog A:" -> wird aufgelöst in: -- Verarbeitung des INIT-Eventhandlers von Dialog A -- Verarbeitung des OPEN-Eventhandlers von Dialog A - Verarbeitung von "irgendein Befehl 2"
Jetzt mal keine Panik - Sie werden den Sinn des Ganzen begreifen, wenn wir uns anschauen, wie
das in DrDialog aussieht.
DrDialog arbeitet hier anders. Da sich die REXX-Befehle und die möglichen Ereignisse
dieselbe Warteschlange teilen müssen, haben die REXX-Befehle des aktuell ausgeführten
Handlers "Priorität" vor den eventuell ausgelösten Ereignissen. Das bedeutet
also, daß DrDialog alle GUI-bezogenen Ereignisse zunächst in der Warteschlange
speichert und diese erst nach Abschluß des aktuellen Handlers ausführt. Für das
obige Beispiel ergäbe sich unter DrDialog demnach ein anderer Ablauf. Zunächst schauen
wir uns nochmals an, wie die Befehlssequenz war:
- irgendein Befehl 1 - ÖFFNE Dialog "A" - irgendein Befehl 1
DrDialog würde das wie folgt verarbeiten:
- Verarbeitung von "irgendein Befehl 1" - Aufruf für "Öffne Dialog A:" ( -> in die Warteschlange stellen! ) - Verarbeitung von "irgendein Befehl 2" < handler fertig, Warteschlange prüfen... aha: Ereignis auflösen in...: > -- Verarbeitung des INIT-Eventhandlers von Dialog A -- Verarbeitung des OPEN-Eventhandlers von Dialog A
Erkennen Sie den Unterschied? In der Praxis stellt uns das nun vor das eine oder andere
Problem - zum Beispiel:
Wir denken meist in "prozeduralen" (oder auch "linearen") Abfolgen einer
Verarbeitung und gehen beispielsweise davon aus, daß wir innerhalb einer Verarbeitungskette
auf eine Benutzereingabe warten können. Obwohl das eigentlich richtig ist, läßt
es sich mit einem Dialogfenster in DrDialog so nicht bewerkstelligen. Wenn Sie also eine
Benutzeraktion (wie Eingaben) benötigen, um eine Verarbeitung fortzusetzen, können Sie
nicht einfach einen Dialog aufrufen und auf das Klicken einer bestimmten Schaltfläche
warten, da DrDialog zuerst die aktuelle Prozedur abarbeitet, bevor der Dialog
erscheint.
Ein Programm auf eine Benutzereingabe warten zu lassen, ist übrigens Batch-Programmierung und DrDialog arbeitet ereignisorientiert. Daher wäre der richtige Ansatz für diese Problemstellung, nicht herauszufinden, wie zum Teufel man die Verarbeitung auf die Eingabe warten lassen kann, sondern vielmehr, die Verarbeitung erst nach der Eingabe zu starten, also: Vom Dialog aus.
Ein weiteres Kriterium zur Problemlösung ist die Tatsache, daß wir Betriebssysteme
verwenden, die multitasking- und multithreading-fähig sind. Anstelle daß
das Programm also auf eine Benutzeraktion wartet und wartet (was bedeutet, daß es also
irgendwie CPU-Zeit verbraucht), sollte es lieber nichts tun (und CPU-Zeit an andere
Prozesse abgeben), bis der Benutzer tatsächlich irgend etwas getan hat.
In der Praxis würden Sie also zuerst den Dialog anzeigen und stopp. Das wär's. Den
Rest der Verarbeitung starten Sie erst, wenn der Benutzer auf die entsprechende Schaltfläche
geklickt hat. Die Verarbeitung ist somit nicht der Bestandteil eines großen
Anweisungsblocks, der vorher einen Dialog anzeigt, sondern Bestandteil dessen, was nach dem
Drücken der Schaltfläche passiert. Sie verstehen? ;)
Gut. So weit also die Hinweise, die das Umgehen mit einem einzelnen Dialog betreffen. Jetzt gehen wir mal einen Schritt weiter. Einen großen...
Stellen Sie sich vor, Sie hätten die Idee zu einem neuen Programm - einem persönlichen Informationsassistenten. Eigentlich haben Sie keinen blassen Schimmer, was da später so alles noch auf Sie zukommt, aber Sie wissen, daß Sie unbedingt folgendes benötigen:
Sie sollten dann damit beginnen, bestimmte Verhältnisse unter den Dialogen zu bestimmen, wie z.B. deren Reihenfolge beim Programmstart. Um das ganze noch etwas komplizierter zu gestalten, nehmen wir also an, daß Ihnen außerdem noch folgendes vorschwebt:
Das ist einiges. Und das ist noch ein Kinderspiel im Vergleich zu den "langweiligen"
Sachen wie das Lesen, Schreiben und Darstellen von Daten.
Und es ist genau das, was wir als Beispielprogramm erstellen werden.
Au Backe... ich armer Kerl! Das kostet mich mindestens wieder ein Dutzend Artikel! Konnten Sie
sich nichts leichteres Ausdenken? ;)
Bevor ich Sie aber jetzt mit großen Erwartungen und einem Haufen offener Fragen
zurücklasse, gönnen wir uns noch einen kleinen Wissenshappen zu DrDialog:
Da wir nun wissen, daß wir Event-Handler nicht wie andere Funktionen "manuell"
aufrufen können, führt uns das direkt zu einer anderen Frage: Wie übergibt man
Informationen an einen Dialog? Das wäre ziemlich nützlich, um beim Öffnen eines
Dialogs gleich ein paar Parameter mitzugeben, wie Position, Größe, Titel und so
weiter. Tja - keine Chance. Zumindest nicht auf direktem Weg... die Antwort lautet: Globale
Variablen.
In den meisten Programmiersprachen werden Sie bestimmte Mittel finden um festzulegen, ob eine Variable nur in der aktuellen Funktion oder im gesamten Programm zur Verfügung steht (= "global" ist). In DrDialog ist das relativ einfach gelöst: Jede von Ihnen angelegte Variable ist automatisch global. Es sind keine besonderen Tricks und Kniffe nötig, damit Sie global ist. Aber Vorsicht - im Gegenzug gibt es auch keine Möglichkeit, eine Variable "lokal" zu machen: Wenn Sie den Inhalt einer Variable an einer Stelle des Programms ändern, ist sie "überall" geändert.
Noch ein kurzes Beispiel dazu? Hier ist es:
Beginnen Sie ein neues Programm in DrDialog. Der Standarddialog wird automatisch angelegt. Jetzt
legen Sie eine Funktion mit dem Namen INIT
im globalen Teil des Codeeditors an (wie
das geht, hatten wir oben besprochen) und tragen dort den folgenden Befehl ein:
MeinDatenFeld = "Hallo"
Jetzt ziehen Sie eine Schaltfläche aus dem Controls-Fenster auf den Dialog. Der Text auf
der Schaltfläche lautet standardmäßig Push
. Nach einem Doppelklick
auf die Schaltfläche erscheint im Codeeditor die Liste der dafür verfügbaren
Event-Handler. Wählen Sie Reiter für das INIT
-Ereignis aus und geben im
Codefenster ein:
call text MeinDatenFeld
Starten Sie das Programm. Wie Sie sehen, wird als Text für die Schaltfläche nun der
Inhalt der globalen Variablen verwendet, die wir in der INIT
-Routine des Programms
definiert haben.
Das wär's für heute. Ich hoffe, Sie freuen sich auf die nächste Folge. Wenn Sie schon immer wissen wollten, wie man einen Dialog "applikationsmodal" (die Anwendung "sperrend") in DrDialog angezeigt bekommt, sollten Sie dabei sein! ;)
Artikelverzeichnis
editor@os2voice.org
< Vorherige Seite | Inhaltsverzeichnis | Nächste Seite >
VOICE-Homepage: http://de.os2voice.org