Logo: Geos Online Print Archiv
G.O.P.A. - Geos Online Print Archiv
24.04.2024 Archiv  #  Recherche  #  Links  #  Kontakt  #  Gästebuch  #  Impressum

Index
Register
Login

Die Anzeige des Archivs erfolgt grafisch. Ändern

Kurs: Programmieren (Teil 4)

Autor: H. J. Ciprina

In dieser Folge wird der Quelltext aus der letzten GUP besprochen. Wer die GUP 17 und somit den Quelltext nicht hat, findet diesen zusammen mit dem assemblierten Programm auf der Diskette GUP 17 und GUP 18 (erhältlich wie alle anderen GUP Ausgaben auf Diskette bei Martin Sauter; Versand wie bei den GeoThek Disketten).

Der erste Teil des Listings ähnelt dem Programm aus dem letzten Heft, zwischen ";Lab1" und ";Lab2" liegt eine kleine Ergänzung vor. GEOS erwartet neben den Menüs auch die Installation von Icons (Piktogramme). Sofern man keine Icons installiert, kann es zu einem Fehlverhalten von GEOS kommen. Aus diesem Grund haben wir in diesem Programm ein nicht-anwählbares Icon installiert. Bei der Installation geht man genauso vor, wie bei der Installation von Menüs: man übergibt in r0 einfach einen Zeiger auf die Iconinformationen (auf die spezielle Struktur einer Icontabelle gehen wir in einem späteren Kursteil ausführlicher ein).

Ab dem Label HMLinks beginnt die Definition des Hauptmenüs; diesmal werden 3 Menüpunkte horizontal angeordnet (b3!HORIZONTAL). Das Hauptmenü sollte bei Anwendungen (Applikationen) immer in der linken oberen Ecke liegen. Die Höhe des Menüpunktes beträgt in der Regel 14 Pixel.
Die Berechnung der Breite des Menüs ist ungleich schwieriger, da aufgrund der Proportionalschrift die einzelnen Buchstaben unterschiedlich breit sind. Im Buch zum MegaAssembler haben wir mehrere Näherungsverfahren zur Menübreite angegeben, jedoch auch hier gilt: "Probieren geht über Studieren".

Jeder Menüpunkt besteht aus einer Word-Byte-Word-Kombination: Das erste Word zeigt auf den Text, unter dem der Menüpunkt erscheinen soll, dann folgt ein Funktionsbyte, sowie ein Zeiger auf die spezielle Menüfunktion.

GEOS kennt drei verschiedene Funktionsbytes:

1. MENU_ACTION
Dieses Funktionsbyte kennzeichnet einen Menüpunkt, bei dessen Anwahl eine Aktion (z.B. Rückkehr zum DeskTop, schließen einer Datei etc.) hervorgerufen wird. Das sich an das Byte anschließende Word bildet einen Zeiger auf die Routine, die bei Anwahl des Menüpunktes angesprungen werden soll.

2. SUB_MENU
Wie der Name dieses Funktionsbytes schon besagt, kennzeichnet dieses Byte ein Unter-(Unter-)Menü. Das sich auf dieses Byte anschließende Word bildet einen Zeiger auf die Untermenüstruktur!

3. DYN_SUB_MENU
Dieses Funktionsbyte kennzeichnet spezielle Untermenüs. In einigen Fällen ist es sinnvoll, daß vor dem Darstellen eines Untermenüs noch eine Aktion hervorgerufen werden soll. Beispielsweise muß GEOPAINT bei Anwahl eines Hauptmenüpunktes die unter dem Menü liegenden Farben retten. TopDesk nutzt diese Menüart um bei Anwahl des Menüpunktes "geos" die auf dem aktuellen Laufwerk vorliegenden DeskAccessories einzulösen. Das sich an dieses Funktionsbyte anschließenden Word zeigt auf eine Routine, die vor dem Aufbau des Menüs angesprungen werden soll. Die Menüroutine muß immer so verlassen werden, daß in r0 ein Zeiger auf das darzustellende Untermenü übergeben wird.
Zum besseren Verständnis haben wir im Listing alle Funktionsarten eingebaut.

Vom Hauptmenü gehen in der Regel Untermenüs vom Typ SUB_MENU oder DYN_SUB_MENU ab.
Der erste Menüpunkt beginnt ab w geosText, dieses Word zeigt auf den Text "geos". Beachten Sie bitte, daß die Texte (Strings) immer mit Null abgeschlossen werden müssen. Das sich anschließende Funktionsbyte besagt, daß ein Untermenü erscheinen soll und das folgende Word zeigt auf die Untermenüstruktur (geosSub).

Ab dem Label :geosSub finden Sie dann eine ähnliche Menüstruktur wieder, wie sie auch für das Hauptmenü vorliegt: zunächst zwei Bytes für die y-Koordinaten und dann zwei Words für die x-Koordinaten, Normalerweise beginnt die obere y-Koordinate 1 Pixel unterhalb des darüberliegenden Menüs; die linke x-Koordinate beginnt mit dem Rand des darüberliegen Menüs. Auch hier müssen Sie bzgl. der x-Koordinate ein wenig tüfteln.

Das folgende Byte gibt dann die Anzahl der Untermenüpunkte an sowie deren Ausrichtung. Im allgemeinen ist die Ausrichtung von Untermenüs immer vertikal, was durch die Oder-Verknüpfung verdeutlicht wird.

Auch hier schließen sich die Informationen zu den einzelnen Menüpunkten an. In unserem Beispiel liegt ein Untermenüpunkt vor, der Text des Menüpunktes soll "Info" lauten, es handelt sich um einen ausführbaren Menüpunkt (b MENU_ACTION), bei dessen Anwahl die Routine ab DoInfo angesprungen wird.

Ab dem Label :DoInfo finden Sie die erste menübezogene Routine: GotoFirstMenu
Diese Routine baut alle Unter-(Unter)Menüs bis zum Hauptmenü wieder ab. GotoFirstMenu benötigt keinerlei Parameter, die Routine restauriert wie alle menüabbauenden Routinen den Vordergrundbildschirm, in dem sie einen rechteckigen Bereich, der der Größe des/der Menüs entspricht, aus dem Hintergrund- in den Vordergrundbildschirm holt. Sie sollten deshalb bei der Verwendung von Menüs darauf achten, daß beide Bildschirme dieselben Informationen enthalten, (siehe: dispBufferOn)

Wir verlassen die Menüroutine einfach mit einem rts. In einer späteren Erweiterung werden wir hier eine Dialogbox erscheinen lassen, die nähere Auskünfte zum Programm gibt.

Die Untermenüstruktur ab :geosSub werden wir im nächsten Kursteil um anwählbare DeskAccessories erweitern.

Zurück zum zweiten Hauptmenüpunkt:
Der zweite Hauptmenüeintrag lautet "Datei", dieses Mal soll jedoch kein Untermenü direkt aufgebaut werden, sondern zunächst soll eine Aktion stattfinden. Die Aktion finden Sie ab :DateiDyn.
Hier lernen Sie zunächst eine Geosroutine zum Invertieren von rechteckigen Bereichen kennen: InvertRectangle.
InvertRectangle muß man in r3 als Word die linke x-Koordinate, in r4 die rechte x-Koordinate, in r2L die obere y-Koordinate und in r2H die untere y-Koordinate des Bildschirms angeben. In Abhängigkeit von dispBufferOn invertiert InvertRectangle den Bildschirm (vgl. GEOS-Programmierung mit dem MegaAssembler Seite 232).

Anschließend übergeben wir einen Zeiger (Word) auf die Untermenüstruktur, die nach der Teilinvertierung des Bildschirms dargestellt werden soll. Erst jetzt darf mittels rts die Menüfunktion abgeschlossen werden. Ab dem Label :DateiTab finden Sie die Menüeinträge für das Dateiuntermenü.

Bei den dynamischen Untermenüs findet also immer erst eine Aktion statt, dann wird ein Untermenü aufgebaut. Auch die Untermenüstruktur ab :DateiTab entspricht wieder der der anderen Menüs. Wir haben allerdings für die Anzahl der Menüpunkte die Konstante DMPKT verwendet und als Wert 3 definiert, dies hat den einfachen Vorteil, daß bei einer Ergänzung von Menüpunkten sich auch die Menühöhe automatisch mit ändert.

Eine besondere Beachtung soll hier aber noch die Textdarstellung finden:
Sie können unter GEOS die einzelnen Menütexte noch besonders gestalten und formatieren (ab GEOS 1.3). Da die Darstellung der Texte über die später noch genauer zu beschreibende Routine PutString verläuft, ist es möglich, die Texte noch mit Attributen zu versehen.
Betrachten Sie den Menütext ab :SchließenText, zunächst folgt der eigentliche Text "schließen", anschließend ein Byte (GOTOX), das die Routine PutString anweist, mit der Textausgabe an einer durch ein Word gekennzeichneten x-Koordinate fortzufahren. Wir berechnen mit dem Assembler diese Stelle aus DMLinks+DMOFFSET (28 + 60 = 88). Es folgen zwei Bytes SHORTCUT und BOLDON. Durch das trennende Komma legt dar Assembler beide Bytes nacheinander im Speicher ab.
Die Konstante SHORTCUT steht für die Darstellung des Commodore - Logos (C=), BOLDON für Fettschrift. Es wird also ab der Koordinate DMLinks+OFFSET zunächst das Commodore-Logo ausgegeben und dann in die Fettschrift umgeschaltet. Anschließend wird das "s" ausgegeben, alle Textveränderungen werden durch PLAINTEXT rückgängig gemacht und die Textausgabe mit dem Nullbyte abgeschlossen!
Genauso verfahren wir mit dem Text zu dem Menüpunkte "Drucken". Die ersten beiden Untermenüpunkte des Dateimenüs springen alle dieselbe Routine an: Abbau des kompletten Untermenüs mit GotoFirstMenu und beenden mit rts.

Für die Funktion "Ende" haben wir kein Shortcut vorgesehen, damit der Anwender das Programm bewußt mit der Maus beenden muß. Sie können jedoch in Analogie zu "schließen" und "drucken" auch für "Ende" ein Shortcut vorsehen und ergänzen.

Bei der Routine zum Beenden des Programms bauen wir zunächst das Untermenü ab (jsr GotoFirstMenu) bevor wir es korrekt nach Desktop verlassen.

Der dritte Hauptmenüeintrag "Bearbeiten" verfügt über dieselbe Struktur wie die anderen beiden Menüs, jedoch haben wir hier zusätzlich bei der Anzahl und Ausrichtung der Untermenüpunkte diese mit CONSTRAINED geodert.
Durch CONSTRAINED wird das sechste Bit auf 1 gesetzt (Bit 7 gibt die Ausrichtung an!). Durch das Setzen des sechten Bits kann das Menü nur in die Richtung verlassen werden, in die es aufgebaut wurde, also bei vertikalen Menüs nur nach oben und bei horizontalen nur nach links. Sofern Sie im Listing verdeutlichen wollen, daß das Menü ohne Anwahl immer verlassen werden kann, können Sie die Konstante UNCONSTRAINED einsetzen; dies hätte dengleichen Effekt wie bei den Menüs "geos" und "Datei"!

Der Aufbau der Texte und der Routinen zu den Untermenüpunkten "ändern", "löschen" und "weitersuchen" entspricht (noch) dem Aufbau aus dem Dateiuntermenü (siehe oben).

Eine Besonderheit ergibt sich für das Einfügenmenü:
Der Text "einfügen" wird mit 2 Spaces begonnen, dann folgt ein GOTOX um 10 Pixel versetzt und dann erst dar Text. Bei der dazugehörigen Routine DoInsert klärt sich diese Besonderheit auf. Da nur dann eine bereits bestehende Datei verändert werden sollte, wenn der Anwender dies explizit wünscht, soll durch ein Sternchen (*) vor dem Einfügen angedeutet werden, daß ein Hinzufügen von Daten jetzt erlaubt ist.

Damit später vom Programm aus der Einfügemodus exakt abgelesen werden kann, haben wir das InsertFlag im Listing eingeführt. Ist der Wert dieses Flags $ff (255), so ist das Sternchen gesetzt, ist er Null, so ist es gelöscht.

In Abhängigkeit des gelöschten bzw. gesetzten Sternchens wird entweder in den Text ab :EinfügenText ein Sternchen oder ein Space geschrieben. Die Entscheidung ob InsertFlag über den Wert Null oder $ff verfügt, geschieht bei der Routine :DoInsert mittels des bit-Befehls. Wird eine Speicherstelle über bit abgefragt, so wird das sechste und siebte Bit der Speicherstelle in das Statusregister übertragen. Das siebte Bit setzt das Negativflag im Statusregister, das mit bmi bzw. bpl abgefragt wird. Ist der Wert in InsertFlag negativ (also $ff=255=-1), so wird das lokale Label ::10 angesprungen, ein Space in den Text ab :EinfügenText geschrieben, und das InsertFlag gelöscht. War der Wert in InsertFlag nicht negativ (auch der Wert Null ist beim Computer positiv - entgegen der Mathematik!), so wird das Sternchen gesetzt und das InsertFlag auf $ff (=255=-1) gelegt. Da dieser Wert (im Akku) nicht Null ist, wird über bne nach dem lokalen Label ::20 verzweigt, wo auch der andere Teil der Routine endet.

Hier wird aber nicht das Menü mittels GotoFirstMenü abgebaut, sondern über die Routine ReDoMenu nochmals angezeigt! ReDoMenu stellt das letzte Menü nochmals zu Auswahl, wobei der dann geänderte EinfügenText schon gleich miterscheint!

Der Untermenüpunkt "suchen" eröffnet ein weiters Untermenü. Unter GEOS sind beliebig viele Unter-(Unter-)Menüs machbar, sie dürfen sich auch überlappen! Die jeweilige Untermenüebene hat dieselbe Struktur wie jedes andere Menü auch. Wir gehen deshalb auch nicht mehr auf die Struktur von SearchSub ein.

Eine dritte menübezogene Routine lernen Sie noch ab :DoCDTitel kennen:
PreviousMenu. Wie der Name schon sagt, wird das Untermenü nicht aber die darüberliegenden Untermenüs abgebaut, d. h. in unserem Beispielprogramm wird das Untermenü "Bearbeiten" dargestellt, das Unter-Untermenü "suchen" jedoch abgebaut.

Zusammenfassung:

Der Aufbau aller GEOS-Menüs erfolgt aus einer Struktur heraus, die für alle Menüs gleich ist. Zunächst werden die beiden y-Koordinaten als Byte und dann die x-Koordinaten als Word angegeben. Das sich daran anschließende Byte gibt Auskunft über die Anzahl der Menüpunkte, die Ausrichtung (Bit 7) sowie der Mausbegrenzung bezogen auf dieses Menü (Bit 6).

Danach folgen die Einträge zu den einzelnen Menüpunkten. Zuerst ein Zeiger (Word) auf den Menütext, dann ein Funktionsbyte und schließlich ein Zeiger auf die vom Funkionsbyte abhängige Funktion.

Menütexte können mit Attributen versehen bzw. formatiert werden.

Das Funktionsbyte ist entweder vom Typ MENU_ACTION, SUB_MENU oder DYN_SUB_MENU. Handelt es sich um den Typ MENU_ACTION, so dient das sich anschließende Word als Zeiger auf die auszuführende Routine, war es vom Typ SUB_MENU, so dient das folgende Word als Zeiger auf die Untermenüstruktur. Im Falle von DYN_SUB_MENU ist das folgende Word als Zeiger auf die zuerst auszuführende Aktion zu sehen, am Ende der Aktion übergibt man in r0 einen Zeiger auf das dann anzuzeigende Menü.

Folgende menübezogenen Routinen kennt GEOS:

  1. DoMenu
    DoMenu stellt ein Menü im nächsten Mainloopdurchlauf dar. Dazu muß man in r0 einen Zeiger auf die Hauptmenüstruktur übergeben, der Akku sollte auf einen Menüpunkt zeigen.
     
  2. GotoFirstMenu
    GotoFirstMenü baut alle Unter-(Unter-)menüs bis auf das Hauptmenü ab. Achtung: GotoFirstMenu darf nicht auf einen Hauptmenüeintrag verwendet werden!
     
  3. ReDoMenu
    ReDoMenu stellt das zuletzt dargestellte Menü erneut zur Auswahl. Sofern Sie im Hauptmenü einen Menüpunkt vom Typ MENU_ACTION verwenden, müssen Sie ReDoMenu benutzen!
     
  4. DoPreviousMenu
    DoPreviousMenu stellt das vorherige Untermenü zur Auswahl und baut nur das letzte Untermenü ab.

Für den nächsten Kursteil sollten Sie das bisherige Listing wie folgt abändern:

  1. Das Dateimenü sollte ein "normales" Untermenü werden.
  2. Die Menüpunkte "Interpret", "CD-Titel" und "Titel" sollten alle mittels GotoFirstMenu die Menüstruktur abbauen.
  3. Der Menüpunkt "ändern" sollte ebenfalls über ein Sternchen gesteuert werden, das dazu benötigte Flag sollten Sie ChangeFlag nennen.

Viel Spaß beim Programmieren, bis zur nächsten Ausgabe.

 

H. J. Ciprina

 

 

 




Dieser Artikel ist Bestandteil von:

Ausgabe 18

! - - - - - M I C R O F I L M - - - - - ! | Editorial | Einsteiger: Büro-Kurs (Teil 1) | GUC Treffen | TopDesk Erfahrungsbericht | Update für TopDesk | RamPrint Erfahrungsbericht | Kurs: Programmieren (Teil 4) | Neuer Workshop ? | Die GeoThek | Regionales | GEOS auf Eprom | GEOS Professional | DTP 6 - Was der Geos-User von geoPublish erwartet ... | PC/GEOS TEIL zur GEOS - USER - POST 18 | Das Allerletzte


Kurs Programmieren

Kurs: Programmieren (Teil 1) | Kurs: Programmieren (Teil 2) | Kurs: Programmieren (Teil 3) | Kurs: Programmieren (Teil 4) | Kurs: Programmieren (Teil 5) | Kurs: Programmieren (Teil 6) | Kurs: Programmieren (Teil 7) | Kurs: Programmieren (Teil 8)


Kurzlink hierhin: http://geos-printarchiv.de/1217


Letzte Änderung am 01.11.2019