GFA Basic unterstĂŒtzt GEM so, dass die Erstellung von Programmen sehr leicht ist. Und die GFA Systemtechnik wartet noch mit einem weiteren bonbon auf: Mitgeliefert wird ein komfortables Resource Construction Set, das RCS2.PRG. Dass es beim Start irgendwelche Dateien auf dem Laufwerk A: sucht, ist zwar nicht schön (besonders bei einer Harddisk), aber dem Programm nicht weiter abtrĂ€glich.
So schön dieses Programm auch ist, die Ausgabe der benannten Objekte als LST-File handhabt es mit einer nicht zu ĂŒbersehenden Formlosigkeit. Objektnamen und BĂ€ume werden in der Reihenfolge geschrieben, in der sie benannt wurden. Wie ein solches LST-File mit 20 BĂ€umen und 300, 400 Objekten nach der 12. Ănderung aussieht, kann sich wohl jeder denken. Ein Wust von Objektnamen, Baumbezeichnungen: Hinter dem MenĂŒeintrag Nr. 32 in Baum 0 steht der Button aus Baum 15, der Name von Baum 0 steht irgendwo mittendrin, in Zeile 352...
Also, Möglichkeit Nr.1, dort Ordnung zu schaffen: Von jedem Baum eine Hardcopy, die Objekte numeriert und die Namen irgendwo auf dem Blatt mit der Nummer notiert. FĂŒr RSC-Dateien bis zu zwei BĂ€umen mit 20 Objekten kein Problem, zur Not merkt man sich die Namen auch so. Aber bei 80, 90, 100, 200 oder mehr Objekten dĂŒrfte es damit etwas schwierig werden.
Die zweite Möglichkeit zeigt mein Programm, das in dieses Chaos Ordnung bringt: Es sortiert das File.
Zuerst stehen die BĂ€ume, der Nummer nach sortiert. Danach kommen fĂŒr jeden Baum die Objekte (auch sortiert). Und damit die Schreibarbeit noch mehr vermindert wird, stehen fĂŒr jedes Objekt noch der Typ und bei Textobjekten (also auch bei Buttons) die ersten 20 Zeichen dahinter. AuĂerdem werden bei jedem Objekt der Status, z.B. SELECTED - d.h. das Objekt ist invertiert dargestellt - und die gesetzten Flags wie EDITABLE, HIDDEN, TOUCHEXIT angegeben, allerdings als KĂŒrzel. Davon jedoch spĂ€ter mehr. Die Angabe der Nummer des entsprechenden Baumes bleibt natĂŒrlich erhalten. Doch betrachten wir nun das Programm:
ZunĂ€chst setzen wir die Untergrenze der Arrays auf 1, damit spĂ€terhin die Sortierfunktion korrekt sortiert. Ohne diese MaĂnahme bliebe das Element 0 immer leer und könnte die Routine stören. Dann werden etliche Arrays definiert, die Bestimmung der einzelnen Felder entnehmen Sie bitte den Kommentaren. AuĂerdem kommen wir bei einigen Feldern auf ihre Bestimmung noch zu sprechen. Als Eckdaten gelten:
zu verwaltende Objekte: max. 500
zu verwaltende BĂ€ume: max. 30 Objekte
pro Baum: max. 150
Insgesamt mögen die Daten als etwas sehr hoch angesetzt erscheinen, doch habe ich selbst gemerkt, daà bei leistungsfÀhigen Dialogen und Dialogen zur Dateneingabe mit Leichtigkeit 100 Objekte Zusammenkommen. Doch weiter im Programm:
Zuerst wird das Includefile mittels RECALL in das Array a$() eingelesen. Dann mĂŒssen die Objekte grob vorsortiert werden, damit die Objekte gleicher BĂ€ume zusammengefaĂt werden können. Dabei werden die verstreuten BĂ€ume auch gleich an die Spitze gestellt. Dazu mĂŒssen die Baumnummern, die zu den Objekten gehören, festgestellt werden. Wir bedienen uns des Formats der Anweisungszeilen:
Bei Objekten:
âobjcname&=
objnr !Obj in #baumnrâ
z.B.: EXIT&=15 !Obj in #6
Bei BĂ€umen:
âtreename&=
treenr !RSC_TREE'
z.B.: DIALOG&=6 !RSC_TREE
Die Baumnummer steht also hinter dem '#â (genannt Hash [hĂ€sch]). Bei BĂ€umen ist das nicht der Fall. Also stellen wir die Position des Hashs fest. Ist sie ungleich Null, liefert die VAL( )-Funktion des dahinter liegenden Teilstrings die Baumnummer des Objektes. Ist die Position Null, haben wir die Zuweisung einer Baumnummer vor uns und setzen das Element a&() auf minus eins.
Gleichzeitig setzen wir das entsprechende Array-Element a%() auf den Index i%. In der nun folgenden Sortierung wird neben dem Array a&() das Array a%() mitsortiert.
Bild 1: Phase 1 der Sortierung
Bild 2: Man kann sich auch die einzelnen BĂ€ume und Objekte des Resources anzeigen lassen.
Wozu das alles?
Nehmen wir an, bei der Sortierung ist das Element a&(5) auf die Stelle 53 gelangt. Nun steht in a%(53) der Index 5, weil a%(5) ebenfalls auf die Stelle 53 verschoben wurde. Beim Umspeichern in das Array b$() muĂ in das Element b$(53) das Element a$(5) geschrieben werden. Genau dieser Index steht aber in a%(53)! Also heiĂt die Anweisungszeile b$(i%)=a$(a%(i%)). Ăhnliche Zeilen werden wir noch öfter sehen.
Die Zuweisungen der Baumnummern stehen nach der Sortierung an der Spitze des Arrays b$(), weil die entsprechenden a&()-Elemente gleich minus eins sind.
Die Anzahl der BĂ€ume wird danach ermittelt. Solange das nĂ€chste a&()-Element gleich minus eins ist, wird die Variable t% um eins erhöht. Danach wird die Variable ende% auf t% gesetzt. Nun werden noch einige benötigte Felder dimensioniert, die fĂŒr die weitere Bearbeitung nötig sind. Was nun ablĂ€uft, haben wir am Anfang ganz genau betrachtet, so daĂ wir uns um die Sortierung der BĂ€ume nicht mehr zu kĂŒmmern brauchen. FĂŒr die weitere Bearbeitung ist die Speicherform des eindimensionalen Feldes (Vektor) schlecht geeignet. Besser geeignet ist nun ein zweidimensionales Array, auch Matrix genannt. In der Matrix gibt es Zeilen und Spalten, sie ist also praktisch eine Tabelle. Nun speichern wir die Objektindizes so ab, daĂ in den Spalten der ersten Zeile alle Objekte des ersten Baumes stehen. In der zweiten Zeile stehen dann alle Objekte des zweiten Baumes usw. In der gleichen Art werden auch die Zuweisungszeilen gespeichert. Gleichzeitig werden auch die Objekte eines Baumes mittels des Vektors obj_count&() gezĂ€hlt.
Jetzt ist alles bereit, und die RSC-DATEI kann geladen werden. Nachdem diese im Speicher steht, werden mit ~RSRC_GADDR die Adressen der BÀume, deren Nummern in t&() stehen, in t%() gespeichert. Nun ist alles nur noch halb so schwer, wie es aussieht. Systematisch werden die Objekttypen der Objekte festgestellt. Dabei wird der Startwert beginge der inneren i%-Schleife bei jedem erfolgreichen Durchlauf auf den um eins erhöhten aktuellen i%-Wert gesetzt. Gleichzeitig wird das Flag ex! auf FALSE (logisch falsch) gesetzt, damit die Schleife nicht verlassen wird.
Beim nĂ€chsten Durchlauf wird sie wieder auf TRUE gesetzt, damit im Falle eines erfolglosen Durchlaufs die Schleife sofort verlassen wird. In begin% steht nun der i%-Wert, bei dem die Schleife verlassen wurde und bei dem der Wiedereinstieg erfolgen muĂ, da wir den nĂ€chsten Baum bearbeiten. Diese optimale Bearbeitung ist aber nur deshalb möglich, weil alle Objekte eines Baumes durch die grobe Vorsortierung direkt hintereinander stehen und nicht im gesamten Vektor b$() verstreut sind. Diese Routine ist die zeitkritischste im Programm. Ersetzen Sie begin% durch ende%+1, so braucht die Routine je nach DateigröĂe bis ĂŒber das Doppelte an Zeit.
AnschlieĂend wird die Zuweisungszeile um die Angabe des Objekttyps erweitert, die Vorgehensweise dĂŒrfte keine VerstĂ€ndnisprobleme aufwerfen. Wenn es sich beim Baum um einen MenĂŒbaum handelt und das Objekt vom Typ STRING ist, haben wir es mit einem MenĂŒeintrag, neudeutsch ENTRY genannt, zu tun und nennen ihn auch so. Einen MenĂŒbaum erkennen wir daran, daĂ das dritte Objekt ein G_TITLE ist (OB TYPE(tree%,3)=32).
Dann benötigen nur noch die Zeichenketten der Textobjekte wie STRING, TEXT, BOXTEXT, FTEXT (EDIT), FBOXTEXT (BOXEDIT), BUTTON. Bei STRING und BUTTON liefert uns OB_SPEC(tree%,obj&) die Adresse des entsprechenden Strings. Die Funktion CHAR{} liest den String an dieser Adresse aus. Bei den anderen Textobjekten liefert uns OB_SPEC() 'nur' die Adresse eines Zeigers, der die Adresse des uns interessierenden Strings enthĂ€lt. Deshalb wird CHAR{{}} verwendet. Die Leerzeichen links und rechts dieses Strings werden mit TRIM$() gelöscht (soweit vorhanden) und die ersten 20 Zeichen an die Befehlszeile angehĂ€ngt. Nun werden Status und Flags der Objekte abgefragt, indem die einzelnen Bits der entsprechenden Strukturen mittels BTST() getestet werden. Ein Objektstatus wird in GroĂbuchstaben geschrieben und mit einem Slash (â/â) getrennt, wĂ€hrend bei den Flags Kleinbuchstaben und ein âIâ Verwendung finden. Hier sind alle KĂŒrzel aufgefĂŒhrt:
/SLCT:SELECTED /CRSS:CROSSED /CHCK:CHECKED
/D'ABL: DISABLED /OUTLN:OUTLINED /SHWD:SHADOWED
|slctbl:SELECTABLE |default:DEFAULT |exit:EXIT
|edit:EDITABLE |radio :RBUTTON |last :LASTOB
|touch:TOUCHEXIT |hide :HIDETREE (HIDDEN)
Alle KĂŒrzel auf einen Blick
Damit sind wir fast am Ende des eigentlichen Programms. Zum SchluĂ werden auf die altbekannte Art und Weise die Objekte jedes Baumes sortiert. Danach werden die Objektbaumnummern in der richtigen Reihenfolge gespeichert und wieder in den Vektor b$() zurĂŒckgeschrieben. Die ersten ende%-Elemente sind die ObjektbĂ€ume. SchlieĂlich werden die ergĂ€nzten und sortierten Zuweisungszeilen aus dem Array obj_line$() in den Vektor b$() geschrieben. Die eigentliche Routine ist nun beendet. Der Rest sind kleine Routinen, die nicht weiter schwierig zu verstehen und auĂerdem ausfĂŒhrlich dokumentiert sind.
Bei der Ausgabe erfolgt zunĂ€chst die Angabe der ObjektbĂ€ume. Danach ist es möglich, sich die BĂ€ume anzeigen zu lassen. Haben wir kein MenĂŒ vor uns, so wird der Baum zentriert, bevor er angezeigt wird. Die BĂ€ume werden ausnahmslos mittels OBJC_DRAW() aufgebaut, so werden Schwierigkeiten mit der MenĂŒverwaltung vermieden.
Zum AbschluĂ sei noch ein Wort zum Programm selbst gesagt: NatĂŒrlich kommt Unsinn zustande, wenn Include -file und RSC-Datei nicht zueinandergehören, Tests auf diesem Gebiet sind also unnötig. Auch sollte ein MenĂŒ immer an erster Stelle im Resource stehen. Genauso ist es auch möglich, aus dem RSC-Header die Anzahl der BĂ€ume direkt auszulesen. Doch das ist nur interessant, wenn kein Includefile vorhanden ist, wie es bei einem RSC-Analyser der Fall ist. Das vorliegende Programm soll nur zeigen, was mit den Sortierungsroutinen gemacht werden kann und wie SchlĂŒsselfelder benutzt werden. Zudem ist das Programm in meinen Augen ein gutes, einfaches und sinnvolles Beispiel, wie bequem in GFA BASIC 3.xx Objekte behandelt werden können.
Literatur:
Szczepanowski,
Das groĂe GEM-Buch zum ATARI ST
DATA BECKER Verlag 1985
GFA BASIC 3.0 Handbuch
LET MENUE&=0 !RSC_TREE
LET EXAMPLE1&=1 !RSC_TREE
LET EXAMPLE2&=2 !RSC_TREE
LET DESK&=3 »Obj in #0 TITLE:'Desk'
LET FILE&=4 !Obj in #0 TITLE:'File'
LET INFO&=7 !Obj in #0 ENTRY:'Hier ist das Info'
LET QUIT&=16 !Obj in #0 ENTRY:'Quit'
LET DATEI&=17 !Obj in #0 ENTRY:'Datei'
LET LADEN18 !Obj in #0 ENTRY:'laden'
LET SPEICHER&=19 !Obj in #0 ENTRY:'speichern'
LET ICONBOX&=20 !Obj in #0 BOX|last
'
LET BUTTON&=l !Obj in #1 BUTTON:'BUTTON'|slctbl
LET STRING&=2 !Obj in #1 STRING:'STRING'
LET EDIT&=3 !Obj in #1 EDIT:'_______'|edit
LET BOXEDIT&=4 !Obj in #1 BOXEDIT:'____'|edit
LET TEXT&=5 !Obj in #1 TEXT:'TEXT'
LET BOXCHAR& = 6 !Obj in #1 BOXCHAR
LET BOXTEXT&=7 »Obj in #1 BOXTEXT:'BOXTEXT'
LET ICON&=8 !Obj in #1 ICON
LET IMAGE&=9 !Obj in #1 IMAGE
LET BOX1&=10 !Obj in #1 BOX
LET STRB0X1&=11 !Obj in #1 STRING:'BOX 1â
LET BOX2&=12 !Obj in #1 IBOX/OUTLN
LET STRBOX2&=13 !Obj in #1 STRING:'BOX 2â |last
'
LET BUTTON2&=l !Obj in #2 BUTTON:'BUTTON'/SLCT|slctbl|default|exit|radio
LET STRING2&=2 !Obj in #2 STRING:'STRING'
LET EDIT2&=3 !Obj in #2 EDIT:'_______'/SLCT/D'ABL/OUTLN|edit
LET BOXEDIT2&=4 !Obj in #2 BOXEDIT:'____'|edit
LET TEXT2&=5 !Obj in #2 TEXT: 'TEXT'
LET BOXCHAR2&=6 !Obj in #2 BOXCHAR/CRSS/CHCK/SHDW|slctbl|exit|touch
LET BOXTEXT2&=7 !Obj in #2 BOXTEXT:'BOXTEXT'/SHDW
LET ICON2&=8 !Obj in #2 ICON
LET IMAGO2&=9 !Obj in #2 IMAGE/SLCT|slctbl|exit|radio
LET BOXO2&=10 !Obj in #2 BOX/SLCT/SHDW
LET IBOX2&=12 !Obj in #2 IBOX/OUTLN
' (c) MAXON Computer GmbH
OPTION BASE 1 ! Nötig zum korrekten Sortieren
DIM a$(500) ! Original-File
DIM a&(500) ! Baumnummern der Objekte, TREE=-1
DIM b$(500) ! Sortiertes File, da andere Reihenfolge als im Original
DIM a%(500) ! Index-SchlĂŒssel, nötig zum sortierten Umspeichern
DIM z%(150) ! Index-SchlĂŒssel f.Objektsortierung
DIM z$(150) ! Anweisungszeilen fĂŒr Objektnamen
DIM s% (150) ! Objekt-Indizes
DIM spec$(20) ! Objekt-Bezeichnungen
DIM spec|(20) ! Objekt-Typen
DIM obj&(30,150) ! Objekt-Nummer
DIM obj_count&(30) ! Anzahl der Objekte pro Baum
DIM obj$(30,150) ! Text der Objekte
DIM obj_type|(30,150) ! Typ der Objekte
DIM obj_line$(30,150) ! Befehlszeilen
'
init_spec
abbruch!=FALSE
REPEAT
CLS
original$="\*.LST"
lst_file$="\*.LST"
r$="\*.RSC"
PRINT AT(32,2);"MERGE-File lesen"
get_in_file(original$)
CLS
abbruch!=(LEN(original$)=0)
IF NOT abbruch!
PRINT AT(32,2);"RSC-Datei laden"
get_in_file(r$)
CLS
abbruch!=(r$="")
ENDIF
IF NOT abbruch!
IF EXIST(original$)
'
'
PRINT "Original-File lesen"
OPEN "I",#1,original$
RECALL #1,a$(),-1,n%
CLOSE
'
t=TIMER
PRINT "Objektindizes nach Baumnummern sortieren"
PRINT "Objekte nach Baumnummern intern indizieren"
FOR i%=1 TO n%
a%(i%)=i%
p|=RINSTR(a$(i%),"#")
'
' Baumnummer in der Befehlszeile feststellen
'
IF p|<>0
a&(i%)=VAL(MID$(a$(i%),p|+1))
ELSE
a&(i%)=-1 ! Bei Baumnamen ist kein '#' in der Anweisungszeile vorhanden
ENDIF
NEXT i%
PRINT "Sortierung lÀuft"
SSORT a&(),n%,a%() ! Objekte n.Baumnummern sortieren
'
PRINT "Umschichtung lÀuft" ^
FOR i%=1 TO n%
b$(i%)=a$(a%(i%)) ! Befehlszeilen nach sortierten Objekten abspeichern
NEXT i%
'
PRINT "Feststellen der Baumanzahl"
t%=0
WHILE a&(t%+1)=-1
INC t%
WEND
'
ende%=t%
'
ERASE t&(),t%(),ts%()
DIM t&(t%) ! Baumnummern
DIM t%(t%) ! Baumadressen
DIM ts%(t%) ! Baumindizes
'
PRINT "Baumnummern speichern"
FOR t%=1 TO ende%
t$=b$(t%)
IF INSTR(t$,"#")=0 ! Nur BĂ€ume
p|=INSTR(t$,"=") ! Baumnummer suchen in der Befehlszeile
IF p|<>0
t&(t%)=VAL(MID$(t$,p|+1)) ! Baumnummer abspeichern
ts%(t%)=t%
ENDIF
ENDIF
NEXT t%
PRINT "Baumnummern sortieren"
SSORT t&(),ende%,ts%() ! Baumnummern sortieren
'
ARRAYFILL obj&(),-1
PRINT "Objektindizes aufbereiten BAUM ";
x%=CRSCOL
y%=CRSLIN
'
' Hier werden die Objekte in einer Art Tabelle (2D-Array) nach den BĂ€umen
' geordnet abgespeichert, dadurch wird die Handhabung wesentlich leichter.
' In der gleichen Art werden auch die Befehlszeilen umgeschichtet, um
' das spĂ€tere zurĂŒckspeichern in das File-Array zu erleichtern.
'
begin%=ende%+1
FOR t%=1 TO ende%
PRINT AT(x%,y%);t&(t%)
count%=0
obj_count&(t%)=0
IF begin%<=n%
FOR i%=begin% TO n%
ex!=TRUE
t$=b$(i%)
'
' Zu welchem Baum gehört das Objekt?
' Abfrage nach '#baumnummer' am Ende der Zeile
'
IF RIGHT$(t$,LEN(STR$(t&(t%)))+1)="#"+STR$(t&(t%))
p|=INSTR(t$,"=") !Objektnummer finden
IF p|<>0
INC count%
ex!=FALSE
begin%=i%+1
obj&(t&(t%)+1,count%)=VAL(MID$(t$,p|+1)) ! Objektnumme
obj_line$(t&(t%)+1,count%)=t$ ! Befehlszeile
INC obj_count&(t%)
ENDIF
ENDIF
EXIT IF ex!
NEXT i%
ENDIF
NEXT t%
'
PRINT "RSC-Datei laden"
@load_rsc(r$)
IF load!
PRINT "Objektadressen ermitteln"
FOR t%=1 TO ende%
~RSRC_GADDR(0,t&(t%),t%(t%))
NEXT t%
'
PRINT "Objekttypen feststellen BAUM ";
x%=CRSCOL
y%=CRSLIN
FOR t%=1 TO ende%
PRINT AT(x%,y%);t&(t%)
FOR k&=1 TO obj_count&(t%)
obj_type|(t%,k&)=BYTE(OB_TYPE(t%(t%),obj&(t%,k&))) ! Typ des Obj.
'
' Bezeichnung des Typs finden
'
FOR i|=1 TO n|
IF obj_type|(t%,k&)=spec|(i|)
'
' Wenn das dritte Objekt eines Baumes ein G_TITLE ist, so
' haben wir es mit einem Menue zu tun.
' Die EintrÀge im Menue sind allesamt Strings,
' obwohl die Titel einen eigenen Typ besitzen.
' Daher wird auf Menue und Titel geprĂŒft.
'
IF OB_TYPE(t%(t%),3)<>32 OR OB_TYPE(t%(t%),obj&(t%,k&))=32 OR OB_TYPE (t% (t%),obj&(t%,k&))<>28
obj_line$(t%,k&)=obj_line$(t%,k&)+" "+spec$(i|)
ELSE
obj_line$(t%,k&)=obj_line$(t%,k&)+" ENTRY"
ENDIF
ENDIF
EXIT IF obj_type|(t%,k&)=spec|(i|)
NEXT i|
'
NEXT k&
NEXT t%
PRINT "STRING-Objekte kenntlich machen BAUM ";
x%=CRSCOL
y%=CRSLIN
FOR t%=1 TO ende%
PRINT AT(x%,y%);t&(t%)
FOR k&=1 TO obj_count&(t%)
SELECT obj_type|(t%,k&)
CASE 21,22,29,30 ! Objekt des Typs 'TEXT / FTEXT'
a$=CHAR{{OB_SPEC(t%(t%),obj&(t%,k&))}} ! Text lesen
IF ASC(TRIM$(a$))<32
a$="**"
ENDIF
obj_line$(t%,k&)=obj_line$(t%,k&)+":'"+LEFT$(TRIM$(a$),20)+"'"
CASE 26,28,32 ! Objekt des Typs STRING (ENTRY) / BUTTON / TITLE
a$=CHAR{OB_SPEC(t%(t%),obj&(t%,k&))}
IF ASC(TRIM$(a$))<32
a$="**"
ENDIF
obj_line$(t%,k&)=obj_line$(t%,k&)+":'"+LEFT$(TRIM$(a$),20)+"â"
ENDSELECT
FOR s|=0 TO 5
IF BTST(OB_5TATE(t%(t%),obj&(t%,k&)),s|)
SELECT s|
CASE 0
state$="SLCT"
CASE 1
state$="CRSS"
CASE 2
state$="CHCK"
CASE 3
state$="D'ABL"
CASE 4
state$="OUTLN"
CASE 5
state$="SHDW"
ENDSELECT
obj_line$(t%,k&)=obj_line$(t%,k&)+"/"+state$
ENDIF
NEXT s|
'
FOR s|=0 TO 7
IF BTST(OB_FLAGS(t%(t%),obj&(t%,k&)),s|)
SELECT s|
CASE 0
state$="slctbl"
CASE 1
state$="default"
CASE 2
state$="exit"
CASE 3
state$="edit"
CASE 4
state$="radio"
CASE 5
state$="last"
CASE 6
state$="touch"
CASE 7
state$="hide"
ENDSELECT
obj_line$(t%,k&)=obj_line$(t%,k&)+"|"+state$
ENDIF
NEXT s|
NEXT k&
NEXT t%
PRINT "Sortieren der Objekte innerhalb der BĂ€ume. BAUM ";
x%=CRSCOL
y%=CRSLIN
FOR t%=1 TO ende%
PRINT AT(x%,y%);t&(t%)
FOR k&=1 TO obj_count&(t%)
z$(k&)=obj_line$(t%,k&)
p|=INSTR(z$(k&),"=")
IF p|<>0
s%(k&)=VAL(MID$(z$(k&),p|+1))
ENDIF
z%(k&)=INT(k&)
NEXT k&
SSORT s%(),obj_count&(t%),z%()
'
FOR k&=1 TO obj_count&(t%)
obj_line$(t%,k&)=z$(z%(k&))
NEXT k&
NEXT t%
'
PRINT "RĂŒckspeichern der BĂ€ume"
FOR i%=1 TO ende%
z$(i%)=b$(ts%(i%))
NEXT i%
FOR i%=1 TO ende%
b$(i%)=z$(i%)
NEXT i%
'
PRINT "RĂŒckspeichern der Objekte BAUM ";
x%=CRSCOL
y%=CRSLIN
count%=ende%
FOR t%=1 TO ende%
PRINT AT(x%,y%);t&(t%)
FOR k&=1 TO obj_count&(t%)
INC count%
b$(count%)=obj_line$(t%,k&)
NEXT k&
INC count%
b$(count%)="'"
NEXT t%
n%=count%
ELSE
PRINT "Fehler beim Laden der RSC-Datei"
~RSRC_FREE()
RESERVE
ENDIF
t=TIMER-t
PRINT "Laufzeit: ";t/200;" Sekunden"
PRINT "Weiter mit einer Taste"
~INP(2)
'
'
OPEN #1,"CON:"
CLS
PRINT
PRINT ,,"ObjektbÀume"
STORE #1,b$(),ende%
~INP(2)
CLOSE
FOR t%=1 TO ende%
CLS
FOR k&=1 TO obj_count&(t%)
PRINT obj_line$(t%,k&)
IF k& MOD 20=0
~INP(2)
ENDIF
NEXT k&
~INP(2)
NEXT t%
'
CLS
PRINT "Weiter mit einer Taste"
~INP(2)
ALERT 3,"Objekte zeigen ?",1," JA |NEIN",i|
IF i|=1
FOR i%=1 TO ende%
CLS
IF OB_TYPE(t%(i%),3)<>32
~FORM_CENTER(t%(i%),px&,py&,pw&,ph&)
ELSE
px&=0
py&=0
pw&=640
ph&=400
PRINT AT(40-0.5*LEN(b$(i%)),25);b$(i%);
ENDIF
~OBJC_DRAW(t%(i%),0,255,px&,py&,pw&,ph&)
IF px&<>O AND py&<>O
TEXT 8*(40-0.5*LEN(b$(i%))),18,b$(i%)
ENDIF
~INP(2)
NEXT i%
ENDIF
~RSRC_FREE()
RESERVE
'
ALERT 3,"Abgewandeltes |MERGE-File schreiben?",1," JA |NEIN",i|
IF i|=1
PRINT AT(22,2);"Abgewandeltes MERGE-File schreiben"
get_in_file(lst_file$)
IF lst_file$<>""
CLS
OPEN "o",#1,lst_file$
STORE #1,b$(),n%
CLOSE
ENDIF
ENDIF
'
ALERT 3,"Ausgabe auf DRUCKER ?",1," JA |NEIN",i|
IF i|=1
FOR t%=1 TO ende%
headline
FOR k&=1 TO obj_count&(t%)
LPRINT obj_line$(t%,k&)
IF k& MOD 50=0
OUT 0,12
headline
ENDIF
NEXT k&
OUT 0,12
NEXT t%
OUT 0,12
ENDIF
ENDIF
ENDIF
UNTIL abbruch!
'
END
'
'
'
> PROCEDURE init_spec
DATA BOX,TEXT,BOXTEXT,IMAGE,USERDEF,IBOX,BUTTON,BOXCHAR,STRING,EDIT,BOXEDIT,ICON,TITLE,*
DATA 20,21,22,23,24,25,26,27,28,29,30,31,32
FOR i|=1 TO 20
READ spec$(i|)
EXIT IF spec$(i|)="*"
NEXT i|
n|=i|-1
FOR i|=1 TO n|
READ sped(i|)
NEXT i|
RETURN
'
> PROCEDURE load_rsc(rsc$)
RESERVE -64000
IF EXIST(rsc$)
LET load!=RSRC_LOAD(rsc$)
ELSE
LET load!=FALSE
ENDIF
RETURN
'
> PROCEDURE headline
LPRINT
LPRINT
LPRINT
LPRINT SPC(40-0.5*LEN("BAUM "+STR$(t%)));"BAUM " ;STR$(t%)
LPRINT
LPRINT SPC(40-0.5*LEN(b$(t%)));b$(t%)
LPRINT
LPRINT
RETURN
'
> PROCEDURE get_in_file(VAR datei$)
LOCAL path$,file$
get_path_and_file(datei$,path$,file$)
FILESELECT path$,file$,datei$
RETURN
'
> PROCEDURE get_path_and_file(a$, VAR p$,f$)
LOCAL i%,f$,leer!,b$
IF LEN(a$)<>0
b$=TRIM$(a$)
i%=1
'
' Hier wird der String von hinten aufgerollt, bis ein '\' gefunden wird,
' alles, was davor ist, ist dann der Path, dahinter steht das File
' Wenn ein '\' vorhanden ist.
'
IF INSTR(b$,"\")<>0
i%=RINSTR(b$,"\")
f$=RIGHT$(f$,i%-1)
p$=LEFT$(b$,LEN(b$)-i%+1)
ELSE ! kein '\' vorhanden ...
IF MID$(b$,2,1)=":" ! ein vorhanden?
p$=LEFT$(b$,2) ! Drive abtrennen,
f$=RIGHT$(b$,LEN(b$)-2) ! Rest ist Filename
ELSE
f$=b$ ! Ansonsten reiner Dateiname
p$="\*.*" ! ohne Path
ENDIF
ENDIF
ELSE ! StringlÀnge=0, von Nichts kommt nichts...
f$=""
p$="\*.*â
ENDIF
IF INSTR(f$,"*") OR INSTR(f$,"?")
f$=""
path$=b$
ENDIF
RETURN
DEFFN get_string$(tree%,obj&)=CHAR{OB_SPEC(tree%,obj&)}
DEFFN get_text$(tree%,obj&)=CHAR{{OB_SPEC(tree%,obj&)}}