|
|
|
|
3. Die Dialog Library 3.1
3.2
3.3
3.4
3.5
3.6
3.7Aufbau einer Dialogbox
Definition einer Diologbox
Aufruf einer Dialogbox
Auswertung einer Dialogbox
Menüs und modale Dialogboxen
Nichtmodale Dialogboxen
Verbindung zur Control LibraryReferenzliste Dialog Library
| Dieser Teil der EasyGem Library beschäftigt sich nun mit den Dialogboxen, also diesen Kästen, die immer dann auf dem Bildschirm erscheinen, wenn der Anwender irgendetwas auswählen oder eingeben soll oder wenn über den Fortschritt bei einer Funktion (z.B. Dokument drucken) informiert werden soll. Er kann damit komfortabel mit Knöpfen zwischen verschiedenen Alternativen wählen oder auch kleinere Texte eingeben. |
| 3.1 Aufbau einer Dialogbox Gehen wir am besten gleich direkt zur Praxis über. Wir wollen einfach eine kleine Dialogbox auf den Bildschirm bringen. EasyGem müssen wir vorher initialisiert haben (mit Easy_Init). Dann beginnt das eigentliche Programm. Um mit Dialogboxen arbeiten zu können, müssen wir erst einmal festlegen, wie diese eigentlich aussehen sollen. Das geht mit EasyGem genauso einfach, wie beim Arbeiten mit Menüs; indem Sie nämlich mit den entsprechenden Befehlen Ihre Dialogbox im Programm definieren. |
| Dabei gibt es in EasyGem ab Version 4.0 zwei unterschiedliche Möglichkeiten,
eine Dialogbox aufzubauen. 1. Für einfache Dialogboxen, die nur die Standardobjekte verwenden und keine besonderen Ansprüche an das Layout stellen, genügen die Befehle und Funktionen der Dialog Library. Dabei wird die Dialogbox in Zeilen eingeteilt, in denen dann wieder Texte und Objekte einer Art definiert werden können. 2. Mit Hilfe der Control Library gibt es zusätzlich die Möglichkeit, in Dialogboxen freie Controls zu definieren. Dabei steht Ihnen neben den Standardtypen ein breites Spektrum an weiteren Objekten zur Verfügung (z.B. Icons, Slider, Tickmarks, Zeit und Datumsanzeige usw. ), die ausserdem beliebig positioniert werden können. Mit der Control Library können Sie nahezu alle Objekte, die auf dem Mac zur Verfügung stehen, definieren und verwalten. Die Programmierung ist jedoch schwieriger als bei der ersten Methode. |
| Im diesem Kapitel beschäftigen wir uns nur mit der ersten Methode,
da sie für den Anfänger leichter anzuwenden ist. Grosse Teile des Layouts
und der Verwaltung werden bereits von EasyGem übernommen und müssen nicht
extra programmiert werden. In den einzelnen Zeilen einer Dialogbox können folgende Elemente untergebracht werden: |
Das gilt natürlich nicht für nichtmodale Dialogboxen, die in Ihrer Titelzeile ein Schliessfeld haben, aber dazu später mehr. Aus diesen Elementen können Sie Ihre Dialogbox zusammensetzen. |
| 3.2 Definition einer Dialogbox Eine Definition beginnt immer mit dem Befehl Def_Dialog und endet mit End_Dialog. Zwischen diesen beiden Aufrufen befindet sich die eigentliche Definition, in der das Aussehen festgelegt wird: |
| Def_Dialog R Dialog_Id[,X,Y,W,H],Title$,Type Make_Dialog Type Make_Dialog Box$,Dialog_Id[,Name$] |
| Definition beginnen. |
| Make_Dialog wurde
nur aus Kompatibilitätsgründen zu älteren EasyGem Versionen implementiert.
Verwenden Sie darum am besten nur Def_Dialog. In Dialog_Id erhalten Sie wie bei Def_Menu eine Identifikationsnummer, die Sie bei allen Zugriffen auf die Dialogbox angeben müssen. Optional kann man mit X,Y,W,H auch gleich noch Position und Grösse der Dialogbox festlegen. Zunächst wollen wir diese Möglichkeit aber nicht nutzen. EasyGem berechnet die Grösse dann selbsständig aus den enthaltenen Objekten und stellt die Dialogbox zentriert auf dem Bildschirm dar. Title$ wird bei verschiebbaren Dialogboxen in der Titelzeile angezeigt, bei nicht verschiebbaren Dialogboxen wird der Titelstring ganz oben in der Dialogbox eingetragen. Mit Type schliesslich bestimmen Sie, um welchen Dialogbox-Typ es sich handeln soll. Dabei gibt es die folgenden Möglichkeiten: Type=0 erzeugt eine modale, nicht verschiebbare Dialogbox. Type=1 erzeugt eine Dialogbox, die ebenfalls modal ist, aber über einen Schiebebalken verfügt. Während die Dialogbox offen ist, können Sie also auch auf andere Programme umschalten und die Dialogbox kann auch auf dem Bildschirm verschoben werden. Mit Ihrem eigenen Programm können Sie allerdings erst weiterarbeiten, wenn die Dialogbox verlassen wurde. Type=2 erzeugt eine nicht modale, verschiebbare Dialogbox. Eine solche Dialogbox kann immer geöffnet bleiben. Sie braucht also nicht erst geschlossen zu werden, um mit anderen Teilen Ihres Programms weiterarbeiten zu können. |
| Nach Def_Dialog folgt die eigentliche Definition, die weiter unten erläutert wird.
Den Abschluß bildet dann: |
| End_Dialog [[Box$,]R Dialog_Id] |
| Definition abschließen. |
| Box$ hat keine
Bedeutung und dient nur der Kompatibilität zu älteren EasyGem Versionen,
kann also immer weggelassen werden. Dialog_Id können Sie ebenfalls weglassen, da Sie die Dialog-Identifikationsnummer
ja schon bei Def_Dialog zurückerhalten haben. Verwenden Sie also am besten End_Dialog ohne Parameter. Eine typische Dialogbox-Definition sieht damit wie folgt aus: |
| Def_Dialog Dialog1,"Modale Dialogbox",1 'Hier steht die Definition der Dialogbox. End_Dialog |
| Clear_Dialog [Box$,] Dialog_Id |
| Dialogbox löschen. |
| Dieser Befehl löscht die Dialogbox mit der Identifikations-Nummer
Dialog_Id. Die Angabe
Box$ ist wieder nur
aus Kompatibilitätsgründen möglich und hat keine Bedeutung. Man braucht
diesen Befehl eigentlich nur, wenn keine Identifikationsnummern mehr frei sind. Nun kommen wir zum eigentlichen Definitionsteil. Beginnen wir mit den Überschriften: |
| D_Title [Line_No,]Txt$ |
| Definiert eine Titelzeile in der Dialogbox. |
| Ein Titel wird zentriert in einer kleinen Box dargestellt. Line_No gibt die Zeile innerhalb der Dialogbox an, in der der Titel erscheinen soll (1=ganz oben, 2=eine Textzeile tiefer usw). Txt$ ist der Text, der als Titel ausgegeben werden soll. Wird Line_No=0 gesetzt oder ganz weggelassen, so wird Txt$ in die Titelzeile der Dialogbox eingetragen. Das funktioniert natürlich nur, wenn die Dialogbox auch eine Titelzeile (Schiebebalken) hat, wenn Sie also bei Def_Dialog für Typ=1 oder Typ=2 angegeben haben. |
| Beispiel: |
| Def_Dialog Dialog1,"",0 D_Title 2,"Titel" End_Dialog |
| Durch diese Definition ist das Aussehen der Dialogbox festgelegt. Die Dialogbox erscheint aber noch nicht auf dem Bildschirm! Wie Sie sehen, ist die Zeilennummer bei D_Title in unserem Beispiel 2. Das bedeutet, daß die Dialogbox, die ja immer in Zeile 1 anfängt, über dem Titel noch eine Leerzeile hat. |
| D_Text Line_No,Txt$ |
| Definiert eine Textzeile in der Dialogbox. |
| Dieser Aufruf erzeugt eine Textzeile in Ihrer Dialogbox. Line_No ist wieder die Zeile innerhalb der Dialogbox, in der der Text erscheinen soll. Txt$ ist der Text selbst. |
| D_Button Line_No,Txt$ |
| Normale Knöpfe definieren. |
| D_Radiobutton Line_No,Txt$ |
| Radioknöpfe definieren. |
| D_Checkbox Line_No,Txt$ |
| Ankreuzkästchen definieren. |
| D_Exitbutton Line_No,Txt$[,Defaultbutton] |
| Ausgangsknöpfe definieren. |
| Mit diesen Befehlen können Sie die vier verschiedenen Knopfsorten
definieren. Jedesmal gibt Line_No die Zeile innerhalb der Dialogbox an, in der der jeweilige Knopf (die jeweiligen
Knöpfe) erscheinen soll(en). Txt$ enthält Informationen über die Knöpfe und die Texte, die sonst noch in der Zeile stehen sollen. Defaultbutton ist ein Parameter, mit dem Sie festlegen können, welcher Ausgangsknopf auch durch einfaches Drücken der Return-Taste ausgelöst werden kann. Dieser Knopf wird dann mit einer dicken Umrandung dargestellt. Wenn die Dialogbox kein Schliessfeld enthält (Type=0), muss sie eine Möglichkeit enthalten, wie man sie wieder verlassen kann. Das kann nur über Ausgangsknöpfe erfolgen. Deshalb muß jede Dialogbox vom Typ 0 mindestens einen solcher Ausgangsknöpfe enthalten, sonst meldet EasyGem einen Fehler. Der Aufbau von Txt$ ist nicht ganz einfach. Ein Beispiel macht am besten klar, wie Txt$ verwendet werden muß: |
| D_Radiobutton 4, "Richtig?[Ja][Nein][Vielleicht]" |
| Diese Zeile definiert in der 4. Zeile der Dialogbox drei Radioknöpfe mit den Inhalten [Ja], [Nein] und [Vielleicht] und davor den Text "Richtig?": |
|
Richtig? |
[Ja] |
[Nein] |
[Vielleicht] |
|
normaler Text |
1. Knopf |
2. Knopf |
3. Knopf |
| In einer Zeile mit Knöpfen können also auch Texte stehen. Alles, was in eckigen Klammern steht, ist ein Knopf, und alles andere ein Text. Auch zwischen den eckigen Klammern können noch Texte stehen. |
| Wenn Sie bei D_Exitbutton mit dem Parameter Defaultbutton einen Ausgangsknopf von mehreren durch Drücken von [Return] anwälbar machen wollen, müssen Sie der Prozedur D_Exitbutton die sogenannte Objektnummer dieses Knopfes übergeben. Die Objektnummer erhalten Sie einfach, indem Sie die einzelnen Textstücke und Buttons zählen. So ist das Objekt Nr. 1 in der Beispielzeile mit D_Radiobutton nicht der Knopf [Ja], sondern der Text "Richtig?"! Der Knopf [Ja] ist Objekt Nr. 2, [Nein] Objekt Nr. 3 usw.. Wenn Sie Leerzeichen zwischen den Knöpfen haben, um z.B. den Abstand der Knöpfe zu vergrößern, zählen diese natürlich wieder als Text und haben ihre eigene Objektnummer, die Sie beim Zählen nicht vergessen dürfen! |
| Beispiel: Wir definieren eine Zeile mit den Ausgangsknöpfen [Löschen] und [Abbruch], wobei [Abbruch] der Default-Button sein soll. |
| D_Exitbutton 7,"Wollen Sie: [Löschen] oder [Abbruch] ?",4 |
| Der Knopf [Abbruch] ist hier Objekt Nr. 4! Objekt 1 ist der Text "Wollen Sie: ", Objekt 2 ist der Knopf [Löschen], Objekt 3 ist der Text " oder ", Objekt 4 ist der Knopf [Abbruch] und Objekt 5 ist der Text " ?". |
| D_Empty Line_No |
| Leerzeile in der Dialogbox definieren. |
| Diese Prozedur definiert eine leere Textzeile. Sie können sie benutzen, um die Objekte innerhalb der Dialogbox zu gruppieren. |
| Achtung: Ab EasyGem 4.0 ist die Höhe einer Zeile nicht mehr konstant, sondern von dem in dieser Zeile definierten Objekt abhängig. Darum muss jede Zeile definiert werden und die Definitionen müssen nach Zeilennummern in aufsteigender Reihenfolge erfolgen. Soll eine Zeile leer bleiben, so muss für diese Zeile ein D_Empty angegeben werden. |
| D_Input Line_No,Txt$,Input_Len[,Flag] D_Input Line_No,Txt$ |
| Definiert eine Eingabezeile. |
| Line_No gibt wieder an, in
welcher Zeile der Dialogbox die Eingabe stattfinden soll. Txt$ enthält den Text, der links neben der eigentlichen Eingabe ausgegeben werden soll. Input_Len gibt die maximale Länge des einzugebenden Ausdrucks in Zeichen an. Flag hat keine Bedeutung mehr und kann daher auch weggelassen werden. |
| Beispiel: |
| D_Input 7,"Geben Sie Ihren Druckertyp ein: ",6 |
| Diese Zeile definiert in Zeile 7 der Dialogbox ein Eingabefeld, in
das man maximal 6 Zeichen eingeben kann. Ab EasyGem 4.0 gibt es eine zweite Variante des Input-Befehls. Er hat nur zwei Parameter, ermöglicht damit aber die Definition von mehreren Eingabefeldern pro Zeile. Dazu muss in Txt$ ein String übergeben werden, wie Sie ihn von D_Button bereits kennen. |
| Beispiel: |
| D_Input 7,"Breite:[ ] Höhe:[ ]" |
| D_Output Line_No,Txt$,Output_Len |
| Definiert eine Ausgabezeile. |
| Line_No gibt auch hier wieder
die Zeile an, in der ein Text ausgegeben werden soll. Txt$ wird wie bei D_Input fest in die Zeile geschrieben. Output_Len ist die Länge des Textes, der außerdem noch ausgegeben werden kann. Diesen Text können Sie während des Programmlaufs ändern. |
| D_Popup Line_No,Txt$,Popup_Id |
| Definiert ein Popup-Button. |
| Line_No gibt wieder an, in
welcher Zeile der Dialogbox die Eingabe stattfinden soll. Txt$ enthält den Text, der links neben dem Popup-Button ausgegeben werden soll. Popup_Id ist die Identifikationsnummer eines Popup-Menüs, das Sie natürlich vorher mit den Funktionen der Menu Library definiert haben müssen |
| Beispiel: |
| D_Popup 2,"Popup-Menü:",Popup_Id |
| Ab EasyGem 4.0 gibt es noch einige weiter Prozeduren und Funktionen,
mit denen man das Erscheinungsbild einer Dialogbox beeinflussen kann. Wie Sie an den vorherigen Beispielen erkennen können, sind die Positionen der einzelnen Objekte allein durch die Buchstaben in der Definitionszeile bestimmt. Diese Informationen muss EasyGem natürlich irgendwie in Pixelwerte umrechnen. Dazu wird für jedes Textzeichen eine feste Pixelbreite angenommen und ausserdem zwischen den Objekten und zwischen den Zeilen zusätzlich Platz reserviert. Diese Einstellungen können Sie mit den folgenden Funktionen abfragen und auch verändern: |
| D_Setcellwidth Width |
| Stellt die Breite ein, die pro Buchstabe reserviert wird. |
| FN D_Getcellwidth |
| Fragt die eingestellte Zellenbreite ab. |
| D_Setspace Width, Height |
| Damit stellen Sie den Zwischenraum zwischen den Objekten bzw. zwischen den Zeilen ein. |
| D_Getspace R Width, R Height |
| Abfrage der Zwischenräume. |
| Im allgemeinen werden Sie diese Prozeduren und Funktionen nicht benötigen, da EasyGem die Objekte mit den Standardeinstellungen recht gut positioniert. |
| Nach der Definition einer Dialogbox sind zunächst alle Objekte anwählbar. Manchmal möchte man jedoch, dass abhängig vom jeweiligen Kontext einige Objekte nicht anwählbar sind, weil dies aktuell keinen Sinn machen würde. Dafür gibt es die beiden Prozeduren: |
| D_Enable Dialog_Id,Line_No,Object_No |
| Objekt anwählbar machen. |
| D_Disable Dialog_Id,Line_No,Object_No |
| Objekt nicht anwählbar machen. |
| Diese Befehle funktionieren genau so, wie Sie es bereits aus der Menu Library kennen. Wenn ein Objekt nicht anwählbar ist, wird es in grau dargestellt. |
| 3.3 Aufruf einer Dialogbox Nun haben wir alle Befehle zur Definition einer Dialogbox kennengelernt und können beliebige Dialogboxen definieren. Bevor wir ein ausführbares Programm schreiben können, benötigen wir aber noch eine Möglichkeit, die Dialogbox auch auf den Bildschirm zu bringen. Dazu dient die folgende Prozedur: |
| Easy_Dialog Dialog_Id |
| Easy_Dialog Box$,Dialog_Id[,R Object_No[,R Line_No]] |
| Easy_Dialog Dialog_Id,X,Y,R Object_No,R Line_No |
| Stellt die Dialogbox dar. |
| Box$ hat keine
Bedeutung und ist wieder nur aus Kompatibilitätsgründen vorhanden. Dialog_Id ist bekanntlich die Identifikations-Nummer, die Sie bei Def_Dialog zurückerhalten haben. Object_No ist die Objektnummer innerhalb der Zeile, in der der angeklickte Exitbutton liegt. Line_No ist die Zeilennummer, in der sich der angeklickte Exitbutton befindet. Diese Angabe benötigen Sie nur, wenn Sie mehrere Zeilen mit Exitbuttons haben. Mit X und Y können Sie bestimmen, wo auf dem Bildschirm die Dialogbox dargestellt werden soll. X=0 und Y=0 bewirken eine zentrierte Darstellung. Der Befehl Easy_Dialog kehrt erst wieder zurück, wenn der Benutzer einen Exitbutton angeklickt oder die Taste [Return] gedrückt hat. Damit können wird jetzt unser erstes voll funktionsfähiges Beispielprogramm schreiben: |
| COMPILER "MIN_SIZE 1000000" COMPILER "BAS_MEM 1000000" COMPILER "Warnings off" Easy_Init 'Dialogbox definieren. Def_Dialog Dialog1,"Beispiel",1 D_Radiobutton 1,"Richtig?[Ja][Nein][Vielleicht]" D_Empty 2 D_Exitbutton 3," [ Ok ]",2 End_Dialog 'Dialogbox darstellen. Easy_Dialog Dialog1 Easy_Exit END |
| Für Profis: Die Prozedur Easy_Dialog besteht genaugenommen aus folgenden Unterprozeduren, die Sie natürlich auch einzeln aufrufen können: |
| D_Show [Box$,]Dialog_Id |
| D_Show Dialog_Id,X,Y |
| Dialogbox darstellen. |
| Stellt die Dialogbox mit der Identifikationsnummer Dialog_Id dar. Mit X und Y können Sie bestimmen, wo auf dem Bildschirm die Dialogbox angezeigt werden soll. X=0 und Y=0 bewirken eine zentrierte Darstellung. |
| D_Redraw Dialog_Id[,Line_No] |
| Dialogbox neu zeichnen. |
| Die Dialogbox wird neu gezeichnet. Mit Line_No kann bestimmt werden, daß nur diese eine Zeile neu gezeichnet wird. |
| D_Edit Dialog_Id[,R Objekt_No[,R Line_No]] |
| Dialogbox neu zeichnen und editieren. |
| D_Edit_ Dialog_Id[,R Objekt_No[,R Line_No]] |
| Dialogbox editieren. |
| Diese beiden Prozeduren lassen den Benutzer Eingaben in der Dialogbox machen. Bei der ersten wird vorher noch D_Redraw aufgerufen. |
| D_Event Dialog_Id,R Object_No[,R Line_No[,R Entry]] |
| Ein Ereignis auswerten. |
| Diese Prozedur funktioniert so ähnlich, wie D_Edit_, nur daß sie sofort zurückkehrt, auch wenn noch kein Ausgangsknopf gedrückt wurde. Dadurch behalten Sie die Kontrolle über den Programmablauf, müssen dafür aber auch selbst dafür sorgen, daß die Dialogbox zum gegebenen Zeitpunkt wieder vom Bildschirm verschwindet. Dazu dient der Befehl: |
| D_Hide Dialog_Id |
| Dialogbox schließen. |
| Entfernt die Dialogbox vom Bildschirm. Sie können diese Einzelprozeduren benutzen, um von Ihrem Programm aus die Dialogbox detaillierter zu kontrollieren. Wenn Sie nämlich nur Easy_Dialog aufrufen, kehrt die Prozedur ja erst zurück, sobald ein Exitbutton ausgewählt wurde. Wenn man aber z.B. beim Bearbeiten einer Datei fortlaufend anzeigen möchte, wie weit der Prozeß fortgeschritten ist, würde man die Dialogbox zunächst nur mit D_Show darstellen und dann mit D_Redraw ständig aktualisieren. Nach Beendigung der Arbeit könnte dann die Dialogbox mit D_Hide wieder entfernt werden oder man ruft vorher noch D_Edit_ auf, damit der Anwender [OK] anklickt oder andere Aktionen auslöst. Um die Vorgehensweise deutlich zu machen, geben wir noch ein Beispiel an. Es sollen Datum und Uhrzeit in einer Dialogbox dargestellt werden. Die Uhrzeit soll dabei in Intervallen von einer Sekunde aktualisiert werden. |
| Beispiel: |
| COMPILER "MIN_SIZE 1000000" COMPILER "BAS_MEM 1000000" COMPILER "Warnings off" Easy_Init 'Dialogbox definieren. Def_Dialog Date_Time,"Datum und Zeit",1 D_Output 1,"Datum ",12 D_Output 2,"Zeit ",12 D_Empty 3 D_Exitbutton 4," [Abbruch]",2 End_Dialog 'Variablen und Dialogbox initialisieren. Tim=TIMER Dialog_Text$(1,Date_Time)=DATE$ Dialog_Text$(2,Date_Time)=TIME$ 'Dialogbox darstellen und in einer Schleife aktualisieren. D_Show Date_Time REPEAT IF TIMER >Tim+200 THEN Dialog_Text$(2,Date_Time)=TIME$ D_Redraw Date_Time,2:'Nur Zeile 2 aktualisieren. Tim=TIMER ENDIF 'Testen ob [Abbruch] gedrückt wurde. D_Event Date_Time,Object_No 'Hier könnte noch weiterer Programmcode stehen. UNTIL Object_No D_Hide Date_Time:'Dialogbox wieder entfernen. Easy_Exit END |
| Hinweis: Während die Dialogbox auf dem Bildschirm dargestellt wird, können Sie natürlich nicht in anderen Fenstern weiterarbeiten, da es sich um eine modale Dialogbox handelt. Ihr Programm kann aber im Hintergrund z.B. einige Berechnungen durchführen oder einen virtuellen Bildschirm aufbauen, der dann nach dem Verlassen der Dialogbox dargestellt wird. |
| 3.4 Auswertung einer Dialogbox Die bisher besprochenen Befehle sind geeignet, eine Dialogbox zu definieren und auf dem Bildschirm darzustellen. Natürlich muß man hinterher auch feststellen können, welche Knöpfe angeklickt wurden, welchen Text der Anwender in die Dialogbox geschrieben hat usw.. Wie das geht, erfahren Sie jetzt. Wie man feststellt, mit welchem Exitbutton die Dialogbox verlassen wurde, haben wir ja schon bei Easy_Dialog beschrieben. Um das Ganze auch mit anderen Knöpfen und den Texten zu ermöglichen, gibt es zwei globale Variablenfelder, in denen EasyGem die gewünschten Informationen speichert. Fangen wir mit den Knöpfen an. Zuständig dafür ist das Variablenfeld: |
| Dialog_Button%F(Line_No,Object_No,Dialog_Id) |
| Knopfzustand ermitteln oder setzen. |
| Wie Sie sehen, handelt es sich um ein sogenanntes Flagfeld (%F). Die Feldelemente können nur zwei Zustände annehmen: falsch=(0) oder wahr=(-1). 0 steht bei Buttons stets für "nicht selektiert" (Darstellung auf dem Bildschirm: normal), -1 steht für selektiert (Darstellung auf dem Bildschirm: invertiert bzw. angekreuzt etc.). Line_No gibt die Zeile innerhalb der Dialogbox an, deren Zustand wir ermitteln wollen, und Object_No ist die Nummer des Objekts innerhalb der Zeile (die Objekte werden so numeriert wie bei D_Exitbutton beschrieben). Wie Sie sehen, hat also nicht nur jeder Knopf, sondern auch jeder Text die ihm zugeordnete Variable. Allerdings ist diese bei Texten immer null, da Texte ja nicht durch Anklicken selektiert werden können. |
| Beispiel: |
| COMPILER "MIN_SIZE 1000000" COMPILER "BAS_MEM 1000000" COMPILER "Warnings off" COMPILER "OPW 320*200" Easy_Init Def_Dialog Dialog1,"Beispiel",1 D_Radiobutton 1,"Richtig?[Ja][Nein][Vielleicht]" D_Empty 2 D_Exitbutton 3," [ Ok ]",2 End_Dialog Dialog_Button%F(1,2,Dialog1)=-1:'Ja ist default. Easy_Dialog Dialog1 M_Show 0:GRAF_PORT 0 IF Dialog_Button%F(1,2,Dialog1) THEN PRINT "Ja wurde angeklickt!" IF Dialog_Button%F(1,3,Dialog1) THEN PRINT "Nein wurde angeklickt!" IF Dialog_Button%F(1,4,Dialog1) THEN PRINT "Vielleicht wurde angeklickt!" REPEAT COMPILER "Event" UNTIL 0 Easy_Exit END |
| Indem Sie den Inhalt der jeweiligen Variablen abfragen, können
Sie also feststellen, welcher Knopf tatsächlich gedrückt wurde. Das funktioniert
natürlich auch in umgekehrter Richtung: Wenn Sie vor dem Aufruf von Easy_Dialog einen Knopf
auf "selektiert" (also ungleich null) setzen, so ist dieser beim Aufruf
der Dialogbox bereits selektiert. In unserem Demoprogramm weiter hinten wird die
Verwendung des Feldes Dialog_Button%F für diesen Zweck an einem Beispiel dargestellt. Für eine Zeile mit Radiobuttons, von denen ja nur maximal einer angeklickt sein kann, gibt es übrigens auch eine Funktion, die direkt die Nummer des Knopfes zurückgibt: |
| FN Rbutton(Line_No,Dialog_Id) |
| 'Nummer des gedrückten Radioknopfs ermitteln. |
| Gibt die Objektnummer des ausgewählten Knopfes in einer Radiobutton-Zeile.
Wenn kein Knopf ausgewählt war, wird eine null zurückgegeben. Ähnlich funktioniert das ganze bei den Texten von D_Input. Dafür gibt es zwei Textfelder. Das Feld mit zwei Parametern können Sie für Input-Befehle verwenden, die nur ein Eingabefeld pro Zeile haben. Wenn Sie mehrere Eingabefelder pro Zeile verwenden wollen, so müssen Sie mit dem Textfeld arbeiten, das zusätzlich noch die Objektnummer als dritten Parameter enthält: |
| Dialog_Text$(Line_No[,Object_No],Dialog_Id) |
| Text in Zeile Line_No ermitteln oder setzen. |
| Man kann damit einen Text initialisieren und nachher wieder abfragen,
wie an dem nachfolgenden Demoprogramm gezeigt. Bei D_Output sieht das Ganze genauso aus. Es ist aber nicht sehr sinnvoll, den Text wieder abzufragen, da er ja vom Anwender nicht geändert werden kann. Wenn Sie übrigens alle Knöpfe und alle Texte einer Dialogbox löschen wollen, gibt es auch dafür einen Befehl: |
| Clear_Parameter(Dialog_Id) |
| Alle Knöpfe und Texte einer Dialogbox löschen. |
| Dialog_Id ist natürlich wieder die Identifikations-Nummer der Dialogbox. |
| 3.5 Menüs und modale Dialogboxen Wenn eine modale Dialogbox geöffnet wird, empfiehlt es sich, vorher alle Menüeinträge zu deaktivieren, da der Anwender bei einer modalen Dialogbox ja nur Funktionen innerhalb der Dialogbox anwählen kann. Wenn Ihre Dialogbox Eingabefelder enthält, sollten Sie die Menüfunktionen zum Ausschneiden, Kopieren, Einsetzen und Löschen aber aktiv lassen, um dem Anwender die Möglichkeit zu geben, Texte in der Dialogbox über das Clipboard auszutauschen. Das erfordert natürlich schon etwas mehr Programmieraufwand. Das folgende Beispiel zeigt wie es geht: |
| COMPILER "MIN_SIZE 1000000" COMPILER "BAS_MEM 1000000" COMPILER "Warnings off" Extension_Init Easy_Init 'Menü definieren. Def_Menu Menu1,"Über dieses Programm",Info M_Title "Datei",File1 M_Entry "Modale Dialogbox",Modal_Dialog1 M_Line_Entry M_Entry "Quit/Q",Quit1 M_Title "Bearbeiten",Edit1 M_Entry "Ausschneiden/X",Cut1 M_Entry "Kopieren/C",Copy1 M_Entry "Einsetzen/V",Paste1 M_Entry "Löschen",Clear1 End_Menu 'Dialogbox definieren. Def_Dialog Dialog1,"Modale Dialog",1 D_Input 1,"Input Box 1",10 D_Input 2,"Input Box 2[ ]Input Box 3[ ]" D_Empty 3 D_Exitbutton 4," [Abbruch] [ OK ]",4 End_Dialog Dialog_Text$(1,Dialog1)="Input 1" Dialog_Text$(2,2,Dialog1)="Input 2" Dialog_Text$(2,4,Dialog1)="Input 3" M_Show Menu1 'Hauptereignisschleife. REPEAT Easy_Mesag Entry 'Auf Menüaktionen und Apple-Events untersuchen. IF Entry THEN SELECT Entry CASE Modal_Dialog1:Open_Modal_Dialog CASE Quit1,CVIL("quit"):Quit_Program END_SELECT ENDIF UNTIL 0 DEF PROC Quit_Program Easy_Exit Extension_Exit END END_PROC DEF PROC Open_Modal_Dialog LOCAL Con,Object_No,Entry,Sel_Start,Sel_End,Scrap$,T$ M_Disable Menu1,File1:M_Draw:'Datei-Menü deaktivieren. D_Show Dialog1:'Dialogbox darstellen. REPEAT D_Event Dialog1,Object_No,0,Entry IF Entry THEN 'Es wurde ein Menüpunkt angeklickt. Con=FN Con_Getkeyfocus(Dialog1) IF Con THEN 'Die Dialogbox hat ein aktives Text-Eingabefeld. SELECT Entry CASE Cut1 Con_Getselect Con,Sel_Start,Sel_End:T$=FN Con_Gettext$(Con) T$=FN Con_Gettext$(Con) Put_Scrap CVIL("TEXT"),MID$(T$,Sel_Start+1,Sel_End-Sel_Start) Con_Settext Con,LEFT$(T$,Sel_Start)+MID$(T$,Sel_End+1) Con_Setselect Con,Sel_Start,Sel_Start CASE Copy1 Con_Getselect Con,Sel_Start,Sel_End T$=MID$(FN Con_Gettext$(Con),Sel_Start+1,Sel_End-Sel_Start) Put_Scrap CVIL("TEXT"),T$ CASE Paste1 Con_Getselect Con,Sel_Start,Sel_End T$=FN Con_Gettext$(Con) Scrap$=FN Get_Scrap$(CVIL("TEXT")) Con_Settext Con,LEFT$(T$,Sel_Start)+Scrap$+MID$(T$,Sel_End+1) Sel_Start+=LEN(Scrap$) Con_Setselect Con,Sel_Start,Sel_Start CASE Clear1 Con_Getselect Con,Sel_Start,Sel_End T$=FN Con_Gettext$(Con) Con_Settext Con,LEFT$(T$,Sel_Start)+MID$(T$,Sel_End+1) Con_Setselect Con,Sel_Start,Sel_Start END_SELECT ENDIF ENDIF UNTIL Object_No:'Bis ein Ausgangsknopf angeklickt wurde. D_Hide Dialog1 M_Enable Menu1,File1:M_Draw:'Datei-Menü wieder aktivieren. END_PROC |
| Um dieses Programm ausprobieren zu können, müssen Sie neben
der EasyGem Library auch noch die Extension Library zuladen. Für die Realisierung der Funktionen zum Ausschneiden, Kopieren, Einsetzen und Löschen von Texten werden Befehle aus der Control Library benutzt, die hier nicht weiter erklärt werden können. Eine genaue Beschreibung finden Sie in dem Kapitel "Die Control Library". Hinweis: Bei editierbaren Textfeldern funktionieren die Tastenkombinationen [Cmd]+[X], [Cmd]+[C] und [Cmd]+[V] zum Ausschneiden, Kopieren und Ersetzen auch dann, wenn kein Edit-Menü vorhanden ist. |
| 3.6 Nichtmodale Dialogboxen Ab EasyGem 4.0 ist es möglich, auch nichtmodale Dialogboxen (Type=2 bei Def_Dialog) zu verwenden. Eine nichtmodale Dialogbox blockiert die Ausführung Ihres Programms nicht; sie kann also permanent geöffnet bleiben, während Sie an anderen Dingen arbeiten. Damit ergibt sich allerdings ein neues Problem: Bei einer modalen Dialogbox ist es ja so, dass Sie vom Anwender geschlossen wird, nachdem die gewünschten Einstellungen vorgenommen wurden. Nach der Rückkehr von Easy_Dialog kann Ihr Programm dann die Dialogbox-Felder auswerten und entsprechend darauf reagieren. Da eine nichtmodale Dialogbox normalerweise nicht geschlossen wird, muss man sich hierfür einen anderen Mechanismus ausdenken, um auf die Aktionen des Anwenders reagieren zu können. In EasyGem gibt es dafür die Möglichkeit, jedem Objekt eine sogenannte Action-Funktion zuzuordnen. Diese wird immer dann aufgerufen, wenn der Anwender das Objekt angewählt hat. Bei einem normalen Button ist dies z.B. genau dann der Fall, wenn die Maus über dem Button losgelassen wird. |
| D_Setaction Dialog_Id,Line_No,Object_No,Act_Fun |
| Action-Funktion für das durch Dialog_Id,Line_No und Object_No spezifizierte Objekt setzen. |
| Die Action-Funktion müssen Sie selbst definieren. Sie muss vom
Typ Long-Integer sein und drei Parameter übernehmen. DEF FN My_Action(Dialog_Id,Line_No,Object_No) In den Parametern werden Ihrer Action-Funktion die Dialog-Identifikationsnummer, die Zeilennummer und die Objektnummer übergeben, so dass Sie das Objekt, auf das der Anwender geklickt hat, eindeutig identifizieren können. In Act_Fun übergeben Sie dann die Adresse dieser Funktion: Act_Fun=&FN My_Action(,,) Das folgende Beispiel verdeutlicht die einzelnen Schritte: |
| COMPILER "MIN_SIZE 1000000" COMPILER "BAS_MEM 1000000" COMPILER "Warnings off" COMPILER "OPW 320*200" Easy_Init 'Menü definieren. Def_Menu Menu1,"Über dieses Programm",Info M_Title "Datei",File1 M_Entry "Dialogbox 1 öffnen",Open_Dialog1 M_Entry "Dialogbox 2 öffnen",Open_Dialog2 M_Line_Entry M_Entry "Quit/Q",Quit1 End_Menu 'Erste Dialogbox definieren. Def_Dialog Dialog1,"Planeten",2 D_Radiobutton 1,"[Merkur][Venus][Erde][Mars]" D_Checkbox 2,"[Masse][Radius][Atmosphäre ]" D_Empty 3 D_Button 4," [Ausführen]" End_Dialog 'Zweite Dialogbox definieren. Def_Dialog Dialog2,"Sterne",2 D_Radiobutton 1,"[Sonne][Sirius][Rigel]" D_Checkbox 2,"[Entfernung][Helligkeit][Temperatur]" D_Empty 3 D_Button 4," [Ausführen]" End_Dialog 'Dialog-Buttons initialisieren. Dialog_Button%F(1,3,Dialog1)=-1 Dialog_Button%F(1,1,Dialog2)=-1 'Action-Funktionen zuordnen. D_Setaction Dialog1,4,2,&FN Display_Status(,,) D_Setaction Dialog2,4,2,&FN Display_Status(,,) M_Show Menu1 'Hauptereignisschleife. REPEAT Easy_Mesag Entry,Buffer$ 'Auf Menüaktionen und Apple-Events untersuchen. IF Entry THEN SELECT Entry CASE Open_Dialog1:D_Show Dialog1 CASE Open_Dialog2:D_Show Dialog2 CASE Quit1,CVIL("quit"):Quit_Program END_SELECT ELSE Win_Domessages Buffer$ ENDIF UNTIL 0 DEF PROC Quit_Program Easy_Exit END END_PROC 'Action-Funktion definieren. DEF FN Display_Status(Id,Lin,Obj) GRAF_PORT 0:CLS 'Zustand der Dialogboxen ausgeben. SELECT Id CASE Dialog1 SELECT FN Rbutton(1,Id) CASE 1:PRINT "Merkur" CASE 2:PRINT "Venus" CASE 3:PRINT "Erde" CASE 4:PRINT "Mars" END_SELECT IF Dialog_Button%F(2,1,Id) THEN PRINT "Masse" IF Dialog_Button%F(2,2,Id) THEN PRINT "Radius" IF Dialog_Button%F(2,3,Id) THEN PRINT "Atmosphäre" CASE Dialog2 SELECT FN Rbutton(1,Id) CASE 1:PRINT "Sonne" CASE 2:PRINT "Sirius" CASE 3:PRINT "Rigel" END_SELECT IF Dialog_Button%F(2,1,Id) THEN PRINT "Entfernung" IF Dialog_Button%F(2,2,Id) THEN PRINT "Helligkeit" IF Dialog_Button%F(2,3,Id) THEN PRINT "Temperatur" END_SELECT END_FN |
| An diesem Beispiel können Sie selbst ausprobieren, wie eine nichtmodale
Dialogbox funktioniert. Nachdem Sie eine Dialogbox geöffnet haben, können
Sie über das Menü auch noch die zweite öffnen. Sie können zwischen
den Dialogboxen wechseln, indem Sie einfach mit der Maus in die jeweils andere Box
klicken. Sobald Sie auf einen der "Ausführen" Knöpfe klicken, wird Ihre Action-Funktion Display_Status aufgerufen und der Zustand der Radiobuttons und Checkboxes im Fenster ausgegeben. Hinweis: Um nichtmodale Dialogboxen verwalten zu können, benötigen Sie eine erweiterte Form von Easy_Mesag und die Prozedur Win_Domessages. Beide werden in dem Kapitel über die Fenster-Programmierung erklärt. |
| 3.7 Verbindung zur Control Library Bei den Objekten, die Sie mit der Dialog Library definieren können, handelt es sich um sogenannte Controls. Die Dialog Library programmiert also die Control Library, indem Sie verschiedenen Funktionen zusammenfasst, durch die Einteilung in Zeilen eine einfache und übersichtliche Identifikation der Objekte ermöglicht und einen grossen Teil der Verwaltung übernimmt. Der Nachteil dieser Methode besteht darin, dass man nicht mehr so viele Möglichkeiten hat, auf die einzelnen Objekte individuell zuzugreifen. Um diesen Nachteil zumindest teilweise wieder auszugleichen, gibt es die folgende Funktion: |
| FN D_Controlid(Dialog_Id,Line_No,Object_No) |
| Gibt die Control-Identifikationsnummer des durch Dialog_Id,Line_No und Object_No spezifizierten Objektes zurück. |
| Damit können Sie also die Control-Identifikationsnummer für
jedes einzelne Objekt in Ihrer Dialogbox ermitteln. Mit dieser Nummer kann man dann
die Funktionen der Control Library auf das entsprechende Objekt anwenden und dieses
dadurch z.B. mit Con_Setborder pixelweise positionieren oder Textfarbe, Textstil, Textgrösse usw.
mit Con_Fontstyle
verändern. Zum Abschluss noch ein Beispielprogramm, das eine Übersicht über die bisher vorgestellten Objekte vermittelt: |
| COMPILER "MIN_SIZE 1000000" COMPILER "BAS_MEM 1000000" COMPILER "Warnings off" Easy_Init 'Menü definieren. Def_Menu Menu1,"Über dieses Programm",Info M_Title "Datei",File1 M_Entry "Modale Dialogbox",Modal_Dialog1 M_Line_Entry M_Entry "Quit/Q",Quit1 End_Menu 'Popup-Menü definieren. Def_Popup Particles M_Entry "Photon",Photon M_Entry "Neutrino",Neutrino M_Entry "Electron",Electron M_Entry "Proton",Proton M_Entry "Neutron",Neutron End_Popup 'Dialogbox definieren. Def_Dialog Mm_Dialog,"Bewegliche modale Dialogbox",1 D_Text 1,"Dies ist ein Beispiel für Demonstrationszwecke." D_Empty 2 D_Checkbox 3,"Checkboxes [Checkbox 1][Checkbox 2][Checkbox 3]" D_Radiobutton 4,"Radio Buttons[Button 1 ][Button 2 ][Button 3 ]" D_Input 5,"Input Box 1",10 D_Input 6,"Input Box 2[ ] Input Box 3[ ]" D_Popup 7,"Partikel",Particles D_Empty 8 D_Exitbutton 9," [Abbruch] [ OK ] ",4 End_Dialog Con=FN D_Controlid(Mm_Dialog,1,1):Con_Setborder Con,0,400,20 Con_Setfontstyle Con,0,13,%101,0,0,7,1 Dialog_Button%F(3,2,Mm_Dialog)=-1 Dialog_Button%F(3,4,Mm_Dialog)=-1 Dialog_Button%F(4,3,Mm_Dialog)=-1 Dialog_Text$(5,Mm_Dialog)="Input 1" Dialog_Text$(6,2,Mm_Dialog)="Input 2" Dialog_Text$(6,4,Mm_Dialog)="Input 3" Dialog_Button%F(7,3,Mm_Dialog)=-1 M_Show Menu1 'Hauptereignisschleife. REPEAT Easy_Mesag Entry 'Auf Menüaktionen und Apple-Events untersuchen. IF Entry THEN SELECT Entry CASE Modal_Dialog1:Open_Modal_Dialog CASE Quit1,CVIL("quit"):Quit_Program END_SELECT ENDIF UNTIL 0 DEF PROC Quit_Program Easy_Exit END END_PROC DEF PROC Open_Modal_Dialog LOCAL Object_No M_Disable Menu1,File1:M_Draw:'Datei-Menü deaktivieren. Easy_Dialog Mm_Dialog,MOUSEX,MOUSEY,Obj_No,0:'Dialogbox an der 'aktuellen Mausposition aufrufen. If Obj_No=4 THEN 'OK wurde angeklickt. ELSE 'Abbruch wurde angeklickt. ENDIF M_Enable Menu1,File1:M_Draw:'Datei-Menü wieder aktivieren. END_PROC |
|
|
|
© 1998-2000 www.berkhan.de | Online bestellen |