Three Flights Up ---------------- The new Programmer's Guide to Let 'em Fly! (includes version 1.20) April 1993 (c) 1991-93 by Oliver Scheel ... this guide (however) goes Freaky Deaky! Introduction ============ Tja, nun ist es soweit, der komplett berarbeitete Guide ist da. Er soll dazu dienen die programmiertechnischen M”glichkeiten in Zu- sammenhang mit Let 'em Fly! n„herzubringen. Um jedoch hochgesteckten Erwartungen entgegenzuwirken: Er kann das Gehirn des einzelnen nicht ersetzen, also nichts fr den Ex US-Pr„sidenten Ronny ("The President's brain's missin'!"). Nun denn, fr diesen Guide sind C-Kenntnisse (und nach M”glichkeit auch Assemblerkenntisse) erforderlich. Eine Untersttzung von GFA- Basic (oder Omikron-Basic) wird es von meiner Seite her nicht geben, da ich noch nie mit Basic auf dem ST gearbeitet habe (ich stelle mir es aber ziemlich kompliziert vor) und natrlich gewisse Abneigungen gegen Basic auf dem ST habe. Da eine echte strukturierte Pro- grammierung unter Basic nicht m”glich ist (da kann der Herr Ostrowski noch so viel `while's und `case's einbauen), drfte besonders der Zugriff auf die Struktur nicht ganz einfach sein. Auch wenn dieser Absatz etwas hart kommt, muž ich aber leider sagen, daž ich mich recht h„ufig ber GFA-Basic Programme aufregen muž. Dabei meine ich nicht unbedingt die der Freizeitprogrammierer, sondern eher die der `Professionellen'. Der Lieferumfang und die Kondome („h, Konditionen) -------------------------------------------------- Dieses Paket ist Public Domain, d.h. es darf frei kopiert und benutzt werden. Der Vertrieb ber einen PD-Versand ist nur mit schrift- licher(!) Genehmigung meinerseits m”glich. Zuwiderhandlungen werde ich strafrechtlich verfolgen. Zu `Three Flights Up' geh”ren folgende Dateien: - 3FLIGHTS.TXT Dieser Text - CHANGES.TXT Die komplette Changes-Liste von Let 'em Fly! - MULTITOS.TXT Bemerkungen zu Let 'em Fly! und MultiTOS (Wichtig!) - FUTURE.TXT Die Zukunft von Let 'em Fly! - LTMF_LIB.C Eine Library fr C - LTMF_LIB.H Dazu das Header-File - DO_SAMPL.C Ein form_do() Sample Das Paket darf nur komplett mit diesen Dateien weitergegeben werden! Es ist erlaubt die *.C Dateien fr die eigenenen Anforderungen zu ver„ndern. Es ist jedoch NICHT erlaubt diese ver„nderten Dateien weiterzugeben. Fr Fehlerkorrekturen habe ich natrlich immer ein offenes Ohr. First Flight (Internes) ======================= Na, wo h„ngen wir denn berall drin? ------------------------------------ Let 'em Fly! verbiegt den TRAP #2 (AES/VDI) und den TRAP #13 (BIOS) und benutzt dazu die XBRA-Kennung `LTMF'. Unter bestimmten Vor- raussetzungen verbiegt Let 'em Fly! den etv_critic Vektor. Ansonsten wird noch ein Cookie-Jar installiert (s.u.). Der Werdegang einer Dialogbox bei installiertem Let 'em Fly! ------------------------------------------------------------ Normalerweise wird in einem Programm eine Dialogbox nach dem folgen- den Schema abgearbeitet: [...] form_center(dialog, &x, &y, &w, &h); form_dial(FMD_START, 0, 0, 0, 0, x, y, w, h); objc_draw(dialog, ROOT, MAX_DEPTH, x, y, w, h); choice = form_do(dialog, 0); form_dial(FMD_FINISH, 0, 0, 0, 0, x, y, w, h); [...] Let 'em Fly! h„ngt in allen eben benutzten Funktionen drin und mischt mehr oder weniger kr„ftig mit. Da dies die grundlegenden Funktionen im Dialogbox-Handling sind, werden die Einflsse von Let 'em Fly! auf diese Funktionen jetzt im einzelnen beschrieben: form_center(dialog, ...) ------------------------ Hier wird der Dialog normalerweise zentriert. Bei eingeschaltetem `Save Position' werden nur die Tree-Koordinaten mit Korrektur zurckgegeben. Ist der `VSCR-Support' aktiv, so wird die Box von Let 'em Fly! im gerade sichtbaren Ausschnitt zentriert. form_dial(FMD_START, ...) ------------------------- šber diese Funktion sichert Let 'em Fly! den Dialogbox-Hintergrund. Der bergebene Bereich sollte daher m”glichst genau angegeben werden. Wird eine LTMF-Version ab 1.14 benutzt, so kann man auch einen gr”žeren Ausschnitt bergeben, Let 'em Fly! transformiert dann bei Bedarf die Koordinaten. `form_center()' liefert bei 'normalen' Dialog- boxen richtige Ergebnisse, Probleme gibt's z.B. bei SHADOWED Ones. Im Zweifelsfall lieber ein bižchen mehr angeben. Konnte der Hintergrund nicht gesichert werden, so wird die UR- Routine aufgerufen. objc_draw(dialog, ...) ---------------------- Let 'em Fly! setzt hier nur einige interne Flags. form_do(dialog, ...) -------------------- Hier greift Let 'em Fly! in die Vollen. Zwei AES-Funktionen, die in form_do() benutzt werden (und form_do() selbst natrlich auch), wur- den komplett neu programmiert und ins Betriebssystem eingebunden: `form_keybd()' und `objc_edit()'. Bei selbstgebauten form_do()- Routinen sollte man daher Gebrauch von diesen beiden Funktionen machen, insbesondere von objc_edit(), da hier u.a. der Clipboard- Support, die History und die Special Character Box integriert wurden. Auch sollte man nicht zuviele Tastenkombinationen vor dem Aufruf herausfiltern. Innerhalb von `form_do()' wird dann u.a. der Objektbaum nach Tastenkombination durchgescannt. Diese (rekursive) Funktion arbeitet wie folgt: Das entsprechende Objekt muž entweder SELECTABLE, EXIT oder TOUCHEXIT sein und darf nicht DISABLED oder geHIDETREEd sein. Ist der Parent geHIDETREEd, so werden die Children ebenfalls nicht durchsucht. Jetzt wird geprft, ob sich ein Text in dem Objekt befindet. Falls ja, dann wird dieser Text nach einer freien Tastenkombination abgesucht. Falls nicht, dann schaut Let 'em Fly! nach, ob das n„chste Objekt in der Liste(!) einen Text enth„lt und dieses Objekt nicht SELECTABLE, EXIT, TOUCHEXIT, DISABLED oder geHIDETREEd ist. Dieser Text wird dann zur Zuweisung der Tastenkombination benutzt. Die Y-Koordinate des Ersatzobjektes muž auf +/- 3 Pixel bereinstimmen. Daher ist darauf zu achten, daž die Dialogbox richtig sortiert ist. Der Text des `Abbruch'-Buttons sollte mit einem der oben schon aufgefhrten bereinstimmen. Zu beachten ist, daž es auch eine HELP-Taste geben kann. Weiterhin ist es ab Version 1.10 m”glich die Tasten gezielt zu vergeben (s.u.). Ebenso wurden in `form_do()' das `Fly Delay' (ab V1.17) und die direkte Cursor-Positionierung implementiert. Let 'em Fly! l”scht ab Version 1.17 vor dem Eintritt in den Event-Loop den Tastaturbuffer. Die Let 'em Fly! Funktion ist brigens sehr kompatibel zum Original, da sie auf den (inzwischen ”ffent- lichen) D.R. form_do() Sourcen basiert. form_dial(FMD_FINISH, ...) -------------------------- Das ist das Gegenstck zu FMD_START. Hier wird dann der Bildschirmaus- schnitt wieder korrekt hergestellt. Konnte der Hintergrund vorher nicht gesichert werden, so wird hier ein Redraw ausgel”st. Die Hauptapplikation wird somit aufgefordert den Bildschirmausschnitt wie- der herzustellen. Die FMD_STARTs und FINISHes sind gegen die untere (0) und obere (6) Grenze abgesichert. Natrlich sollte man darauf achten, daž es zu jedem FMD_START auch nur ein entsprechendes FMD_FINISH (und um- gekehrt) gibt, ansonsten kann man Let 'em Fly! durcheinander bringen. Werden zuviele FINISHes aufgerufen, so wird ein entsprechender Redraw erzeugt (s.a. Third Flight). Steuerung von Let 'em Fly! ber die Extended Objects ---------------------------------------------------- Ab Version 1.10 werden die erweiterten Objekttypen benutzt, um Let 'em Fly! innerhalb von Dialogen `steuern' zu k”nnen. Es k”nnen jetzt so bei einigen Dialogen Funktionen abgeschaltet werden und die Tasten gezielt vergeben werden. Der Extended Object Type im ROOT- Objekt muž ein Magic enthalten, damit Let 'em Fly! weiž, daž die restlichen Werte des Dialogs gltig sind. Damit sollen Kollisionen mit fremden Dialogroutinen vermieden werden. šber die Objekt-Flags 10 und 11 im ROOT-Objekt k”nnen die Key- Dials und der Extended Editor global (also fr diesen Dialog) abge- schaltet werden. Das Objekt-Flag 14 erzwingt ein Zentrieren des Dialogs (interessant bei eingeschaltetem `Save Position'). šber das Objekt-Flag 12 kann ein Dialog flugunf„hig gemacht werden. Das ist dann interessant, wenn ein Programm mit den fliegenden Dialogen nicht zurrechtkommt. Das Objekt-Flag 15 wird brigens von Let 'em Fly! benutzt, um einen bereits zentrierten Dialog zu markieren. Dies ist unabh„ngig vom Magic und kann nur durch den Schalter `Save Position' unterdrckt werden. Fr die restlichen Objekte im Dialog wird das Extended Object Byte dazu benutzt um Tasten gezielt zu vergeben. Es wird dabei zwischen normalen Tasten (A-Z, 0-9) und Sondertasten (HELP, UNDO, F1- F10) unterschieden. Weiterhin kann man bestimmen, ob das n„chste Objekt fr die Tastenvergabe benutzt werden soll. Die Objekt-Flags 10 und 11 haben die gleiche Bedeutung wie im ROOT-Objekt, sind jedoch nur lokal wirksam. So, und hier die genaue Belegung der Bits and Bytes (die Flags werden von 0, entspricht Bit 0, ab an gez„hlt!): ROOT-Objekt ----------- - Extended Object Byte (erweiterter Objekttyp) MAGIC 0x89 (137) Sagt Let 'em Fly!, daž die restlichen Werte im Dialog gltig sind. GLOBOFF 0x71 (113) Hiermit wird Let 'em Fly! fr diesen Dialog komplett(!) ausgeschaltet. Das Byte stimmt mit dem in FormDoIt! benutzten berein. - Objekt-Flags Flag 11 Schaltet die Key Dials global aus. Flag 12 Macht den Dialog flug_un_f„hig. Flag 13 Rastet den Dialog nach dem Fliegen wieder auf das ursprngliche Byte-Alignment ein. Flag 14 Erzwingt ein Zentrieren des Dialogs (entspricht `Save Position' OFF). restliche Objekte ----------------- - Extended Object Byte (erweiterter Objekttyp) Das Byte wird in zwei Nibbles (  4 Bit) unterteilt. Das obere Nibble konfiguriert das untere Nibble. Eine kleine Grafik drfte hier hilfreich sein: +---+---+---+---+----------------+ | E | F | S | T | Key Identifier | +---+---+---+---+----------------+ ^ ^ ^ ^ ^ | | | | +---- Identifiziert die Taste. Ist dieses | | | | Nibble nicht gesetzt, also gleich Null, | | | | so vergibt Let 'em Fly! die Taste nach | | | | dem herk”mmlichen Verfahren. Besitzt | | | | dieses Nibble einen Wert (1-15), so wird | | | | damit die Position(!) der Taste im Text | | | | angegeben. Vorsicht: Der Z„hler beginnt | | | | mit 1 (also nicht mit 0) und fhrende | | | | Spaces werden mitgez„hlt! | | | | | | | +-------- Zeigt an, daž das n„chste Objekt zur | | | Tastenvergabe benutzt werden soll. Es | | | muž kein Key Identifier verhanden sein. | | | In diesem Fall sucht sich Let 'em Fly! | | | die Taste selbst aus. | | | | | +------------ Dieses Bit sagt, daž dieses Objekt mit | | einer Sondertaste belegt werden soll. | | Der Key Identifier muž dann einen | | gltigen Wert haben: | | 1 - UNDO | | 2 - HELP | | 3 - F1 | | [...] | | 12 - F10 | | Weiterhin wird das Objekt noch nach dem | | Let 'em Fly! Algorithmus mit einer Taste | | belegt. Man kann es aber ber das | | ObFlag 12 unterdrcken. | | | +---------------- šber dieses Bit wird das Flugobjekt | festgelegt. Eine Kombination mit den an- | deren beiden Bits ist nicht sinnvoll. | Das untere Nibble (Key Identifier) sagt | dann aus, ob das Flugobjekt Ex- | clusivrechte besitzt (d.h. es kann nur | ber dieses Objekt `geflogen' werden) | oder nicht. Dabei gilt: | 0 - Exclusiv | 1 - Inclusiv (d.h. Background und | Flugobjekt). | 2 - sinnlos | 3 - Inclusiv, jedoch wird das | Objekt unter keinen Umst„nden | von Let 'em Fly! gel”scht. | +-------------------- Zeigt an, daž bei diesem Objekt eine sog. EXAPPLBLK-Struktur benutzt wurde. Die Struktur wird weiter unten be- schrieben. Zu beachten ist, daž auch weiterhin die automatische Tastenvergabe aktiv ist. Wird UNDO ber die ExObTypes vergeben, so ist es gegen eine weitere automatische Vergabe geschtzt. Bei HELP ist dies nicht der Fall! Special ab V1.17: Ab dieser Version wird auch das FormDoIt! Byte (0x71 / 113) zur Unterdrckung der Tastenvergabe fr das jeweilige Objekt untersttzt. Da dieser Wert eh sinnlos ist, gibt es daher auch keine Kollisionen. - Objekt-Flags Flag 11 Schaltet die Key Dials fr dieses Objekt (und dessen Unterobjekte!) aus. Flag 12 Wird eine Taste mit einer Sondertaste (z.B. UNDO) belegt, so wurde trotzdem noch eine `normale' Tastenkmbination dafr herausgesucht. Durch setzen dieses Flags kann man es (erfolgreich) verhindern. Vorsicht: Fr Kollisionen bei der Tastenvergabe ist der Pro- grammierer, bzw. der Ver„nderer des RSC-Files selbst ver- antwortlich! Natrlich kann man auch `fremde' RSC-Files modifizieren, jedoch sollte man hier sehr vorsichtig sein. Vielleicht werden die Bits ja auch vom Programm selbst benutzt und ver„ndert. Weiterhin ist es selbstverst„ndlich, daž ver„nderte RSC-Files grunds„tzlich NICHT weitergegeben werden drfen!!! Falls ich solchen F„llen auf die Spur kommen sollte, so bekommt derjenige er- heblichen(!) Žrger von mir! Abh„ngigkeiten zwischen Schalter, ob_flags und Funktionen --------------------------------------------------------- Function | Switch | ob_flags (only with MAGIC) ---------------+-------------------+--------------------------- form_do() | Let 'em Fly ON/OFF| ExObType Value 0x71 (113) | Key Dials | Flag 11 / ExObType 0x71 form_dial() | Flying ON/OFF | Flag 12 (ROOT-only) | Grow/Shrink | --- | Send Redraw | --- form_center() | Save Position | Flag 14 | VSCR Support | no flag available yet form_alert() | Alert/Error-Boxes | --- form_error() | Alert/Error-Boxes | --- form_keybd() | Extended Editor | --- objc_edit() | Extended Editor | --- appl_exit() | - no switch - | --- ---------------+-------------------+--------------------------- di_fly() | Flying ON/OFF | Flag 12 (ROOT-only) | Solid/Hollow Fl. | --- Die EXAPPLBLK-Struktur ---------------------- Um Benutzerdefinierte Objekte ins Resource einzubinden, muž man eine spezielle Struktur benutzen (USERBLK), die weitere Informationen fr das AES enth„lt. Die EXAPPLBLK-Struktur ist eine erweiterte USERBLK- Struktur und sieht wie folgt aus: typedef struct { int cdecl (*ub_code)(struct __parmblk *parmblock); union obspecptr *ub_spec; /* old ob_spec */ int ub_type; /* old ob_type */ } EXAPPLBLK; `ub_code' ist der Zeiger auf die Funktion zum Malen des Objekts, `ub_spec' ist ein Zeiger auf den alten ObSpec und `ub_type' der alte Objekt-Typ (der neue muž ja G_USERDEF sein). Fr weitere Informationen zu benutzerdefinierten Objekten verweise ich an dieser Stelle auf das neue Profibuch. šber diese Struktur kann Let 'em Fly! nun auch bei entsprechenden be- nutzerdefinierten Objekten Tasten vergeben. Ich nutze jetzt die M”glichkeit um hier auf eine Library von Markus Nick aufmerksam machen. Sie heižt `Ruby' und erm”glicht es Flugecken, runde Radio-Buttons und Check-Boxen in ein Resource einzubinden. Die Flugf„higkeit und die Tastenvergabe bernimmt Let 'em Fly!. Somit ist nur der Let 'em Fly!-unabh„ngige Teil im eigentlichen Programm ent- halten, was sich natrlich auf die Gr”že positiv auswirkt. Weiterhin ist das Format in den Grundelementen kompatibel zu denen der Fly/My/MagicDials, d.h. sp„tere Library-Wechsel sind relativ einfach zu bewerkstelligen. `Ruby' sollte inzwischen in jeder gut sortierten Mailbox zu finden sein. Ebenso kann diese Library auch ber einen adressierten und frankierten Rckumschlag bei mir oder beim Markus bezogen werden. Second Flight (The Cookie) ========================== Let 'em Fly! installiert einen Cookie mit der Kennung `LTMF', welcher auf die folgende Struktur zeigt: typedef struct { unsigned int version; /* Version im BCD-Format*/ struct { unsigned light : 1; /* light version (read) */ unsigned niceln : 1; /* niceline */ unsigned jumpin : 1; /* jumpin' dials */ unsigned flyswi : 1; /* conf. flymode switch */ unsigned vscr : 1; /* virtual scr. support */ unsigned center : 1; /* center mode */ unsigned keys : 1; /* key handling */ unsigned edit : 1; /* extended editor */ unsigned redraw : 1; /* send redraw message */ unsigned flytyp : 1; /* solid/hollow fly */ unsigned fly : 1; /* flying on/off */ unsigned alert : 1; /* Alerts/Errors on/off */ unsigned mouse : 1; /* dials to mouse */ unsigned f_grow : 1; /* grow/shrink boxes */ unsigned g_grow : 1; unsigned bypass : 1; /* ON/OFF highest prio */ } config; int conf2; /* reserved */ int reserved; /* reserved */ void cdecl (*di_fly)(OBJECT *tree); void cdecl (*obj_clsize)(OBJECT *tree, int obj, int *x, int *y, int *w, int *h); int cdecl (*do_key)(int key, int kshift); int cdecl (*init_keys)(OBJECT *tree); int cdecl (*lookup_key)(int key, int kshift); int cdecl (*di_moveto)(OBJECT *tree, int mx, int my); int cdecl (*di_center)(OBJECT *tree); int ucol; /* underscore color */ int aicol; /* alert icon color */ int aframe; /* alert frame size */ int flydelay; /* delay before flying (form_do()-only) */ int cdecl (*hist_insert)(char *string); char cdecl (*ins_spcchar)(void); void cdecl (*init_niceline)(OBJECT *tree); } LTMFLY; Die Variablen und Funktionen werden jetzt ab hier genauer be- schrieben. Dabei steht die Zahl in der Klammer fr den Zeitpunkts (Version) des Einzugs in Let 'em Fly!. Will man auf entsprechende Teile zugreifen, so muž man vorher die Version prfen, ansonsten kann es zu šberraschungseffekten kommen. Ausnahme: Die Version ist kleiner oder gleich 1.02. Das ist n„mlich die erste offizielle Release. 1.) Die Variablen (bzw. Konstanten) ----------------------------------- version ------- Hier ist die Version von Let 'em Fly! im BCD-Format (0x0114 ent- spricht 1.14) zu finden. light (1.00) ------------ Zeigt an welche Version geladen wurde (light oder normal). Dieses Flag darf nicht ver„ndert werden! niceln (1.18) ------------- Konfiguriert das in Let 'em Fly! integrierte Niceline. jumpin (1.15) ------------- Schaltet die Jumpin' Dials ein. flyswi (1.13) ------------- Ist dieses Flag gesetzt, so wird die rechte Maustaste fr den Flugmodus (Ghost-Flights) umgeschaltet bzw. invertiert. vscr (1.10) ----------- Zeigt an, ob der VSCR-Cookie ausgewertet und benutzt werden soll. center (1.03) ------------- Bestimmt den Center-Mode. Dabei gilt 1 fr nicht centern und 0 fr centern. keys (1.00) ----------- Schaltet die Key Dials ein. edit (1.00) ----------- šber dieses Flag wird der Extended Editor eingeschaltet. redraw (1.02) ------------- Zeigt an, ob nach dem L”schen der Dialogbox ein Redraw gesendet werden soll. flytyp (1.00) ------------- Bestimmt den Flugmodus (0: Solid, 1: Hollow). fly (1.00) ---------- Schaltet die fliegenden Dialoge aus. alert (1.00) ------------ Konfiguriert die neuen Alert-Boxen. mouse ----- Zentriert die Dialoge an der Mausposition. f_grow (1.00) ------------- Ist dieses Flag gel”scht, so werden die FMD_GROW/SHRINK-Aufrufe igno- riert. g_grow (1.00) ------------- Genauso wie `f_grow', jedoch gilt die ganze Geschichte fr die graf_grow/shrinkbox()-Aufrufe. bypass (1.00) ------------- Hier ist das Master-Flag. Ist es gesetzt, so wird Let 'em Fly! deaktiviert. ucol (1.13) ----------- Bestimmt die Farbe und die Form der Underscores. Ist Bit 0 vom oberen Byte gesetzt, so werden anstelle der Underscores die Buchstaben eingef„rbt (natrlich ohne dabei zu tropfen). aicol (1.13) ------------ Repr„sentiert die Farbe der Alert-Icons. aframe (1.13) ------------- Bistimmt die Rahmendicke der Alert-Boxen. flydelay (1.15) --------------- Gibt die Zeit (ohne Einheit im Bereich von 0-10) zwischen dem Mausklick und dem Flug an. 2.) Die Funktionen ------------------ Let 'em Fly! stellt auch einige Funktionen zur Verfgung, welche besonders fr eigene form_do()-Routinen ntzlich sein k”nnten. Um die Funktionen zu benutzen sollte man das Bindings `LTMF_LIB' verwenden, da hier u.a. auch die unterschiedlichen Versionen bercksichtigt werden. Die jetzt folgende Beschreibung bezieht sich auf das Binding. Weiterhin verweise ich auch auf das form_do()-Beispiel, welches einige Let 'em Fly! Funktionen benutzt. int di_fly(OBJECT *tree) (1.00) ------------------------------- šber diese Funktion kann man Dialoge fliegen lassen. Der Bildschirm- ausschnitt muž vorher mit FMD_START korrekt gesichert worden sein. Die genaue Verwendung ist aus dem form_do()-Sample zu entnehmen. int di_moveto(OBJECT *tree, int x, int y) (1.15) ------------------------------------------------ Diese Funktion wird von den Jumpin' Dials benutzt. Sie l„žt den Dialog (maus)zentriert an die angugebende Position springen. šber diese Funktion kann man jetzt auch testen ob ein Dialog flugf„hig ist bzw. ob der Hintergrund gesichert werden konnte. Dazu wurden in LTMF_LIB.H zwei Macros definiert. int di_center(OBJECT *tree) (1.17) ---------------------------------- Hiermit kann ein Dialog re-centered werden. int obj_clsize(OBJECT *tree, int obj, int *x, *y, *w, *h) (1.10) ---------------------------------------------------------------- Diese Funktion berechnet die wahren Ausmaže eines Objekts. Es wird auch der SHADOWED-Status korrekt behandelt. Eigentlich sollte sie fester Bestandteil des AES sein. int init_keys(OBJECT *tree) (1.13) ---------------------------------- Benutzt man eine eigene form_do()-Routine, will aber trotzdem nicht auf die Tastaturbedienbarkeit verzichten, so kann man mit dieser Funktion die Tastenvergabe von Let 'em Fly! aufrufen. Dabei werden dann auch die Strichlein gemalt, d.h. sie darf erst aufgerufen werden, wenn sich der Dialog auf dem Bildschirm befindet. int lookup_key(int key, int kbshift) (1.13) ------------------------------------------- Hat man vorher init_keys() aufgerufen und einen Wert != 0 zu- rckbekommen, dann kann man die eingehenden Keyboard-Events von die- ser Funktion checken lassen, um zu gucken, ob ein Objekt ber einen Shortcut angew„hlt wurde. Diese Funktion muž VOR form_keybd() und objc_edit() aufgerufen werden! int set_do_key(void (*key_handler)()) (1.12) -------------------------------------------- Oft ist es so, daž man eigene Tasten mit einbinden m”chte, aber denoch nicht auf den Let 'em Fly! Support verzichten zu wollen. Let 'em Fly! erlaubt es daher einen benutzerdefinierten Key-Handler zu installieren (do_key() im Cookie). Hier erstmal ein kleines Bei- spiel: [...] #include [...] int cdecl my_keys(int key, int kshift) { printf("%04x %04x\n\r", key, kshift); return(0); } [...] int do_dialog(OBJECT *tree) { int what; draw_dialog(tree); set_do_key(my_keys); /* Routine einklinken */ what = form_do(tree, 0); set_do_key(0l); /* und wieder ausklinken. */ undraw_dialog(tree); return(what); } [...] Dieses kleine Beispielprogramm macht nichts anderes, als einen Dialog darzustellen und abzuarbeiten, jedoch werden die Tastendrcke inner- halb von form_do() mit printf() auf dem Bildschirm ausgegeben. Die Funktion zur Tastenbearbeitung muž folgenden Regeln folgen: int cdecl do_key(int key, int kshift); Eingabe: key Enth„lt den Tastencode. Er stimmt mit dem von evnt_keybd() zurckgegebenen berein, d.h. Bits 0..7 enthalten den ASCII-Code und Bits 8..15 den Scancode. kshift Enth„lt den Shiftstatus, der von evnt_button() geliefert wurde. Return: 0 Taste konnte nicht verarbeitet werden, bzw. Let 'em Fly! sieht den Tastencode als gltig an und versucht ihn selbst zu verarbeiten. 1 Taste konnte verarbeitet werden. Let 'em Fly! ignoriert die Taste nun. 2 Wie `1', jedoch wird der Dialog zus„tzlich abgebrochen und als Ergebnis (bei form_do()) `0' zurckgeliefert. Wird innerhalb dieser Routinen ein Dialog dargestellt, so wird dieser nicht von Let 'em Fly! untersttzt, da der TRAP-Handler von Let 'em Fly! nicht reentrant ist. Weiterhin muž der Programmierer dafr Sorge tragen, daž der Funktions- Pointer nach Beendigung des Dialogs auf `0L' zurckgesetzt wird. Es k”nnten sonst berraschende Effekte (z.B. Bomben) auftreten. Aus- nahme: Man will nur mal kurz eine Alert-Box darstellen. In diesem Fall wird die neue Tastenroutine von Let 'em Fly! nicht aufgerufen. int ins_spcchar(void) (1.15) ---------------------------- Let 'em Fly! besitzt ab Version 1.15 eine Box, in der man die `blen' Zeichen eingeben kann. Diese Box kann man ber diese Funktion nicht nur innerhalb, sondern auch aužerhalb von Dialogen benutzen. int hist_insert(char *string) (1.16) ------------------------------------ Manchmal ist es sinnvoll Strings manuell in die Let 'em Fly!-History einzufgen. Diese Funktion macht den Weg frei ... int init_niceline(OBJECT *tree) (1.18) -------------------------------------- Mit dieser Funktion kann man `zu Fuž' die Niceline fr einen Menbaum installieren. Bei diesem Menbaum kann es sich auch um ein Popup-Men handeln. Beim Aufruf dieser Funktion werden alle G_STRINGs, die DISABLED sind und `---' enthalten durch die Nicelines ersetzt. int init_flyobj(OBJECT *tree) ----------------------------- Let 'em Fly! untersttzt ab Version 1.17 explizit sog. Flugobjekte. Diese Objekte werden mit bestimmten Eigenschaften versehen (s.a. ExObTypes). Kann ein Dialog nicht fliegen (z.B. Speicherplatzmangel), so wird dieses Objekt gel”scht. Da sich die Flugecke von Julians FlyDials irgendwie eingebrgert hat, kann man ber diese (externe!) Funktion eine eben solche installieren. Das zu verwandelnde Objekt muž natrlich die richtige Kennung und vernnftige Ausmaže besitzen. Am besten ist es, wenn man eine G_BOX mit OUTLINED-Status benutzt. Diese Funktion wird z.B. von Selectric¿, Take-Off 2 und der Fuzzy- Clock ab Version 1.06 benutzt. Bemerkung: Es wird hier natrlich ein USERDEF installiert. Um auch mit Accessories und TSRs (Terminate & Stay Resident) ohne Probleme zu funktionieren, wird die Workstation vom AES benutzt. Die Attribute, die ver„ndert werden, werden natrlich gesichert. Third Flight (Tips & Tricks & Guidelines) ========================================= Das mit dem Redraw einzelner Objekte ... ---------------------------------------- ... machen viele noch falsch. Wird ein Dialog durch Let 'em Fly! flugf„hig, so kann sich ja die Position der Box und somit auch der einzelnen Objekte „ndern. Da objc_draw() und objc_change() jedoch Clipping-Koordinaten ben”tigen, mssen diese vor *JEDEM* Aufruf neu berechnet werden. Viele benutzen nur die, die am Anfang von form_center() zurckgeliefert wurden, was natrlich zu Problemen in der Bidlschirmdarstellung fhrt. Das TOS bercksichtigt es ja auch, sonst wrde Let 'em Fly! berhaupt nicht funktionieren. Um diesen Mižstand zu beheben, folgen nun entsprechende Funktionen, die a) komfortabel und b) Let 'em Fly!-fest sind. Sie sollten sich selbst erkl„ren ... ----- cut here ------------------------------------------------------ /* ---------------------------------------------------------------- */ /* Berechne die _absoluten_ Koordinaten eines Objekts */ /* ---------------------------------------------------------------- */ void obj_xywh(OBJECT *tree, int obj, GRECT *p) { objc_offset(tree, obj, &p->g_x, &p->g_y); p->g_w = tree[obj].ob_width; p->g_h = tree[obj].ob_height; } /* ---------------------------------------------------------------- */ /* Redraw eines einzelnen Objekts unter Bercksichtigung der */ /* _aktuellen_ Position. */ /* ---------------------------------------------------------------- */ void obj_update(OBJECT *tree, int obj) { GRECT p; obj_xywh(tree, obj, &p); objc_draw(tree, obj, MAX_DEPTH, p.g_x, p.g_y, p.g_w, p.g_h); } /* ---------------------------------------------------------------- */ /* Objekt-Status eines Objekts ver„ndern. Dabei gilt ~STATUS fr */ /* Status l”schen. */ /* ---------------------------------------------------------------- */ void obj_stchange(OBJECT *tree, int obj, int state, int update) { if(state < 0) tree[obj].ob_state &= state; else tree[obj].ob_state |= state; if(update) obj_update(tree, obj); } /* ---------------------------------------------------------------- */ /* Objekt-Flags eines Objekts ver„ndern. Dabei gilt ~FLAG fr */ /* Flag l”schen. */ /* ---------------------------------------------------------------- */ void obj_flchange(OBJECT *tree, int obj, int flag, int update) { if(flag < 0) tree[obj].ob_flags &= flag; else tree[obj].ob_flags |= flag; if(update) obj_update(tree, obj); } ----- cut here again ------------------------------------------------ Bei den beiden letzten Funktionen ist zu beachten, daž diese nur Flags/Stati bis zur Nummer 14 korrekt behandeln, da sonst ein Vorzeichenfehler auftritt. Fr den normalen Hausgebrauch reichen sie aber v”llig aus. Nochwas: Wenn man mit VDI-Funktionen in die Box malt (z.B. Edison- Utilities), dann muž man ebenfalls vorher ein obj_xywh() bzw. objc_offset() aufrufen, um den Offset und das Clipping-Rectangle zu erhalten! Senden von Redraws ------------------ In manchen Situationen muž man sich selbst (also der Applikation) einen Redraw senden, um z.B. einen Desktop-Redraw auszul”sen. Hierzu gibt es zwei Verfahren: 1.) Das Senden einer Message ber appl_write() und 2.) ein form_dial(FMD_FINISH, ...) mit den entsprechenden Koordinaten (dabei vorher *KEIN* form_dial(FMD_START, ...) machen, da es a) nicht notwendig und v”llig berflssig ist und b) Let 'em Fly! Versionen vor 1.18 in diesem Fall keinen Redraw senden). Beide M”glichkeiten sind von Atari offiziell dokumentiert. Redrawunterdrckung beim L”schen von Info-`Dialogen' ---------------------------------------------------- Will man nur mal eine Dialogbox auf den Bildschirm zaubern, um eine kleine Info anzuzeigen (z.B. `Sortiere ...'), ohne daž eine Eingabe vom Benutzer erwartet wird, so wird von Let 'em Fly! immer ein Redraw beim L”schen der Box gesendet, da einige Programme das brauchen. Da hilft auch das Abschalten von `Send Redraw' alleine nichts. Dies ist dann hinderlich, wenn man Let 'em Fly! das Buffern des Hintergrundes berlassen will. Man kann es aber unterdrcken, indem man (zus„tzlich zum vorrbergehenden Abschalten von `Send Redraw'!) vor dem FMD_FINISH ein Dummy-objc_find() macht. Der Aufruf sieht wie folgt aus: objc_find(tree, ROOT, MAX_DEPTH, 0, 0); Tastenvergabe in nicht-modalen Dialogen (die in den Fenstern) ------------------------------------------------------------- Vergibt man bei diesen Dialogen die Tasten ber init_keys(), so ist darauf zu achten, daž sich der Dialog im obersten Fenster befindet. Ansonsten sollte man auf einen Aufruf bei einem Redraw verzichten, da es in diesem Fall zu Bildschirmmll kommt. Das Sortieren der Objekte ------------------------- Damit sinnvolle Ergebnisse bei der Verwendung von Ersatzobjekten bei der Tastenvergabe entstehen, mssen die Objekte auch richtig sortiert sein. Am besten ist es, wenn man den ganzen Dialog von links nach rechts und von oben nach unten sortiert. Umlaute als Shortcuts --------------------- Damit Let 'em Fly! international bleibt, ohne enormen Aufwand dafr zu treiben, kann man *keine* Umlaute und Sonderzeichen als Shortcuts mižbrauchen. Sch”nere Buttons ---------------- Da Let 'em Fly! unter die Buchstaben seine Striche malt, stožen diese in der Regel am Boxrand an, was natrlich nicht unbedingt optimal aussieht. Daher empfehle ich die Boxen, welche nur ein Zeichen hoch sind, um 2 Pixel in Y-Richtung zu vergr”žern (siehe FuzzyClock, Selectric¿, Take-Off 2, LET_CONF). Der Aufbau der RSCs fr die Icons der Alertboxen ------------------------------------------------ Let 'em Fly! erwartet in der Datei LET_ICON.RSC seine Icons welche sinnvollerweise in einer G_BOX abgelegt sein sollten. Die Icons mssen von links nach rechts sortiert sein, da sonst die Zuweisungen nicht stimmen. Die Gr”že der Icons betr„gt 32x32 Pixel. Zum Editieren wird ein Resource-Construction-Set und u.U. ein Icon-Editor ben”tigt. Ab Version 1.17 k”nnen eine variable Anzahl von Icons ersetzt werden, jedoch nicht individuell, sondern nur zusammenh„ngend be- ginnend mit dem ersten Icon. Die ersten drei Icons sind fr die Alertboxen gedacht (siehe auch mitgelieferte Icons). Die restlichen drei Icons sind fr die Event-Critic Boxen. Dabei repr„sentiert das erste einen allgemeinen Diskettenfehler, das zweite eine schreibgeschtzte Diskette und das dritte eine zu wechselnde Diskette. Nachschlag ========== Hmm, ich weiž garnicht was ich hier schreiben soll. Na auf jeden Fall bedanke ich mich mal an dieser Stelle fr die vielen Hinweise und Problemanfragen einiger Programmierer, die somit `Three Flights Up' zu dieser Form verholfen haben (und natrlich auch bei denen, die dazu beigetragen haben, daž die Programmierschnittstelle in- zwischen diesen Umfang erreicht hat). Falls noch irgendwelche Ver- besserungsvorschl„ge etc. da sind, hier ... meine Adresse ... Oliver Scheel Rothehausstr. 28 W-5000 K”ln 30 (ab 1.7. 50823 K”ln) MausNet: Oliver Scheel @ K2 InterNet: Oliver_Scheel@k2.maus.de WICHTIG: Meine Adresse kann sich zum September '93 hin „ndern! N„heres ist dann der Zeitschrift ST-Magazin zu entnehmen. Let 'em Fly! Man fliegt nicht mehr ohne ... ---- R„chzschreipf„ler (c) 1991-92 by Oliver Scheel