Mobile Times Business Club
Startseite : Mobility : OPL Kurs
OPL OPL Kurs, Teil 7 Aktualisierung
2007-03-01
01: Einführung
02: Menüs und mehr
03: Basics, Zufall & Mathetrainer
04: Spielend lernen - Würfel, Bandit & Lotto
05: Datenbanken - Neu/Ändern/Löschen
06: Datenbanken - Suchen/Gehen Zu
07: Gezielte Textausgabe
08: Fensterl'n mit dem Psion
09: Zeichnen mit Grips
Gezielte Textausgabe
Bisher haben wir OPL kennengelernt und Programme erstellt, ohne uns großartig um eine wesentliche Funktion, nämlich die Ausgabe auf den Bildschirm zu kümmern.
    In dieser Ausgabe unseres Workshops soll es eben darum gehen - um ganz genau zu sein: Um die Textausgabe.
    Gerade Einsteiger stolpern immer wieder über die verwirrend vielfältigen Möglichkeiten, Texte gezielt auf dem Bildschirm auszugeben. Aber keine Bange, wir schildern Ihnen auch diesmal alles haargenau!

Bildschirm & Fenster
Wir haben im wesentlichen mit zwei begrifflich zu trennenden Dingen zu tun.
    Da ist einerseits der Bildschirm. Er ist lediglich die physikalische Ausgabeeinheit, die über einzeln angesteuerte Bildpunkte (pixel, picture cells) ein Bild für unser Auge aufbereitet. Die Serie 5 verfügt über 640×240 Pixel.
    Andererseits organisiert das Betriebssystem die optische Ausgabe intern über eine ausgefeilte Fenstertechnik. Fenster - den meisten von Ihnen vom PC bekannt - sind in der Größe frei definierbare rechteckige Flächen, die Raum für Darstellungen jeglicher Art bieten. Die Serie 5 kann 64 gleichzeitig offen halten!
    Uns interessiert vorerst jedoch nur ein einziges davon, nämlich das Basisfenster. Dieses steht uns ungefragt und ohne unser Zutun nach dem Start eines OPL-Programmes immer zur Verfügung und nimmt den gesamten Bildschirm ein. Überzeugen Sie sich, indem Sie ein kurzes Programm eintippen, das einen Rahmen um das Fenster zieht. Wie üblich schließen Sie die eigentlichen Programmzeilen zwischen "PROC name:" und "ENDP" ein, übersetzen es und lassen es schließlich laufen:
GET :gBORDER 0 : GET
    Das Basisfenster beschäftigt uns deshalb besonders, weil es das einzige ist, das eine Zwitterstellung einnimmt. Die besteht darin, daß dort Text auf zweierlei Art ausgegeben werden kann, und zwar einmal als normaler Text und andermal als grafischer Text.
    "Normalen Text" haben wir bereits mehrfach verwendet. Der zugehörige Befehl heißt "PRINT". Durch ihn wird in einen dafür reservierten Bereich des Basisfensters geschrieben - in das sogenannte Textfenster.

Kariert
Das Textfenster ist optisch nicht ohne weiteres zu erkennen und eigentlich auch nur eine Vorstellungshilfe für uns Menschen.
    Beim Programmstart hat es fast die gleichen äußeren Abmaße wie das Basisfenster und kann auch nie größer als dieses sein. Um damit vertraut zu werden, stellen Sie sich bitte einmal vor, das Textfenster wäre ein Stück kariertes Papier und auch so unterteilt.
    Die Besonderheit: Es gibt nur vollständige Karos. Auf diese Weise können sie jeden Platz im Textfenster adressieren, indem Sie eine Spalten- und Zeilennumer angeben. Genau das machen Sie mit dem AT-Befehl. Mit ihm werden Spalte und Zeile benannt - gewissermaßen wird ein unsichtbarer Zeiger gesetzt ("Cursor"). Dort genau beginnt schließlich der folgende PRINT-Befehl mit der Textausgabe. Beispiel:
   AT 14,8 : PRINT "Hallo Thomas!"
   REM Text ab Spalte 14, Zeile 8
   GET
    Im Textfenster der Serie 5 stehen 91 Spalten und 21 Zeilen zur Verfügung. Jedenfalls solange man die Schriftart nicht ändert. Verschiedene Schriften ("Fonts") sind aber ein Gestaltungsmittel und daher interessant und wichtig. Ein Merkmal von Fonts ist ihre räumliche Ausdehnung, insbesondere die in "Punkt" gemessene Größe (Höhe). Sie können sich sicherlich sehr gut vorstellen, daß ein größerer Font nicht mehr in die Karostruktur eines kleinern paßt. Würde man also mitten beim Schreiben den Font ändern, käme das Betriebssystem mit der Buchstabenplazierung ins Schleudern.
    Also schiebt das System einen Riegel davor, was wiederum nun uns ins Grübeln kommen läßt: Nach dem Befehl zum Ändern des Fonts wird einfach der Textbildschirm gelöscht!
    Das Betriebssystem berechnet daraufhin die Karostruktur und deren Anordnung im Basisfenster neu. Beispiel:
PRINT "Teil 6" :GET :FONT 12,0 :PRINT "Teil 8" :GET
    Der Text "Teil 6" wird im Standardfont dargestellt, nach einem Tastendruck wird der Font mit dem entsprechenden Befehl gewechselt.
    Die erste Zahl sagt dabei, welcher Font benutzt werden soll, die zweite, welche Auszeichnung Verwendung findet (fett, kursiv...) - die Null steht für "normal", andere gültige Werte entnehmen Sie bitte dem unten stehenden Programm "txtpos1:".
    Die Neuanordnung des virtuellen Karorasters im Basisfenster können Sie gut beobachten, wenn Sie einmal darauf achten, daß der Querbalken des "T" jeweils geringfügig in der Höhe verschoben zur Anzeige kommt.

Fonts
Über diese Fonts verfügen Sie (zugehörige Nummer in Klammern):
Mono      8*8     (4)
Roman     8       (5)
Roman    11       (6)
Roman    13       (7)
Roman    16       (8)
Swiss     8       (9)
Swiss    11      (10)
Swiss    13      (11)
Swiss    16      (12)
Mono      6*6    (13)
    Die Zahlen hinter der Fontbezeichnung ist die Schriftgröße in der Maßeinheit "Punkt".
    Ein kleines Programm zeigt uns die Auswahl noch einmal auf dem Bildschirm:
txtpos1:
PROC txtpos1:
   GLOBAL n% : n%=4
   DO
      FONT n%,0         REM entspricht STYLE 0
      PRINT "FONT Nr.";n%
      PRINT "Text normal"
      STYLE 32 : PRINT "Text kursiv"
      STYLE 4  : PRINT "Text invers"
      STYLE 2  : PRINT "Text unterstrichen"
      n%=n%+1 : GET
   UNTIL n%>13
ENDP
    Das Beispiel beweist gleichzeitig: Solange man den Font in seiner Größe nicht ändert, kann man sein Aussehen durch den STYLE - Befehl in gewissen Grenzen durchaus beeinflussen.
    Die im Programm verwendeten Zahlen können auch addiert werden und ergeben dann eine kombinierte Darstellung (32+4 = kursiv und invers). Die Auszeichnung "fett" würde die Ausdehnung des Fonts ändern und ist daher nicht als Option vorgesehen.
    Diese Fonts fallen am Serie 5 sehr klein aus. Probieren Sie daher einmal die Nummern aus dieser Auswahl:
Arial:   268435951 .. 268435961
Times:   268435962 .. 268435972
Courier: 268436062 .. 268436072
REM Beispiel : FONT 268435959,0
    Um herauszufinden, wieviele Spalte und Zeilen das Textfenster nach einem Fontwechsel hat, bedienen Sie sich des SCREENINFO-Befehles. Der legt seine Informationen in einem vorher zu deklarierenden Variablenfeld mit 10 Variablen ab und wir fischen uns die wichtigsten heraus:
Screeninfo
PROC info:
   LOCAL i%(10)
   SCREENINFO i%()
   PRINT i%(3),"Spalten" : PRINT i%(4), "Zeilen":
   GET
   FONT 268435959,0 :REM Fontänderung
   SCREENINFO i%()
   PRINT i%(3),"Spalten" : PRINT i%(4), "Zeilen"
   GET
ENDP

Änderungen
Ein weiterer Befehl läßt uns aktiv auf Größe und Anordnung des Textfensters Einfluß nehmen: SCREEN. Ein Beispiel:
SCREEN 7,3,2,2
    Unter Verwendung der aktuellen Font-Einstellung wir das Textfeld dadurch auf einen 7 Karos (oder besser Zeichen) breiten und 3 Zeilen hohen Bereich neu eingestellt. Die Entfernung vom Basisfenster-Rand in Zeichen und Zeilen bezieht sich bis zur endgültigen Aktivierung des veränderten Textfensters noch auf das zuletzt benutze Karo-Raster. In unserem Falle liegt das neue Fenster also ab dem 2. Zeichen vom linken und ab der 2. Zeile vom oberen Rand entfernt. In unserem folgenden Beispiel wird zuerst der linke obere Teil des Standart-Textfensters mit Sternchen gefüllt und dann das Textfenster neu eingestellt.
txtpos2:
PROC txtpos2:
   GLOBAL n%
   n%=1
   DO
      PRINT "*********"
      n%=n%+1
   UNTIL n%>5
   rem   SCREEN 7,3,2,2:GET :CLS :GET
   rem   PRINT " 1234567890" : GET
   SCREEN 17,13,12,2:GET :CLS :GET
   PRINT " 12345678901234567890123abcdeffghijk" : GET
ENDP
    Sichtbar wird die neue Form und Position allerdings erst nach dem Text-Löschbefehl "CLS". Die Wirksamkeit des neuen Fensters bestätigt ein kurzer Anhang an das gerade geschriebene Programm:
PRINT " 1234567890" : GET
    Der auszugebende Ausdruck ist länger als die Breite des Textfensters - er wird daher am Rand umgebrochen und in der nächsten Zeile fortgeführt.
    Dimensioniert man das Textfenster für ein eigenes Programm richtig, kann man mit den wenigen Befehlen AT x, y / PRINT / CLS einen recht einfach zu handhabenden Anzeigenbereich verwirklichen.
    Zur Erinnerung: PRINT gibt üblicherweise einen oder mehrere Ausdrücke aus und erzeugt dann einen Zeilenumbruch, wenn die Zeile nicht gerade mit einem Komma oder Semikolon endet. Ein Komma in einer Folge von Ausdrücken hinter dem PRINT ergibt auf dem Bildschirm eine Leerstelle. Die Ausdrücke hinter PRINT können sowohl Text als auch Zahlen als auch komplexe Befehle, Funktionen oder Unterprogramme sein, wenn sie nur am Ende eine Zahl oder einen Text ergeben:
PRINT "Font Nr." ,n%,"ist Arial und" ,640/8,"Zeichen breit",CHR$ (7),ASC ("A")

Schrift grafisch
Nach dem Ausflug in die "Untermenge" Textfenster kehren wir nun zum Basisfenster zurück. Aus all den vorhergehenden Erklärungen ahnen Sie schon, daß wir jetzt über die grafischen Eigenschaften reden müssen. Lassen wir in dieser Folge einmal noch die tatsächlichen Grafiken beiseite und bleiben wir bei der Ausgabe von Text.
    Die meisten Befehle zur Ausgabe ins Textfenster finden ein Gegenstück für die Ausgabe ins Basisfenster. Weil der Text dort pixelgenau - eben wie auch Grafiken - positioniert werden kann, redet man von "grafischen Text". Die verwendeten Befehle beginnen daher folgerichtig mit einem "g". Die Gestaltungsmöglichkeiten sind weitaus umfangreicher und flexibler, setzen aber mehr Kenntnisse und Sorgfalt beim Programmieren voraus.

gAT
gibt die (Cursor-)Position vor, ab der der Text ausgegeben werden soll.

gPRINT
sorgt für die Ausgabe des Textes. Achtung! gPRINT interpretiert die Angaben von "gAT" als einen Punkt auf der Grundlinie des Fonts! Geben Sie eine gPRINT-Anweisung beim ersten Mal ohne eine Positionsanweisung ein, sehen Sie garnichtts bzw. lediglich ein paar Buchstaben, die unter die Grundlinie schreiben, denn beim Start steht der Cursor an den Grundkoordinaten 0,0:
gPRINT "Hallo Edeltraud!"
    Um präzis zu arbeiten, benötigen Sie daher bereits bei der Positionsangabe Kenntnisse über den Font!
    Ein weiterer Unterschied zum PRINT-Befehl: gPRINT sorgt nicht für einen Zeilenumbruch.

gCLS
löscht den GESAMTEN Bereich des Basisfensters - einschließlich den des Textfensters! Dem Geschick des Programmierers bleibt es überlassen, sich vor den unerwünschten Folgen zu schützen, z.B. das Textfenster nach einem gCLS wieder neu zu beschreiben, damit eine eventuell darin enthaltene Information nicht verloren geht.

gFONT
legt den zu benutzenden Font fest. Im Gegensatz zum Textfenster läßt sich der Font "im Galopp" verändern, ohne daß dabei das Fenster gelöscht wird. Das Text-Attribut wird in der gFONT-Anweisung nicht benannt, sondern bei Bedarf mit gSTYLE manipuliert:
gat 10,30
gFONT  9 : gPRINT "H"
gFONT 10 : gPRINT "A"
gFONT 11 : gPRINT "LL"
gFONT 12 : gPRINT "O"

gSTYLE
verhilft dem Text zu seinem Attributen (fett, kursiv..) kennt aber im Gegensatz zu seinem Pendant STYLE eine größere Auswahl. Sie darf ebenfalls durch Additionen der Werte kombiniert werden:
gSTYLE 0    normal
gSTYLE 1    fett
gSTYLE 2    unterstrichen
gSTYLE 4    invers
gSTYLE 8    doppelt hoch
gSTYLE 16   mono
gSTYLE 32   kursiv
zum Beispiel:
gat   10,30
gFONT    12: gPRINT "Hallo "
gSTYLE 2+32: gPRINT "EVA"

gTMODE
setzt die Art, wie sich die Schrift auf die Bildschirmdarstellung auswirkt:
gTMODE 0   Pixel setzen
gTMODE 1   Pixel löschen
gTMODE 2   Pixel invertieren
gTMODE 3   Pixel setzen / Hintergrund löschen
Sehen Sie sich dazu dieses Beispiel an:
Pixel
PROC name:
   gAT 65,0 : gFILL 40,130,0
   GET : gFONT 12 : gSTYLE 1
   gTMODE 0 : gAT 20,30
   gPRINT "Pixel setzen"
   gTMODE 1 : gAT 20,60
   gPRINT "Pixel löschen"
   gTMODE 2 : gAT 20,90
   gPRINT "Pixel invertieren"
   gTMODE 3 : gAT 20,120
   gPRINT "Pixel setzen / Hintergrund löschen"
   GET
ENDP
    Hier wird auch besonders deutlich, was "grafisch" bedeutet: Die Schrift wird Pixel um Pixel gesetzt - im Normalfall wird dabei der "weiße Block" um den Buchstaben nicht mit ausgegeben, wie das aber im Textfeld üblich ist. Zur Verdeutlichung ergänzen Sie einmal das vorstehende Programm um diese Zeile:
AT 7,4 : PRINT "Rudolf Pöchacker" : GET

gSETWIN
ist vergleichbar der SCREEN Anweisung. Die Parameter werden allerdings anders benutzt. Bei zwei angegebenen Parametern wird lediglich die Position des Basisfensters versetzt, bei vier Parametern auch noch Breite und Höhe. Die Angaben sind Pixelwerte. Beispiel:
gBORDER 0 : GSETWIN 40,40
GET : gSETWIN -40,-40
GET
gSETWIN 40,20,gWIDTH-80,gHEIGHT-40
gCLS
gBORDER 0 : GET
    Durch gBORDER erkennt man das Fenster erst so richtig. gSETWIN positioniert nun die linke obere Ecke des Fensters neu auf die Koordinaten 40,40. Daß dabei das Fenster tatsächlich nur verschoben und nicht verändert wird, zeigt die zweite Verschiebung auf die Anfangskoordinaten -40,-40, bei der der Rahmen erhalten bleibt. Jawohl, richtig gelesen! Das grafische Fenster verarbeitet auch negative Koordinaten, ohne daß das Programm abbricht.
    Erst die Verkleinerung des Fensters um je 40 Pixel an der linken und rechten Seite sowie die Verminderung der Höhe um je 20 Pixel oben und unten unterbricht den Rahmen. Der muß deshalb in unserem Beispiel auch neu wieder gezeichnet werden. Damit seine Ecken auch wieder schön rund werden, steht noch ein gCLS vor dem Rahmenbefehl.
    Die Verwendung von gWIDTH und gHEIGHT, deren aktuellen Werte des Betriebssystem selber kennt und die der aktuellen Weite und Höhe des Fensterrs in Pixel entsprechen, ersparen entsprechendes Kopfzerbrechen - lediglich die Seitenabstände werden noch subtrahiert, damit das neu dimensionierte Fenster zentrisch auf dem Bildschirm zu sehen ist.
    Wer dem Frieden nicht traut, ob das Programm auch wirklich das getan hat, was ihm gesagt wurde, prüfe, ob der Abstand des neue Basisfensters tatsächlich 40 und 20 Pixel vom Bildschirmrand liegt mit diesen beiden neuen Befehlen, die die Position der linken oberen Ecke des Fensters auf dem Bildschirm melden:
gAT 20,20 : gPRINT gORIGINX,gORIGINY
    Wer darüber hinaus neugierig ist, wird sich mit gINFO auseinandersetzen müssen. Nur soviel: Ähnlich SCREENINFO wird gINFO i%() ein Array mit 32 Variablenwerten gefüllt, die hinterher abgefragt werden können und Auskunft über diverse aktuelle Parameter des Basisfensters geben.
    Für den Fortgeschrittenen sind aber noch nicht alle Möglichkeiten der grafischen Textausgabe erschöpft. Zur Verfügung stehen nämlich noch weitere Formen, für deren sinnvollen Einsatz man immer erst bei den entsprechenden Spezialfällen zurückkommen wird. Deshalb nur kurz gestreift:

gPRINTB
zeigt einen Text in einem leeren rechteckigen Feld mit einer frei bestimmbaren Breite. Zusatzparameter bestimmen dabei die Anordnung des Textes darin (links, Mitte, rechts) oder legen gezielt den Freiraum über und unter der Schrift fest.

gPRINTCLIP
erlaubt die Textlänge auf eine selbst anzugebende Breite in Pixeln zu begrenzen.

gXPRINT
schreibt den Text vergleichbar dem PRINT-Befehl mit den "leeren" Anteilen, aber auch unterstrichen oder invers.

gTWIDTH
Die Information, wie breit eigentlich ein Schriftzug in Pixel ist, ermittelt für uns gTWIDTH in der Form:
b%=gTWIDTH text$
    So scheinbar unnütz die letzten Befehle waren, so brauchbar sind die beiden letzten. Zuerst

GIPRINT
GIPRINT "maximal 64 Zeichen lang!",0
    Der Wert hinter dem Komma (0,1,2 oder 3) bestimmt, in welcher der 4 Bildschirmecken der Text für etwa 2 Sekunden auftaucht. Er ist dabei keinem der Fenster zugeordnet.
    Da jeder auch sonst übliche Text ausgegeben werden kann, ist das eine exzellente Methode, sich während der Programmentwicklung Variablenwerte etc. anzeigen zu lassen, da ja die Fensterinhalte in keiner Weise betroffen sind. Diese Art der Ausgabe ist auch ganz hervorragend für Nutzerinformationen geeignet, z.B. der Hinweis, wenn es etwas länger dauert: "Initialisierung" oder "Ich rechne".
    Gerade der letzte Fall wird noch besser durch den Befehl BUSY abgedeckt, weil man ihn nämlich wieder abschalten muß. So setzt man am Beginn einer langen Berechnung einen blinkenden Text auf eine der vier Ecken des Bildschirms und schaltet ihn danach wieder ab. Die Parameter sind der Text, und optional die Ecke (0,1,2 oder 3) und eine Einschaltverzögerung (in 0,5 Sekunden Schritten):
BUSY "Ich rechne" ,0,2 : PAUSE 60 : BUSY OFF
    Wie eng grafische Schrift und Grafik selber zueinander stehen, werden wir noch sehen, wenn wir uns mit dem Thema Grafik auseinandersetzen. Alle Grafikbefehle lassen sich nämlich auch auf Schrift anwenden. Aber mit diesem Hinweis wollen wir es dann auch diesmal belassen.
    Zum Abschluß des Stoffes gibt es noch ein kleines Programm, in dem ein großer Teil des neu Gelernten wieder auftaucht - und zu mehr soll es auch garnicht gut sein... die Interpretation bewältigen Sie nun spielend selbst.
Sterne
PROC Sterne:
   GLOBAL  n%, z%, zmax%, x%(10), y%(10), font%(10)
   RANDOMIZE SECOND
   GIPRINT "Sternen-Simulation" ,0
   FONT 4,0 : SCREEN 8,2 : PRINT "*Sterne*"
   n%=1
   DO
      getvars:(n%) : n%=n%+1
   UNTIL n%>10
   zmax%=2 : z%=0
   DO
      n%=1
      DO
         PAUSE 10
         gTMODE 1
         gAT x%(n%), y%(n%)
         gFONT font%(n%)
         gPRINT"*"
         REM löschen
         getvars:(n%)
         gTMODE 0
         gAT x%(n%), y%(n%)
         gFONT font%(n%)
         gPRINT"*"
         REM schreiben
         n%=n%+1
      UNTIL n%>10
      z%=z%+1
   UNTIL z%>zmax%
   gAT gWIDTH/2-50,gHEIGHT/2-40 : gFILL 100,8,0
   PAUSE-40
   CLS : PRINT : PRINT"**ENDE**"
   PAUSE-100
ENDP

PROC getvars: (i%)
   x%(i%)=10+zufall%:(gWIDTH-20)
   y%(i%)=10+zufall%:(gHEIGHT-20)
   font%(i%)=  8+zufall%:(4)
ENDP

PROC zufall%: (max%)
   RETURN 1+INT(RND*max%)
ENDP

Ergänzend zwei Tips:
Der Wartebefehl "PAUSE", verbunden mit einem negativen Wert, ermöglicht die Pause durch einen beliebigen Tastendruck abzubrechen und "gFILL" sorgt für das Zeichnen eines schwarz gefüllten Rechtecks.
    Und nun: variieren Sie fleißig!


OPL am Psion von Rudolf Pöchacker (http://members.xoom.com/poechacker/)
Valid HTML 4.01! Copyright © 2002-2007 Mobile Times Business Club
Zurück zum Menü
Nach Oben