4.0 Application, Primary, Button, Group, Menu

Verfügbare Generic Objekt Klassen

In diesem Abschnitt werden die einzelnen generischen Objektklassen, die in R-BASIC verfügbar sind, im Detail beschrieben. Einige dieser Objekte sind sehr einfach zu benutzen, können aber trotzdem sehr komplexe Funktionen ausführen. Da alle diese Objekte von der GenericClass abstammen, erben sie sämtliche in den vorherigen Kapiteln besprochenen Instance-Variablen. Sie sollten außerdem die in Kapitel 2 beschriebenen Konzepte kennen, um die damit verbundenen Details zu verstehen.
4.1 Application

4.1.1 LongName, Benutzer Notizen und Tokens

4.1.2 Actionhandler des Application Objekts

4.1.3 Starten und Beenden eines Programms

4.1.3.1 Programmstart

4.1.3.2 Programmende

4.1.4 Arbeit mit Dokumenten

4.1.5 Überwachung der Zwischenablage

4.1.6 Der Busy-Status


^

4.1 Application

Dieses Objekt stellt die Verbindung zum GEOS-System her und ist das top Parent-Objekt für alle anderen generischen BASIC-Objekte ihres Programms. Jedes BASIC-Programm muss genau ein Application-Objekt haben. Direktes Child des Application-Objekts ist im allgemeinen ein Primary-Objekt.

Abstammung:

...

Die Definition eines einfachen Application-Objekts sieht z.B. so aus:

Application MyApp
  Children = MyPrimary
END OBJECT
MyApp ist der Name des Application-Objekts, unter dem es bei Bedarf im BASIC-Code angesprochen werden kann. Das ist für Application Objekte jedoch nur selten nötig.

Das Application-Objekt selbst erscheint nicht auf dem Bildschirm. Es ergibt daher keinen Sinn, ihm eine Caption$ zugeben, auch wenn das syntaktisch möglich ist.

Tastaturhandling

Sie können sich in das Tastaturhandling einklinken, indem Sie einen Tastaturhandler für das Application-Objekt schreiben. Dazu werden die folgenden Instancevariablen unterstützt:

Actionhandler Instancevariablen Methoden
OnKeyPresed inputFlags --

Der OnKeyPressed-Handler muss als KeyboardAction deklariert werden. Eine ausführliche Beschreibung, wie man einen Tastaturhandler schreibt und was es dabei zu beachten gilt, finden Sie im Handbuch "Spezielle Themen", Kapitel 14.

Das Schreiben eines Tastaturhandlers für das Application-Objekt ist eine sehr einfache Methode, wenn ein "globaler" Tastaturhandler geeignet ist. Das ist z.B. für viele Spielprogramme der Fall.

Focus und Target

Das Application-Objekt ist ein Knoten in der Focus- und Target-Hierarchie. Es ist möglich zu überwachen, ob ein Application-Objekt den Focus oder das Target hat, indem man einen Focus- bzw. Target-Handler schreibt. Die notwendigen Details zur Arbeit mit Focus und Target finden Sie im Kapitel 12 (Focus und Target) des Handbuchs "Spezielle Themen". Das Arbeiten mit Focus und Target ist etwas für erfahrene Programmierer und nur in wenigen Fällen notwendig. Eine Ausnahme bildet die Implementation von speziellen Menüs wie dem "Bearbeiten" Menü. Diesem Thema ist deswegen ein eigenes Kapitel ("Spezielle Themen", Kapitel 13) gewidmet.

Spezielle Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
OnInit OnInit = <Handler> --
OnStartup OnStartup = <Handler> --
OnExit OnExit = <Handler> --
OnClpChange OnClpChange = <Handler> nur schreiben
OnConnection OnConnection = <Handler> nur schreiben
LongName$ LongName$ = "Name" --
userNotes$ userNotes$ = "Text" --
crNote$ crNote$ = "Text" --
AppToken AppToken = " <chars>", <numVal> --
DocToken DocToken = " <chars>", <numVal> --
ExtraToken ExtraToken = " <chars>", <numVal> --

Methoden:

Methode Aufgabe
MarkBusy Busy-Status aktivieren
MarkNotBusy Busy-Status verlassen
HoldUpInput Usereingaben zwischenspeichern
ResumeInput Zwischengespeicherte Usereingaben ausführen
IgnoreInput Alle Usereingaben ignorieren
AcceptInput Usereingaben wieder akzeptieren

Action-Handler-Typen:

Handler-Typ Parameter
SystemAction (sender as object, flags as word, dataFile$ as String(250) )

Konstanten für Parameter "flags":

Konstante Wert Bedeutung
AF_FOR_PRINT 1 Datei zum Drucken übergeben
AF_RESTORE 2 Wiederherstellung nach System Shutdown
AF_DATA_FILE 4 Datendatei wurde übergeben
AF_SHUTDOWN 8 GEOS fährt herunter

Eine ausführliche Beschreibung der einzelnen Flags finden Sie im nächsten Kapitel.

^

4.1.1 LongName, Benutzer Notizen und Tokens

Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
LongName$ LongName$ = "Name" --
userNotes$ userNotes$ = "Text" --
crNote$ crNote$ = "Text" --
AppToken AppToken = " <chars>", <numVar> --
DocToken DocToken = " <chars>", <numVar> --
ExtraToken ExtraToken = " <chars>", <numVar> --


LongName$

Der "LongName$" ist der eigentliche Name des Programms, mit dem es im GeoManager und im Expressmenü erscheint. Er wird benötigt, wenn Sie ein "Eigenständiges Programm" anlegen, um es an andere Nutzer weiterzugeben. In den meisten Fällen wird die Instancevariable LongName$ jedoch gar nicht explizit gesetzt. R-BASIC verwendet dafür standardmäßig den Namen Ihres BASIC Programms. Setzen Sie einen abweichenden Wert für "LongName$", falls das fertige Programm unter einem anderen Namen im GeoManager erscheinen soll.

userNotes$

Die userNotes$ sind die Dokument-Notizen, die Im GeoManager angesehen und geändert werden können. Sie können bis zu 99 Zeichen lang sein, wobei Zeilenumbrüche als ein Zeichen gezählt werden.

crNote$

crNote$ definiert eine bis zu 32 Zeichen lange Copyright-Notiz. Sie wird in den Dateiheader des Programms geschrieben und nicht im GeoManager angezeigt.

AppToken

AppToken spezifiziert das Icon (Symbol-Bild), dass der GeoManager für das Programm anzeigt. Es wird benötigt, wenn Sie ein "Eigenständiges Programm" anlegen, um es an andere Nutzer weiterzugeben. AppToken ist vom Typ GeodeToken, d.h. es besteht aus 4 Buchstaben und einer Zahl zwischen 0 und 65535, der sogenannten "Manufacturer-ID".

Beispiel:

Application  MyApp
  Children = MyPrimary
  AppToken = "BPdm",16600
  userNotes$ = "Version 2.0, Jan. 2013"
  crNote$ = "(c) by Rabe-Soft 01/2013"
END OBJECT
Jedes Programm benötigt ein eigenes Token. Wenn Sie ein "eigenständiges Programm" erzeugen (also ein Programm, das auch ohne R-BASIC lauffähig ist), kopiert R-BASIC das Icon-Bild aus der Token Database in das fertige BASIC Programm. Das bedeutet folgendes:

  • Dass durch AppToken spezifizierte Token muss sich beim Anlegen des eigenständigen Programms in ihrer Token Database befinden.

  • Benutzt ein User Ihr Programm, so installiert das Programm automatisch sein AppToken in der Token Database, falls es dort noch nicht existiert. Hier verhält sich ein R-BASIC Programm genau wie ein mit dem PC/GEOS-SDK geschriebenes Programm.

  • Spezifizieren Sie kein AppToken verwendet R-BASIC ein "Standard-Token".
Sie können für AppToken sowohl ein Token aus einer existierenden Iconsammlung verwenden als auch ein eigenes Icon erstellen.

Um ein eigenes Icon zu erstellen können Sie das Programm "IconEditor" verwenden, der das Icon direkt in die Token Database exportieren kann. Dazu benötigen Sie eine eigene Manufacturer-ID. Im Kapitel 3.4 "Über die Manufacturer-ID" im R-BASIC Benutzer Handbuch wird beschrieben, wie Sie eine Manufacturer-ID erhalten können.

Zu einem "Token" (4 Zeichen + Manufacturer-ID) gehören üblicherweise mehrere Icon-Bilder. R-BASIC unterstützt genau zwei Bilder pro Token:

Das Erste ist das eigentliche Icon. Es wird vom GeoManager bei der Anzeige des Programms verwendet. Es ist üblicher Weise 48x30 Pixel groß und hat 16 oder 256 Farben. Das Zweite ist das "Tool" Icon und wird z.B. für das Expressmenü benutzt. Es ist üblicherweise 15x15 Pixel groß und kann ebenfalls 16 oder 265 Farben haben. Im Abschnitt "Eigenständige Programme anlegen" des R-BASIC Benutzer Handbuchs finden sie eine ausführliche Beschreibung wie Sie zum Erstellen eigener Icons vorgehen können.

DocToken

Wenn Ihr Programm mit Dokumenten arbeitet, können Sie diesen ein eigenes Token zuweisen (bei DOS-Dateien in der GEOS.INI, bei VM-Dateien über das Attribut "Token"). Um sicherzustellen, dass sich das Token auch in der Token Database befindet, können Sie die Instancevariable DocToken verwenden. R-BASIC wird - wie beim AppToken - beim Anlegen des eigenständigen Programms die beiden zum DocToken gehörenden Iconbilder in das BASIC-Programm kopieren. Das BASIC-Programm installiert dann das DocToken gemeinsam mit dem AppToken in der Token Database. Mehr macht das R-BASIC Programm nicht! Es bleibt Ihnen überlassen ob und wie Sie das DocToken verwenden.

ExtraToken

Für den unwahrscheinlichen Fall, dass Sie ein weiteres Token benötigen, können Sie ein ExtraToken spezifizieren, dass dann gemeinsam mit dem AppToken und dem DocToken in das BASIC-Programm kopiert und von diesem bei Bedarf in die Token Database installiert wird.

^

4.1.2 Actionhandler des Application Objekts

Alle Actionhandler des Application-Objekts müssen als SystemAction deklariert sein. Der Parameter sender enthält dabei immer das Application Objekt, die Parameter flags und dataFile$ sind im Folgenden beschrieben.

Der Parameter flags

Der Parameter "flags" (engl. Flagge) enthält zusätzliche Informationen, die unter gewissen Umständen von Bedeutung sein könnten. Es handelt sich dabei um einzelne Bits, die gesetzt sein können oder eben nicht. Um abzufragen, ob ein bestimmtes Flag gesetzt ist verwenden Sie die logische AND Operation und prüfen Sie, ob das Resultat Null ist oder nicht. Vergessen Sie die Klammern nicht!

 ! Prüfen ob AF_DATA_FILE gesetzt ist
 IF flags AND AF_DATA_FILE THEN ...
' gleichbedeutend mit
 IF (flags AND AF_DATA_FILE) <> 0  THEN ...
oder:
 ! Prüfen ob AF_DATA_FILE  NICHT gesetzt ist
 IF (flags AND AF_DATA_FILE) = 0 THEN ...
Beachten Sie folgendes:

  • Verwenden Sie nicht den NOT-Operator

    z.B.: IF NOT ( flags AND AF_DATA_FILE ) THEN ...
    oder: IF flags AND NOT AF_DATA_FILE ) THEN ...

    Der Operator NOT führt eine bitweise Negation aus, was gemeinsam mit dem AND Operator in den meisten Fällen zur Aussage "wahr" (d.h. ungleich Null) führt. Ein solcher Fehler ist selbst für Profis sehr schwer zu finden.

  • Verwenden Sie niemals ein einfaches "=" (if flags=AF_DATA_FILE), da sie nie sicher sein können ob noch andere Flags gesetzt sind! Möglicherweise werden von späteren Versionen zusätzliche Flags bereitgestellt, die gesetzt sein könnten!

AF_DATA_FILE
Dieses Flag zeigt an, dass dem Handler eine Datendatei übergeben wurde (Parameter dataFile$ enthält dann den Pfad zur Datei). Die Abfrage dieses Flags ist schneller als das Prüfen der Stringlänge mit Len(dataFile$). Len(dataFile$) > Null zeigt ebenfalls an, dass eine Datendatei übergeben wurde.

AF_FOR_PRINT
Dieses Flag kann nur gesetzt sein, wenn auch eine Datendatei übergeben wurde (AF_DATA_FILE gesetzt). Es zeigt an, dass der Nutzer die Datei nicht durch einen Doppelklick sondern über das Menü "Drucken" des Geomanagers geöffnet hat. Sie können z.B. entscheiden, dass Sie die Datei ignorieren wollen (weil Ihr Programm gar nicht drucken kann) oder eine andere Sonderaktion durchführen, wenn das sinnvoll ist.

AF_RESTORE Dieses Flag kann nur im OnInit oder im OnStartup Handler gesetzt sein. Es zeigt an, dass das Programm beim letzten Herunterfahren von PC/GEOS noch offen war und jetzt, beim Systemneustart, wiederhergestellt (engl.: restored) wird. Möglicherweise möchten Sie in diesem Fall bestimmte Initialisierungsschritte auslassen oder stattdessen andere ausführen.

AF_SHUTDOWN
Dieses Flag wird nur dem OnExit Handler übergeben und zeigt an, dass sich Ihr Programm schließt, weil PC/GEOS heruntergefahren wird, nicht weil das Programm normal beendet wurde. Sie können dann z.B. Werte, die einen System-Restart überleben sollen in eine Datei sichern und beim wieder Hochfahren des Systems (AF_RESTORE im OnStartup bzw. OnInit Handler gesetzt) wieder auslesen. Es ist aber ein besserer Stil (und meist auch einfacher) Ihr Programm gleich so zu schreiben, dass dies nicht nötig ist.

Der Parameter dataFile$

Sie können R-BASIC Programme wie alle anderen GEOS Programme auch durch einen entsprechenden Eintrag in der GEOS.INI (filenameTokens) mit DOS Dateien bzw. durch Setzten des "Creator" Attributs in VM-Dateien auch mit VM-Dateien verknüpfen. Der Geomanager stellt beim Doppelklick auf eine so verknüpfte Datei eine Verbindung zum zugehörigen Programm her und übergibt ihm den Namen und den Pfad zur Datei. Der Parameter "dataFile$" enthält dann den vollständigen Pfad zu der an das Programm übergebenen Datendatei (z.B. "D:\GEOS\DOCUMENT\INFO.FOO"). In diesem Fall ist auch immer das Flag AF_DATA_FILE im Parameter "flags" gesetzt. Wurde keine Datendatei übergeben so enthält dataFile$ einen Leerstring und das Flag AF_DATA_FILE ist nicht gesetzt.

Hinweis: Für den Zugriff auf den Inhalt von VM-Dateien müssen Sie die VMFiles Library einbinden.

^

4.1.3 Starten und Beenden eines Programms

Das Application Objekt stellt nicht nur die Verbindung zum GEOS System her, es erledigt auch alle Aufgaben, die beim Starten und Beenden eines BASIC Programms anfallen. Dazu gehört insbesondere, das Ausführen des Programmcodes zu starten.

R-BASIC erlaubt es, Programmcode zu schreiben, der nicht Teil einer Routine (SUB oder FUNCTION) oder eines Actionhandlers ist. Alle "klassischen" BASIC Programme und auch viele R-BASIC Beispiele machen davon Gebrauch. Dieser sogenannte "klassische Code" wird beim Start des Programms automatisch ausgeführt.

Beispiel: Ein "Hallo Welt" Programm im klassischen BASIC

ClassicCode
CLS
Print : Print
Print "Hallo Welt"
Print "Willkommen bei R-BASIC!"
Die Anweisung ClassicCode bewirkt drei Dinge:

  • Das Scheiben von Code außerhalb von Routinen wird zugelassen.

  • Es werden automatisch ein paar Objekte angelegt, so dass Grafik und Text ausgegeben werden können.

  • Dieser "klassische" Code wird beim Start des Programms automatisch ausgeführt.

Für ein objektorientiertes Programm ist das nicht nur ein schlechter Stil, sondern es fehlt z.B. die Möglichkeit speziellen Code am Programmende automatisch auszuführen. Das Application Objekt unterstützt deswegen mehrere Actionhandler, die am Programmstart bzw. am Programmende ausgeführt werden.

^

4.1.3.1 Programmstart

Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
OnInit OnInit = <Handler> --
OnStartup OnStartup = <Handler> --

Wenn ein BASIC Programm startet werden die folgenden Schritte in der hier angegebenen Reihenfolge ausgeführt:

  1. Die Objekte werden geladen und vollständig initialisiert, erscheinen aber noch nicht auf dem Schirm.

  2. Wenn vorhanden wird der OnInit-Handler ausgeführt. Dieser Handler kann bereits mit den Objekten interagieren und Dinge erledigen, die vor allen anderen erledigt werden müssen.

  3. Die Objekte erscheinen auf dem Schirm.

  4. Wenn vorhanden wird der OnClpChange-Handler ausgeführt.

  5. Wenn es Objekte gibt, die einen OnDraw-Handler oder einen QueryHandler haben, werden diese Handler jetzt ausgeführt, damit diese Objekte korrekt dargestellt werden.

  6. Wenn vorhanden wird der OnStartup-Handler ausgeführt. Wenn Sie nicht sicher sind, ob eine Aktion in den OnInit oder den OnStartup-Handler gehört, wählen Sie den OnStartup Handler.

  7. Wenn vorhanden wird jetzt der "klassische Code" ausgeführt.
Nach diesen Schritten ist das Programm bereit für weitere Ereignisse.

OnStartup

Der OnStartup Handler ist der übliche Platz für den Initialisierungscode Ihres Programms. Der oben dargestellte "klassische" Code würde in der (besseren) objektorientierte Version so aussehen. Die erste Codezeile im Starthandler verhindert, dass die Grafikausgabe nach einem Neustart von GEOS mit laufendem BASIC-Programm erneut ausgeführt wird. Sie sollten immer im Blick haben, was im OnStartup bzw. OnInit Handler passiert, wenn GEOS bei laufendem Programm neu gestartet wird. Typische Fehler sind hier z.B. das Initialisieren von Objekten mit vorgegebenen Werte - womit bereits von Nutzer veränderte Werte überschrieben werden - oder das erneute Anwenden von Koordinatentransformationen oder grafischen Ausgaben.

UI Code:

Application  MyApp
  Children = MyPrimary
  OnStartup = StartHandler
END OBJECT

BASIC Code:

SystemAction StartHandler 
  IF flags AND AF_RESTORE THEN RETURN
  CLS
  Print : Print
  Print "Hallo Welt"
  Print "Willkommen bei R-BASIC!"
  END Action
Wenn das R-BASIC Programm mit einem Dateityp verknüpft ist und durch Doppelklick auf eine verknüpfte Datei gestartet wird, dann enthält der Parameter dataFile$ den vollständigen Pfad zu dieser Datei. Andernfalls enthält dataFile$ einen Leerstring. Details dazu sind im Abschnitt zur Arbeit mit Dokumenten (siehe unten) beschrieben.

Im Parameter flags können eines oder mehrere der Flags AF_FOR_PRINT, AF_RESTORE oder AF_DATA_FILE gesetzt sein.

OnInit

In einigen Fällen kann es nötig sein bereits BASIC Code auszuführen, wenn noch kein Objekt auf dem Schirm ist. Typisch ist z.B. das Öffnen von Dateien und das Einlesen von Daten, die für Objekte benötigt werden, die bereits beim Programmstart sichtbar sind. Der OnInit-Handler ist immer der allererste BASIC Handler, der ausgeführt wird. Beispiel:

UI Code

Application  MyApp
  Children = MyPrimary
  OnInit = InitHandler
  OnExit = ExitHandler   ' Siehe Abschnitt Programmende
END OBJECT

BASIC Code

DIM f AS FILE   ' globale Variable

SYSTEMACTION InitHandler
DIM anz as word
  f = FileOpen "MyData.TXT"
  IF f = NullFile() THEN f = CreateNewDataFile
  anz = FindAnzahlDatenInFile(f)
  MyDynamicList.count = anz
END Action

Wir nehmen in diesem Beispiel an, dass die Routinen CreateNewDataFile und FindAnzahlDatenInFile sowie die DynamicList MyDynamicList anderswo im Code definiert sind.

Hinweise:

  • Die meisten Programme benötigen keinen OnInit-Handler.

  • Während der OnInit-Handler ausgeführt wird, sind noch keine Objekte auf dem Schirm. Sie erscheinen erst wenn der OnInit Handler abgearbeitet ist. Sehr umfangreiche (lange laufende) OnInit-Handler verzögern deswegen den "gefühlten" Programmstart.

  • Prinzipiell gibt es keine Einschränkungen bezüglich der in einem OnInit-Handler verwendbaren Befehle. Insbesondere ist es zulässig mit Objekten zu interagieren, deren Instancevariablen zu lesen oder zu ändern.

  • Der OnInit-Handler wird auch beim Neustart von GEOS bei laufendem BASIC-Programm ausgeführt. Mit der Codezeile
   IF  flags AND AF_RESTORE THEN RETURN
    können Sie verhindern, dass in diesem unerwünschter Initialierungscode erneut ausgeführt wird.

  • Vermeiden Sie die Verwendung von "klassischen" Interaktionsbefehlen wie INPUT oder InKey$ im OnInit-Handler. Das erzeugt nur Chaos.

  • Wenn Sie nicht sicher sind, ob sie den OnInit- oder den OnStartup-Handler verwenden sollen, wählen Sie zunächst den OnStartup-Handler. Nur wenn Sie mit dem Ergebnis nicht zufrieden sind verschieben Sie Teile des Codes in den OnInit-Handler.
Wenn das R-BASIC Programm mit einem Dateityp verknüpft ist und durch Doppelklick auf eine verknüpfte Datei gestartet wird, dann enthält der Parameter dataFile$ den vollständigen Pfad zu dieser Datei. Andernfalls enthält dataFile$ einen Leerstring. Details dazu sind im Abschnitt zur Arbeit mit Dokumenten (siehe unten) beschrieben.

Im Parameter flags können eines oder mehrere der Flags AF_FOR_PRINT, AF_RESTORE oder AF_DATA_FILE gesetzt sein.

^

4.1.3.2 Programmende

Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
OnExit OnExit = <Handler> --

Ein BASIC Programm kann durch den Menüeintrag "Beende ..." oder durch den BASIC Befehl EXIT beendet werden. Auch im Falle eines Laufzeitfehlers wird das Programm automatisch beendet. In allen diesen Fällen erledigt das Application Objekt die folgenden Schritte:

  1. Wenn vorhanden wird der OnExit-Handler ausgeführt. Sie können hier z.B. abfragen, ob geänderte Daten gespeichert werden sollen.

  2. Die Objekte werden vom Schirm genommen, bleiben aber noch intakt.

  3. Die Event-Warteschlage wird geleert. Events, die noch in der Warteschlange stehen, werden nicht mehr ausgeführt, d.h. die dazugehörigen Handler werden nicht mehr gerufen.

  4. Die Objekte und internen Datenstrukturen werden aufgeräumt.

Hinweise:

  • Der OnExit-Handler (wenn vorhanden) wird auch dann ausgeführt, wenn es vorher einen Laufzeitfehler gegeben hat.

  • Beim Herunterfahren von PC/GEOS die globalen BASIC Variablen nicht automatisch gesichert. Sie sollten ihre Programme grundsätzlich so schreiben dass dies nicht nötig ist - oder Sie müssen sich selbst darum kümmern.

OnExit

Der OnExit-Handler wird automatisch ausgeführt, wenn das Programm geschlossen wird. Er muss als SystemAction deklariert sein. Sie sollten im OnExit-Handler alle Ressourcen freigeben (z.B. Dateien schließen) die Sie im OnInit oder im OnStartup Handler angefordert haben.

Beispiel (bezieht sich auf den Code des OnInit Handlers oben):

SYSTEMACTION ExitHandler
  FileClose f
  f = NullFile()
END Action
Im Parameter flags kann das Flag AF_SHUTDOWN gesetzt sein. In diesem Fall darf man keine Messageboxen oder Dialoge aktivieren, sonst hängt das System.

Beispiel 2: Die SUB's DoSaveData (Daten speichern) und DoCloseFile (Datei Schließen) müssen irgendwo anders definiert sein.

SYSTEMACTION ExitHandler
  IF (flags AND AF_SHUTDOWN) = 0 THEN
  IF QuestionBox ("Daten speichern?") = YES THEN DoSaveData
  End IF
  DoCloseFile
END Action

^

4.1.4 Arbeit mit Dokumenten

Im Handbuch "Spezielle Themen", Kapitel 15 finden Sie eine ausführliche Beschreibung, wie man ein komplettes Dokument-Interface implementiert.

Instance-Variablen:

Variable Syntax im UI-Code Im BASIC-Code
OnConnection OnConnection = <Handler> nur schreiben

Sie können R-BASIC Programme durch einen entsprechenden Eintrag in der GEOS.INI (filenameTokens) mit DOS Dateien bzw. durch Setzten des "Creator" Attributs in GEOS-Dateien auch mit GEOS-Dateien verknüpfen. "Startet" der Nutzer eine solche Datei z.B. durch Doppelklick im Geomanager so wird die Datei im Parameter dataFile$ (vgl. Kapitel 4.1.1) je nach Situation an den OnInit bzw. den OnStartup oder an den OnConnection-Handler übergeben. Gemeinsam mit dem OnStartup Handler (seltener mit dem OnInit Handler) können Sie mit dem OnConnection-Handler die Arbeit mit Dokumenten organisieren.

OnConnection

Der OnConnection-Handler wird gerufen, wenn ein anderes Programm (z.B. der Geomanager) einer Verbindung (Connection) zum BASIC Programm herstellt und der OnInit bzw. OnStartup Handler nicht in Frage kommt, da das BASIC Programm bereits läuft. Üblicher Weise wird eine solche Connection hergestellt, wenn das BASIC Programm mit einem Dateityp verknüpft ist und der Nutzer eine so verknüpfte Datei im Geomanager durch Doppelklick startet.

Dabei gelten die folgenden Regeln:

  • Wenn ein R-BASIC Programm durch Doppelklick auf eine verknüpfte Datei gestartet wird, so wird der Pfad zu dieser Datei sowohl dem OnInit- als auch dem OnStartup-Handler im Parameter dataFile$ übergeben. OnConnection wird beim Öffnen des Programms nicht gerufen!

  • Doppelklickt der Nutzer eine verknüpfte Datei jedoch während das R-BASIC Programm läuft wird der OnConnection-Handler gerufen, wobei auch hier der Parameter dataFile$ den vollständigen Pfad zur übergebenen Datei (z.B. "D:\GEOS\DOCUMENT\DEMO.RBF") enthält.

  • In beiden Fällen ist im Parameter flags das Flag AF_DATA_FILE gesetzt, das Flag AF_FOR_PRINT kann zusätzlich gesetzt sein.

Achtung! Es ist denkbar, wenn auch sehr unwahrscheinlich, dass andere Programme (außer dem Geomanager) eine Verbindung zu Ihrem BASIC Programm herstellen. In diesem Fall kann ebenfalls eine Datendatei übergeben werden, häufiger ist jedoch, dass in diesem Fall keine Datei übergeben wird. Prüfen Sie in ihrem OnConnection-Handler also immer das Bit AF_DATA_FILE (bzw. die Länge von dataFile$) ab!

Beispiel:

Nehmen wir an, Sie möchten einen Viewer für R-BASIC Blockgrafik Fontdateien (RBF-Dateien) schreiben. Der Viewer soll beim Doppelklick auf eine RBF-Datei gestartet werden bzw., wenn er bereits läuft, die angeklickte Datei anzeigen. Dazu nehmen wir folgendes als gegeben an:

  • Es existiert eine globale Dateivariable f. Diese referenziert die offene Fontdatei.

  • Die selbst geschriebene Routine DisplayFontData zeigt die gewünschten Inhalte an.
 DECL SUB DisplayFontData(fh as FILE)

  • Der Geomanager zeigt RBF-Dateien mit dem Token "Font",5 an.

  • Ihr Viewer hat das Token "RbfV",16600.

In der GEOS.INI muss sich die folgende Verknüpfung befinden:

[fileManager]
filenameTokens = {
    *.RBF="Font",5,"RbfV",16600
 ....
}

Ausschnitt aus dem UI Code:

Application RBFViewerApplication
  OnStartup = ViewerStartupHandler
  OnConnection = ViewerNewFileHandler
  OnExit = ViewerExitHandler
  AppToken = "RbfV",16600
  DocToken = "Font",5
  ....
End OBJECT

Der passende BASIC Code dazu:

SYSTEMACTION ViewerStartupHandler
  ! Prüfen ob eine Datei übergeben wurde
  IF Len(dataFile$) THEN
  f = FileOpen ( dataFile$, "r") ! Nur Lesen reicht.
  DisplayFontData ( f )
  End IF
  ! Alternativ könnte man auch AF_DATA_FILE prüfen
  ! IF  flags AND AF_DATA_FILE  THEN ...
END Action

SYSTEMACTION ViewerNewFileHandler
  ! Prüfen ob überhaupt eine Datei übergeben wurde
  IF (flags AND AF_DATA_FILE) = 0 THEN return
  ! eventuell offene Datei schließen
  IF f <> NullFile() THEN FileClose(f)
  ! Neue Datei anzeigen
  f = FileOpen ( dataFile$, "r")
  DisplayFontData(f)
END Action

SYSTEMACTION ViewerExitHandler
  IF f <> NullFile() THEN FileClose(f)
END Action

Bei Bedarf können Sie noch ein Dateimenü (Buttons "Öffnen" und "Schließen") hinzufügen.

^

4.1.5 Überwachung der Zwischenablage

OnClpChange

Um in R-BASIC z.B. ein "Bearbeiten" Menü zu implementieren müssen Sie wissen, wenn jemand etwas ins Clipboard kopiert und was es ist. Dann können Sie z.B. einen "Einfügen" Schalter enablen oder disablen. Für dieses Zweck verfügt das Application Objekt über einen speziellen Actionhandler, der immer dann aufgerufen wird, wenn sich im Clipboard etwas tut. Der ActionHandler muss als "SystemAction" implementiert sein.

Im UI Code:

Application DemoApplication
  Children = DemoPrimary
  OnClpChange = ClpChangeHandler
END Object

' folgende Objekte sollen existieren:
BitmapContent DemoBitmap
Button PasteButton

Im BASIC Code:

'
' Der Handler enabled oder disabled den Einfügen Button
'
SYSTEMACTION ClpChangeHandler
DIM ok
  ok = DemoBitmap.ClpTestPaste
  IF ok THEN
    PasteButton.enabled = TRUE
  ELSE
    PasteButton.enabled = FALSE
  END IF
END Action
Der OnClpChange Handler wird automatisch immer dann aufgerufen, wenn sich die Daten im Clipboard ändern. Die übergebenen Parameter sind hier ohne Bedeutung und sollten ignoriert werden. Details zur Arbeit mit dem Clipboard und dem OnClpChange Handler erfahren Sie im Kapitel "Arbeit mit der Zwischenablage" und insbesondere im Abschnitt "Das Clipboard überwachen"

^

4.1.6 Der Busy-Status

Gelegentlich kommt es vor, dass Ihr Programm "beschäftigt" ist und nicht sofort auf weitere Usereingaben reagieren kann. Der übliche Weg, dies dem User deutlich machen ist, den Mauszeiger zu einer "Sanduhr" werden zu lassen. Für diesen Zweck gibt es den "Busy" (= beschäftigt) Status. Je nachdem, ob sie während dessen auf die Usereingaben reagieren können oder wollen gibt es verschiede Wege, den Busy-Status zu aktivieren.

Methoden:

Methode Aufgabe
MarkBusy Busy-Status aktivieren
MarkNotBusy Busy-Status verlassen
HoldUpInput Usereingaben zwischenspeichern
ResumeInput Zwischengespeicherte Usereingaben ausführen
IgnoreInput Alle Usereingaben ignorieren
AcceptInput Usereingaben wieder akzeptieren


       Syntax BASIC-Code: <obj>.MarkBusy
                          <obj>.MarkNotBusy

Selten genutzte Methoden: <obj>.HoldUpInput <obj>.ResumeInput <obj>.IgnoreInput <obj>.AcceptInput


Wichtig! Alle hier aufgeführten Methoden sind kumulativ, das heißt sie können mehrfach hintereinander ausgeführt werden und z.B. zu jedem MarkBusy wird ein eigenes MarkNotBusy benötigt.

  DemoAppliacation.MarkBusy     ' jetzt busy
  DemoAppliacation.MarkBusy     ' 2x busy
  DemoAppliacation.MarkNotBusy  ' immer noch busy
  DemoAppliacation.MarkNotBusy  ' jetzt nicht mehr

MarkBusy, MarkNotBusy

Der Aufruf von MarkBusy lässt den Mauszeiger zu einer Sanduhr werden, um anzuzeigen, dass das Programm beschäftigt ist. Ansonsten passiert nichts, der Nutzer kann weiterhin Objekte anklicken und z.B. Texte eingeben. MarkNotBusy nimmt ein MarkBusy zurück.

HoldUpInput, ResumeInput

HoldUpInput weist die UI an, Usereingaben nicht sofort an das Programm weiterzuleiten, sondern zwischenzuspeichern. Dabei wird der Mauszeiger nicht zur Sanduhr. Üblicher Weise wird deshalb HoldUpInput gemeinsam mit MarkBusy verwendet. ResumeInput weist die UI an, die zwischengespeicherten Usereingaben an das Programm weiterzuleiten, so dass sie behandelt werden können.

Verwenden Sie die beiden Methoden nur, wenn Sie keine andere Möglichkeit sehen, da der Nutzer schnell den Eindruck bekommen kann, das Ihr Programm "hängt".

IgnoreInput, AcceptInput

IgnoreInput weist die UI an, alle folgenden Eingaben zu blockieren. AcceptInput hebt diesen Zustand wieder auf. Alle zwischen IgnoreInput und AcceptInput erfolgten Eingaben (z.B. Klicks auf einen Button) sind verloren. Verwenden Sie diese Befehle nur als allerletzten Ausweg!

^

Weiter...