Das kleine Buch zu PDIAL 'Make my dial a P-dial!' A. Einleitung "Heute pflastern eine Vielfalt mehr oder weniger gelungener Alternativdialoge die Landschaft. Begonnen beim Klassiker 'Flydials' ber 'Keydials', 'X-GEM', 'My-Dials' zu den 'Spoil-Dials', kein Name erscheint zu platt, als daž man ihn nicht seinen Dialogroutinen verleihen k”nnte." (Laurenz Prssner, "Verdeckte Ermittlungen", ST-Magazin 6/92, 90) Sch”n und gut. Ursprnglich wollten wir ja auch nur die FLYDeal-Lib (aus der TOS 1/93) in Pure Pascal einbinden. Das Linken von C-Objektdateien zu PP-Programmen ist aber eine Sache fr sich, wenn die in C geschriebenen Routinen auf die C-Standardbibliotheken zugreifen. Also sagten wir uns: "Schaun mer mal." Daraus ist dann schliežlich ein Paket geworden, das fliegende Dialoge mit Tastaturbedienung bereitstellt. Leider bietet PP nicht die M”glichkeit, Objektdateien zu Bibliotheken zusammenzufassen, so daž PDIAL aus mehreren Units besteht. B. Features (oder watt et kann) - fliegende Dialoge (solide oder transparent) - springende Dialoge (Jumpin' Dials wie bei Let 'em fly) - tastaturbedienbare Buttons - erweiterte Alertboxfunktionen mit den genannten Features, l„ngerem Text und der M”glichkeit, neue Icons einzubinden - erweiterte objc_edit-Funktion mit neuen Tastaturshortcuts, mauspositionierbarem Cursor, Sonderzeicheneingabe, Clipboard-Untersttzung, ... - erweiterte Objekttypen (MAC-Radiobuttons, ...), Codierung kompabeatel zu Flydials, Flydeals, My-Dials, Ruby, MagicDials und wie sie alle heižen. - Popupmens - verschachtelbare Dialogboxen ("Subdialoge") - optionale Benutzung von Let 'em Fly-Funktionen - putzt 10 Pfund junges Gemse (ohne Vitaminverlust!) und archiviert Ihre Videokassetten automatisch. C. Software-Voraussetzungen Zur Verwendung von PDIAL sind Pure Pascal ab Version 1.1 sowie ein Resource-Editor, mit dem erweiterte Objekttypen eingegeben werden k”nnen (z.B. Interface, ORCS), erforderlich. Den Benutzern des DR RCS 2.0 wnschen wir dabei viel Spaž. D. šberblick ber die Units von PDIAL Welche File dient nun wozu? - NEWOBS.PPU stellt die benutzerdefinierten Objekttypen (MAC-Radiobuttons, Checkboxen usf.) bereit und konvertiert dazu die Objektb„ume. - PFORM.PPU enth„lt unsere Variante der AES-Form-Bibliothek. - ALERT.PPU bietet die erweiterte Alarmbox-Funktion. - MEMORY.PPU beinhaltet die Speicherverwaltung von PDIAL. - TOOLS.PPU enth„lt einige ntzliche Funkti”nchen. Wir empfehlen, die fnf Dateien in den UNIT-Ordner zu kopieren. Wer mit PDIAL programmiert, muž aber in die USES-Anweisung nur NEWOBS, PFORM und gegebenenfalls ALERT aufnehmen, nicht notwendigerweise aber auch MEMORY und TOOLS. E. Rechtliches Die schlechte Nachricht zuerst: Wir bernehmen keinerlei Haftung fr direkte oder indirekte Sch„den, die aus dem Gebrauch unserer Routinen entstehen. Die Verwendung von PDIAL geschieht auf eigene Gefahr. In dieser Anleitung wird auf Warenzeichen Bezug genommen, die nicht explizit als solche ausgewiesen sind. Und nun die gute Nachricht: PDIAL ist Freeware. Das Paket darf frei kopiert und benutzt werden. Bei Verwendung von PDIAL im Programm oder in der Dokumentation muž allerdings auf PDIAL hingewiesen werden. Auch drfen die in der Datei FILES.LST aufgez„hlten Dateien nur zusammen weitergegeben werden. So, das mužte einfach mal gesagt werden F. Apell PDIAL wurde zwar sorgf„ltig getestet, drfte aber dennoch Bugs enthalten. Deshalb folgender Apell: Wenn PDIAL etwa im Flimmermodus der neuen Graphikkarte den Bildschirm-GAU verursacht, dann schiebt es nicht gleich in den Papierkorb, sondern schickt uns eine Beschreibung des Fehlers (dazu sp„ter mehr). Darin sehen wir, da PDIAL ja Freeware ist, gewissermažen moralisch die Gegenleistung fr die Benutzung von PDIAL. G. Benutzung von PDIAL im šberblick I. Das RSC-File muž fr den Einsatz von PDIAL vorbereitet werden. PDIAL wertet n„mlich die sogenannten "erweiterten Objekttypen" aus. Dabei werden die blichen Codes benutzt. Diese kann man in neueren RCS-Editoren direkt eingeben. II. Dann mssen die Units (ALERT,) PFORM und NEWOBS per USES-Anweisung eingebunden werden. III. Im Hauptprogramm mssen die Units PFORM und NEWOBS nach Aufruf von appl_init und erfolgreichem ™ffnen einer VDI_Workstation mit den Funktionen init_pform und init_newobs initialisiert werden. Init_pform legt gegebenfalls (d. h. sofern nicht die Routinen des Utilitys Let 'em fly benutzt werden) einen internen Puffer fr die Bildschirmrestaurierung an. IV. Nach rsrc_load k”nnen alle Objektb„ume der Resourcedatei mit der Funktion fix_all angepažt werden. Dabei wird intern Speicher fr die erweiterten Objekttypen alloziert. Dies kann auch fr jeden Baum einzeln mit fix_tree erledigt werden. V. Programmierung mit den PDIAL-Funktionen. VI. Am Programmende nicht den Aufruf von exit_pform und fix_all bzw. fix_tree vergessen, damit der allozierte Speicher wieder freigegeben wird. H. Die Anpassung der Objektb„ume Damit die von der Unit NEWOBS bereitgestellten erweiterten Objettypen benutzt werden k”nnen, muž der Objektbaum per fix_all oder per fix_tree angepažt werden. Diese Routinen reagieren auf Objekte, die gem„ž der sogleich folgenden Liste markiert worden sind. I. Verschiebeobjekt (Flugobjekt) 1. erweiterter Typ: 17 2. gesetzte Flags: TOUCHEXIT 3. Anmerkung: Wird mit gedrckter linker Maustaste in dieses Objekt hineingefahren, so wird der Dialog verschoben. Ist zus„tzlich die rechte Maustaste, eine Shifttaste, Alternate oder Control gedrckt, so wird der Dialog dabei durchgeblendet. II. Flugecke (Eselsohr) 1. normaler Typ: IBOX 2. erweiterter Typ: 17 3. gesetzte Flags: TOUCHEXIT, OUTLINED, CROSSED 4. Anmerkung: Es handelt sich hier blož um einen Spezialfall eines Verschiebeobjektes. III. Radiobutton 1. normaler Typ: BUTTON, STRING 2. erweiterter Typ: 18 3. gesetzte Flags: RBUTTON IV. Checkbox 1. normaler Typ: BUTTON 2. erweiterter Typ: 18 3. ungesetzte Flags: RBUTTON, EXIT V. Exitbutton 1. normaler Typ: BUTTON 2. erweiterter Typ: 18 3. gesetzte Flags: EXIT 4. ungesetzte Flags: RBUTTON 5. Anmerkung: Wenn zus„tzlich noch Bit 11 in ob_flags oder ob_state gesetzt ist, ist der Button auch mit der Taste UNDO selektierbar. Von der Verwendung von ob_flags Bit 11 raten wir allerdings ab, da dieses Bit von den FALCON-AES wohl anderweitig verwendet wird. VI. Per Tastatur selektierbarer String ("tastaturbedienbarer String") 1. normaler Typ: STRING 2. erweiterter Typ: 18 3. ungesetzte Flags: RBUTTON 4. Anmerkung: Solche Strings k”nnen links neben Popup-Buttons stehen; durch ihre Selektion klappt das Popupmen dann auf. VII. Dialogboxberschrift 1. normaler Typ: STRING, BUTTON 2. erweiterter Typ: 19 3. ungesetztes Flag: SELECTABLE 4. Anmerkung: Der Unterstrich kann die L„nge der Objektbreite (Voreinstellung) oder die L„nge der Objektzeichenkette haben. Dies kann mit der Prozedur set_shorttitle eingestellt werden. VIII. Groupbox (Boxtitel) 1. normaler Typ: BUTTON 2. erweiterter Typ: 20 3. gesetzte States: Ist der Status CHECKED gesetzt, so wird der Boxtitel mit dem kleinen Systemzeichensatz geschrieben. 4. Anmerkung: Die Groupbox wird zum Beispiel als Rahmen um eine Gruppe von Radiobuttons benutzt. IX. Helpbutton 1. erweiterter Typ: 21 2. Anmerkung: Ein derart markiertes Objekt kann durch Drcken der Taste HELP selektiert werden. X. Undobutton 1. erweiterter Typ: 31 2. Anmerkung: Ein derart markiertes Objekt kann durch Drcken der Taste UNDO selektiert werden. XI. Circlebutton 1. normaler Typ: BOXCHAR 2. erweiterter Typ: 22 3. gesetzte Flags: TOUCHEXIT, EXIT XII. Images und Icons Anmerkung: Da ohnehin der gesamte Objektbaum durchsucht wird, werden bei dieser Gelegenheit Images und Icons gleich vom Standardformat ins ger„tespezifische Format konvertiert. Wer dieses Feature nicht nutzen will, sollte vor dem Fixen des Baumes ob_type des Images oder Icons auf einen Phantasiewert setzen und nachher restaurieren. XIII. FText, FBoxtext Anmerkungen: 1. Bekanntlich muž bei F(BOX)TEXT-Objekten im RCS ein Text eingegeben werden, der mindestens so lang ist, wie in 'te_tmplt' gltige Stellen vorhanden sind. Die AES werten die L„nge dieses Textes zur Reservierung von Speicherplatz fr die Eingaben aus. Gibt man einen krzeren Text als Voreinstellung ein, so wird nur fr eine Zeichenkette dieser L„nge Speicherplatz reserviert. šblicherweise setzt man daher im RCS eine beliebige Zeichenkette von der L„nge der Maske, etwa '@12345' oder '123456', ein, um danach im Programm den Inhalt von 'te_ptext' mit einer vernnftigen Voreinstellung zu berschreiben. Mit PDIAL l„žt sich auch ein krzerer Text bereits im RCS voreinstellen. Dazu muž der Text nur bis zum Ende mit Klammeraffen ('@') aufgefllt werden. Diese werden von den Fixing-Routinen aus NEWOBS automatisch entfernt. 2. Die Bedeutung des te_pvalid-Feldes wurde teilweise modifiziert. Deshalb hier eine Liste der zul„ssigen Platzhalter. Platzhalter erlaubte Zeichen ----------- ---------------- 'X' alle Zeichen 'x' wie 'X', aber gegebenenfalls in Grožbuchstaben konvertiert (Anmerkung: Diese Variante ist im Profibuch nicht dokumentiert, funktioniert aber in allen uns bekannten AES-Versionen.) '9' nur Ziffern 'A' Grožbuchstaben und Leerzeichen 'a' Buchstaben und Leerzeichen 'N' Grožbuchstaben, Ziffern, Leerzeichen 'n' Buchstaben, Ziffern, Leerzeichen 'F' alle Zeichen, die zu einem Filenamen geh”ren drfen sowie '|', '*', '?' 'f' alle Zeichen, die zu einem Filenamen geh”ren drfen 'P' alle Zeichen, die zu einem Pfadnamen geh”ren drfen 'p' wie 'P', aber ohne '?' und '*' Die Varianten 'F', 'f', 'P', 'p' sind etwas problematisch, da sich die von ihnen zugelassenen Zeichen nicht mit der GEMDOS-Definition eines legalen Datei-bzw. Pfadnamens decken. Nach letzter sind (laut Profibuch) in Dateinamen erlaubte Zeichen: A..Z, a..z, 0..9, _!@#$%^()+-=~`;"',<>|[]{} Wer das Utility Let 'em Fly von Oliver Scheel installiert hat, das die objc_edit-Routine der AES durch eine eigene ersetzt, kann in die genannten Felder nur diese Zeichen eingeben. Sofern PDIAL verwendet wird und Let 'em Fly nicht installiert ist, kann in die betreffenden Felder aber die Vereinigungsmenge des AES- und des GEMDOS-Verst„ndnisses eines legalen Pfad- und Dateinamens eingetragen werden. Wer nur die vom GEMDOS erlaubten Zeichen zulassen will, verwende die folgenden, von PFORM definierten Platzhalter: 'Y' statt 'F' 'y' statt 'f' 'Z' statt 'P' 'z' statt 'p'. XIV. Mentrennstriche 1. normaler Typ: STRING 2. erweiterter Typ: keiner 3. gesetzte Flags: DISABLED 4. ungesetzte States: SELECTABLE 5. Anmerkung: Strings, die nur aus '-'-Zeichen bestehen und bei denen das Flag DISABLED gesetzt, der State SELECTABLE dagegen nicht gesetzt ist, werden in Mentrennlinien (auch bekannt als 'Nicelines') umgewandelt. Dieses Feature kann mit set_dashmode ein- und ausgeschaltet werden. J. Die einzelnen Routinen I. Routinen aus NEWOBS 1. init_newobs procedure init_newobs(vdihandle: integer); Diese Prozedur initialisiert das Modul NEWOBS. Als Parameter wird das Handle einer virtuellen VDI-Bildschirmworkstation bergeben. 2. fix_tree procedure fix_tree(tree: AESTreePtr; initflag: boolean); Mit dieser Prozedur werden die erweiterten Objekttypen, die Textfelder, die Mentrennstriche und die Images und Icons in einem Objektbaum angepažt, oder es wird der dazu allozierte Speicher wieder freigegeben. 'tree' ist der zu bearbeitende Objektbaum. 'initmode' ist TRUE, wenn die Anpassung vorgenommen werden soll. Da die erweiterten Objekttypen intern ber G_USERDEF-Objekte realisiert werden, muž NEWOBS Speicher fr USERBLK-Strukturen anfordern. Dieser muž nach Abarbeiten des Dialoges (sp„testens am Programmende) wieder freigegeben werden. Dazu wird fix_tree mit 'initmode' = FALSE aufgerufen. 3. fix_all procedure fix_all(initmode: boolean); fix_all ruft fix_tree fr alle B„ume der geladenen Resource auf. Dazu wird die Anzahl der Objektb„ume aus dem Resourceheader ausgelesen, dessen Adresse von rsrc_load in global[7, 8] abgelegt wird. Wer Resourcen per BINOBJ zum Programm dazulinken m”chte, muž also diese Adresse setzen, sofern er fix_all verwenden will. Zu 'initmode' vergleiche die Ausfhrungen zu 2. 4. set_dashmode procedure set_dashmode(change2ln: boolean); Mit set_dashmode kann bestimmt werden, ob Mentrennstriche in Mentrennlinien umgewandelt werden sollen. Die Umwandlung ist voreingestellt. 'change2ln': TRUE: umwandeln; FALSE: nicht umwandeln. 5. set_shorttitle procedure set_shorttitle(short: boolean); Hiermit kann eingestellt werden, ob bei Dialogboxtiteln fr die L„nge des Unterstrichs die L„nge des Textes (kurze šberschrift) oder aber die Breite des Objektes (lange šberschrift) mažgebend ist. Voreingestellt sind lange šberschriften. II. Routinen aus PFORM 1. init_pform procedure init_pform(vdihandle: integer; use_ltmf: boolean); Diese Prozedur initialisiert die Unit PFORM. 'vdihandle' ist das Handle einer virtuellen VDI-Bildschirmworkstation. 'use_ltmf' ist TRUE, wenn zum Verschieben der Dialogboxen die Flugroutinen eines eventuell geladenen Let 'em Fly genutzt werden sollen. Let 'em Fly ist ein (geniales) Freeware-Utility von Oliver Scheel, das diverse Routinen der AES durch eigene ersetzt und so u. a. verschiebbare Dialogboxen in jedem Programm erm”glicht. Wenn Let 'em Fly nicht geladen oder use_ltmf FALSE ist, wird an dieser Stelle Speicherplatz fr die Pufferung des Bildschirms alloziert. Ist dafr nicht gengend Speicherplatz vorhanden, ist das auch nicht weiter schlimm; es kann dann nur eben nicht mit den Dialogen 'geflogen' werden. 2. exit_pform procedure exit_pform; exit_pform muž am Programmende aufgerufen werden, um von init_pform allozierten Speicher freizugeben. 3. pform_size procedure pform_size(tree: AESTreePtr; var x, y, w, h: integer); pform_size gibt in 'x','y', 'w', 'h' die Auženmaže des Dialoges 'tree' zurck. 4. pform_dial function pform_dial(flag, lx, ly, lw, lh, bx, by, bw, bh: integer): integer; pform_dial tritt an die Stelle der AES-Funktion form_dial. 5. init_subdial procedure init_subdial(father: AESTreePtr; var sd: SUBPFORM); init_subdial braucht man, wenn er verschachtelte Dialogboxen programmieren will. Eine Anwendung fr verschachtelte Dialogboxen sind z. B. Hilfekn”pfe, bei deren Selektion eine Dialogbox mit Hilfestellungen ge”ffnet wird. Mit PDIAL kann man Dialoge im Prinzip beliebig tief verschachteln; Verschachtelungstiefen gr”žer 2 sind aber unseres Erachtens ein echter Mižbrauch. father ist der Zeiger auf die darunterliegende Dialogbox. sd braucht hier nicht zu interessieren; darin werden nur interne Informationen bis zum korrespondierenden Aufruf von exit_subdial gespeichert. Die Prozedur muž vor pform_dial(FMD_START, ...) aufgerufen werden. 6. exit_subdial procedure exit_subdial(var sd: SUBPFORM); Auf jedes init_subdial muž nach Abarbeitung des Unterdia- loges (und seiner Unterdialoge) ein korrespondierendes exit_subdial folgen. Die Routine muž nach pform_- dial(FMD_FINISH, ...) aufgerufen werden. 7. pform_do function pform_do(tree: AESTreePtr; start_field: integer): integer; pform_do muž statt der AES-Funktion form_do verwandt werden. 8. pform_thru function pform_thru(tree: AESTreePtr; which: integer; var events: EVENT; var edit_object, idx: integer): integer; pform_thru ist eine spezielle Version von pform_do zur Implementierung nichtmodaler Fensterdialoge. pform_thru muž in die EVENT-Schleife des Hauptprogrammes eingebunden werden. 'tree' ist der Zeiger auf die Dialogbox. 'which' ist das aufgetretene Ereignis, also der Rckgabewert von EvntMulti. 'events' ist die EVENT-Struktur von EvntMulti; 'edit_object' ist das aktuelle Editobjekt, oder 0, wenn ein solches nicht vorhanden ist. Wenn der Dialog zum ersten Mal dargestellt wird, kann man also nicht wie bei pform_do 0 bergeben, um den Cursor auf dem ersten Feld einzuschalten! Dazu muž man selbst ini_field aufrufen. 'idx' ist die Position des Cursors auf dem Editfeld. Rckgabewert: Index des angew„hlten Objektes oder -1. 9. pform_center function pform_center(tree : AESTreePtr; var cx, cy, cw, ch: integer): integer; pform_center entspricht der AES-Funktion form_center. pform_center beachtet den VSCR-Cookie und positioniert, sofern dieses Feature nicht mit set_fastmode(FALSE) ausgeschaltet worden ist, den Dialog beim Zentrieren auf Bytegrenzen, um die Ausgabe der Dialogbox zu beschleunigen. 10. pop_up function pop_up(pmenue: AESTreePtr): integer; pop_up stellt das Popupmen 'pmenue' an der in pmenue^[ROOT].ob_x/ob_y eingetragenen Stelle dar und verarbeitet die Eingaben. Bei dem Popup-Men muž es sich um einen Objektbaum handeln. Dieser darf nur aus dem Wurzelobjekt und den Eintr„gen bestehen; weitere Verschachtelungen werden nicht untersttzt. Der Baum muž sortiert sein. Die einzelnen Eintr„ge k”nnen jeden beliebigen Objekttyp haben. Die Popupmens lassen sich sowohl mit der Maus als auch mit der Tastatur bedienen. Folgende Tasten werden untersttzt: Pfeil hoch/links : vorhergehender Eintrag Pfeil runter, rechts: n„chster Eintrag Home : erster Eintrag Clr : letzter Eintrag Return, Enter, Space: Eintrag ausw„hlen Undo, Esc : Abbruch 11. attach_popup procedure attach_popup(dial: AESTreePtr;popind, strind, btnind, crclind, slct: integer; check: boolean; var dest: POP; nextpop: POPPtr); attach-popup dient der Verwaltung von Popupmens in Dialogboxen. 'dial' ist der Zeiger auf den Dialog. 'popind' ist der Index des Popup-Baumes im RCS. Zu 'stringind', 'btnind' und 'circlind' folgende Skizze: ------------- Popupstring: |Popupbutton|c| ------------- 'stringind' ist der Index eines tastaturbedienbaren Strings (erw. Typ 18, TOUCHEXIT), bei dessen Selektion das Popupmen ausklappen soll. Gibt es einen solchen String nicht, so ist -1 zu bergeben. 'btnind' ist der Index eines Buttons oder eines sonstigen Objektes, das den im Popupmen ausgew„hlten Eintrag zeigt. 'circlind' ist der Index des Popupcircles, mit dem die einzelnen Eintr„ge des Popups ausgew„hlt werden k”nnen, ohne daž es aufklappt. Gibt es keinen Circle, ist -1 zu bergeben. Zum Aufbau eines solchen Gebildes im RCS sp„ter mehr. 'slct' ist der Index des eingangs selektierten Objektes im Popupmen oder 0. 'check' ist TRUE, wenn selektierte Eintr„ge im Popupmen abgehakt werden sollen. 'dest' ist ein record vom Typ POP, der von der Funktion mit den bergebenen Werten gefllt wird und an die Funktionen popup_dialog und do_popdialog bergeben werden muž. 'nextpop' ist die Adresse der POP-Struktur der n„chsten Popup- Konstruktion im Dialog 'dial', oder aber, wenn es eine solche nicht gibt, NIL; Die Prozedur fllt intern 'dest' und setzt den ob_spec des Popupbuttons auf den ob_spec des Popupmeneintrages 'slct'. Daraus ergibt sich, daždie ob_spec's des 'Popupbuttons' und der Eintr„ge im Popumenkompatibel sein mssen! 12. popup_dialog function popup_dialog(dial: AESTreePtr; startob: integer; firstpop: POPPtr): integer; popup_dialog entspricht im Grunde pform_do. Es verwaltet aber aužerdem etwaige Popup-Konstruktionen im Dialog. 'firstpop' ist die Adresse der ersten POP- Struktur oder aber, wenn keine Popup-Konstuktion vorhanden ist, NIL; Der angew„hlte Eintrag in Popumen steht nach der Ausfhrung in firstpop^.select. POPPtr = ^POP; POP = record treeptr : AESTreePtr; stringind : integer; (* oder -1 *) buttonind : integer; circleind : integer; (* oder -1 *) select : integer; check_it : boolean; next : POPPtr; end; 13. do_dialog function do_dialog(dial: AESTreePtr; startob: integer): integer; do_dialog ist eine komfortable Routine, die fr die Verwaltung der allermeisten Dialoge v”llig ausreicht. Statt vieler Worte hier der Sourcecode: function do_dialog(dial: AESTreePtr; startob: integer): integer; var size : GRECT; rc : integer; begin wind_update(BEG_UPDATE); wind_update(BEG_MCTRL); with size do begin pform_center(dial, g_x, g_y, g_w, g_h); pform_dial(FMD_START, g_x, g_y, g_w, g_h, g_x, g_y, g_w, g_h); objc_draw(dial, ROOT, MAX_DEPTH, g_x, g_y, g_w, g_h); rc := pform_do(dial, startob) and $7fff; pform_size(dial, g_x, g_y, g_w, g_h); pform_dial(FMD_FINISH, g_x, g_y, g_w, g_h, g_x, g_y, g_w, g_h); end; wind_update(END_MCTRL); wind_update(END_UPDATE); deselect(dial^[rc]); do_dialog := rc; end (* do_dialog *); 14. do_popdialog function do_popdialog(dial: AESTreePtr; startob: integer; firstpop: POPPtr): integer; do_popdialog ist eine spezielle Variante von do_dialog fr die Verwaltung von Dialogen mit Popupmens. 15. circle_delay procedure circle_delay(val: longint); Mit circle_delay kann die Zeitspanne in ms eingestellt werden, nach der in einem Dialog mit einem Popup-Konstrukt nach Selektierung des Popupcircles der n„chste Eintrag des Popupmens dargestellt wird. 16. set_insert procedure set_insert(ins: INSERTFunc); type INSERTFunc = function: integer; Mit set_insert kann man eine Funktion bergeben, die von PFORM beim Druck der Taste INSERT w„hrend der Bearbeitung einer Dialogbox aufgerufen wird, sofern die Dialogbox ein Eingabefeld enth„lt. Diese Funktion sollte einen Dialog oder ein Popup-Men darstellen und verarbeiten, das dem Benutzer die Auswahl der ber die Tastatur nicht erreichbaren ASCII-Zeichen erm”glicht. Der ASCII-Code des ausgew„hlten Zeichens sollte zurckgegeben werden. Wurde kein Zeichen ausgew„hlt, muž im oberen Wort des Rckgabewertes der Scancode der Taste INSERT, im unteren 0 stehen. 17. set_jumpmode procedure set_jumpmode(use_jump: boolean); Klickt man mit der Maus neben einen Dialog, ert”nt normalerweise eine Klingel. Mit PDIAL dargestellte Dialoge k”nnen optional stattdessen um die Maus herum zentriert werden; sie "springen" zur Maus. Dieses Feature kann mit set_jumpmode ein- ('use_jump' = TRUE; Voreinstellung) und ausgeschaltet ('use_jump' = FALSE) werden. 18. set_feedback procedure set_feedback(feedback: boolean); Hiermit kann die Selektion von Popupcircle und Popupstring ein- (feedback = TRUE; Voreinstellung) oder ausgeschaltet werden. 19. set_fastcenter procedure set_fastcenter(fast: boolean); Ist 'fast' TRUE, so wird der Dialog bei pform_center und beim Springen in horizontaler Richtung auf Bytegrenzen positioniert, um die Ausgabe zu beschleunigen. Dies ist auch die Voreinstellung. Mit 'fast' = FALSE kann dieses Feature mithin abgestellt werden. 20. handle_button, handle_circle, handle_string procedure handle_button(dial: AESTreePtr; currpop: POPPtr); procedure handle_circle(dial: AESTreePtr; currpop: POPPtr); procedure handle_string(dial: AESTreePtr; currpop: POPPtr); Mit diesen drei Funktionen kann man sich einen eigenen Handler fr Popupmens in Dialogboxen basteln. Eine sinnvolle Anwendung erg„be sich etwa bei der Implementierung von unmodalen Fensterdialogen. 21. objc_ed function objc_ed(tree: AESTreePtr; obj, inchar: integer; var idx: integer; kind: integer): integer; Diese Funktion tritt an die Stelle der AES-Funktion objc_edit. Im Vergleich zu jener wurde sie um folgende Merkmale erweitert: a) Der Cursor wird bei 'kind' = EDINIT nicht am Ende der Zeichenkette angestellt, sondern an der in 'idx' bergebenen Stelle. b) Sofern eine solche durch set_insert bergeben wurde, wird bei Druck der Taste INSERT eine Funktion zur Eingabe von Sonderzeichen aufgerufen. c) Control + Delete l”scht den Rest der Zeile. d) Control + Pfeil links und Control + Pfeil rechts springen zum n„chsten Wort. e) Shift + Pfeil links sprigt an den Anfang der Zeile, Shift + Pfeil rechts an deren Ende. f) Control + C speichert den Inhalt der Zeile auf dem Klemmbrett; Control + X schneidet den Inhalt der Zeile aus und speichert ihn auf dem Klemmbrett; Control + V setzt die erste Zeile der Datei SCRAP.TXT aus dem Klemmbrett in das Eingabefeld ein. 22. ini_field function ini_field(tree: AESTreePtr; start_field: integer): integer; Diese Funktion berechnet das erste Eingabefeld in einem Dialog, wenn 'start_field' = 0 oder 'start_field' kein Eingabefeld ist. Diese Funktion wird gebraucht, wenn man ein spezielles form_do schreiben will, etwa fr unmodale Fensterdialoge. III. Routinen aus ALERT ALERT exportiert nur eine einzige Routine: function do_alert(bitblock: BITBLKPtr; otext, obuttons: pchar; bdefault, bundo: integer): integer; 'bitblock' ist die Adresse des Bitblockes des darzustellenden Images. Vordefiniert sind die Bitbl”cke macnote, macwait, macstop, calc, gem2note, gem2wait, gem2stop, gem1note, gem1wait, gem1stop, happy, sad, bomb, info, inversnote, inverswait und inversstop. 'otext' ist der Text der Alertbox. Erlaubt sind bis zu 18 Zeilen mit bis zu 29 Buchstaben, jedoch (wegen Pascal) insgesamt h”chstens 255 Zeichen. Der Text wird automatisch umgebrochen, sofern er nicht schon mit '|'-Zeichen formatiert ist. 'obuttons' rep„sentiert die Buttons. Die einzelnen Buttons werden durch '|'-Zeichen getrennt. Fr die Breite ist die L„nge des l„ngsten Textes mažgeblich. Die Buttons k”nnen mit dem '['-Zeichen markiert werden; sie sind dann auch per Alternate + Buchstabe anw„hlbar. 'bdefault' ist die Nummer (beginnend mit 0) des mit den Tasten Return und Enter selektierbaren Buttons oder kleiner als 0; 'bundo' ist entsprechend die Nummer des mit der Taste Undo anw„hlbaren Knopfes. Zurckgegeben wird der Index des angew„hlten Buttons oder, wenn ein Fehler aufgetreten ist, ein negativer Wert. Da der Objektbaum dynamisch aufgebaut wird, sind Fehler bei der Speicherallozierung denkbar. IV. Routinen aus der Unit MEMORY Die Units des PDIAL-Paketes verwenden zur Speicherallozierung ausschliežlich die Routinen der Unit MEMORY. Jene wiederum liegt im Quelltext bei, so daž jeder, der eine Speicherverwaltung ge- schrieben hat, die Speicher in gr”žeren Bl”cken als Pure Pascal vom Betriebssystem anfordert, MEMORY an diese anpassen kann (und sollte). Nun die Routinen im einzelnen. 1. mem_alloc procedure mem_alloc(var p: pointer; size: longint); mem_alloc alloziert 'size' Byte Speicher an der Adresse 'p'. Im Fehlerfall enth„lt 'p' den Wert NIL. 2. mem_free procedure mem_free(var p: pointer; size: longint); mem_free gibt an der Adresse 'p' 'size' Byte Speicher frei. 3. strdup function strdup(str: pchar): pchar; strdup alloziert ausreichend Speicher und kopiert dann dort den nullterminierten String 'str' hinein. Sollte nicht gengend Speicher vorhanden sein oder 'str' die L„nge 0 haben oder gleich NIL sein, so ist der Rckgabewert NIL. Sonst wird die Adresse des Zielstrings zurckgegeben. Vergleiche auch strnew. V. Routinen und Typen aus TOOLS Die Routinen aus TOOLS br„uchten bei der Programmierung mit PDIAL eigentlich gar nicht verwendet zu werden. Da sie aber wohl ganz ntzlich sind, werden sie hier gleichwohl dokumentiert. 1. GRECT GRECT = record g_x, g_y, g_w, g_h : integer; end; GRECT dient der Aufnahme der Koordinaten eines Rechteckes bei der AES-Programmierung. 2. min function min(a, b: integer): integer; Min gibt den kleineren der Werte 'a' und 'b' zurck. 3. max function max(a, b: integer): integer; Max gibt den gr”žeren der Werte 'a' und 'b' zurck. 4. hiword function hiword(l: longint): word; Hiword gibt die oberen 16 Bit des Langwortes 'l' zurck. 5. loword function loword(l: longint): word; Loword gibt die unteren 16 Bit des Langwortes 'l' zurck. 6. function get_cookie(cookie: longint): pointer; Get_cookie gibt die Adresse des zu 'cookie' geh”renden Cookie-Jars zurck. Konnte ein solcher nicht gefunden werden, so wird NIL zurckgegeben. 7. set_state procedure set_state(var obj: AESObject; state: integer); Set_state setzt den Status 'state' im Objekt 'obj'. 8. unset_state procedure unset_state(var obj: AESObject; state: integer); Unset_state l”scht den Status 'state' im Objekt 'obj'. 9. is_state function is_state(var obj: AESObject; state: integer): boolean; Die Funktion gibt TRUE zurck, wenn im Objekt 'obj' der Status 'state' gesetzt ist, ansonsten FALSE. 10. set_flag procedure set_flag(var obj: AESObject; flag: integer); Set_flag setzt das Flag 'flag' im Objekt 'obj'. 11. unset_flag procedure unset_flag(var obj: AESObject; flag: integer); Unset_flag l”scht das Flag 'flag' im Objekt 'obj'. 12. is_flag function is_flag(var obj: AESObject; flag: integer): boolean; Die Funktion gibt TRUE zurck, wenn im Objekt 'obj' das Flag 'flag' gesetzt ist, ansonsten FALSE. 13. deselect procedure deselect(var obj: AESObject); Deselect l”scht im Objekt 'obj' den Status SELECTED. 14. draw_object procedure draw_object(tree: AESTreePtr; obj: integer); Draw_object malt das Objekt 'tree^[obj]' mit den Clipping- Koordinaten des Wurzelobjektes. 15. is_enabled function is_enabled(var obj: AESObject): boolean; Is_enabled gibt TRUE zurck, wenn im Objekt 'obj' der Status DISABLED gel”scht und das Flag SELECTABLE gesetzt sind, ansonsten FALSE. 16. maptree procedure maptree(tree: AESTreePtr; this, last: integer; routine: MAPProc); type MAPProc = function(tree: AESTreePtr; obj: integer): boolean; Maptree durchwandert den Baum 'tree' vom Objekt mit der Nummer 'this' bis zum Objekt mit der Nummer 'last'. Dabei wird fr jedes Objekt die Funktion 'routine' aufgerufen. Wenn 'routine' FALSE zurckgibt, werden etwaige Kinderobjekte des aktuellen Objektes ignoriert. 17. is_space function isspace(c: char): boolean; Is_space entspricht der gleichnamigen Funktion aus der Sprache C. Es wird TRUE zurckgegeben, wenn der Buchstabe 'c' eines der Zeichen , oder ist. K. Popupmens in Dialogboxen und ihr Aufbau im RCS Ein vollst„ndiges Popup-Konstrukt mit links daneben stehendem String und Circlebutton sollte man im RCS wie folgt aufbauen: Zun„chst muž eine IBOX eingefgt werden. Ihr Rand sollte einen Pixel innerhalb oder (besser) einen Pixel aužerhalb der IBOX liegen. Die IBOX ist zu schattieren. Die Flags SELECTABLE, EXIT, TOUCHEXIT sind NICHT zu setzen. In die IBOX sind der Popupbutton und der Circlebutton als Kinder einzufgen. Der Circlebutton muž ein BOXTEXT mit dem erweiterten Typ 22 sein. Man muž entweder das Flag TOUCHEXIT oder die Flags SELECTABLE und EXIT setzen. Der Popupbutton muž ebenfalls den erweiterten Typ 22 haben; fr die Flags gilt das soeben gesagte. Es ist zu beachten, daž der (normale) Objekttyp des 'Popupbuttons' zum Typ der Eintr„ge des korrespondierenden Popupmens pažt, weil ja der ausgew„hlte Eintrag in dem Popupbutton dargestellt wird und dies in popup_dialog durch einfaches šberschreiben des ob_spec des Popupbuttons mit dem ob_spec des ausgew„hlten Eintrages realisiert ist. Wenn der Popupbutton also etwa wirklich ein Button ist, k”nnen im Popupmen nur Eintr„ge der Typen BUTTON und STRING stehen; ist er aber zum Beispiel ein TEXT, so mssen die Eintr„ge im Popupmen (BOX)TEXTe sein. Wenn man keinen Circlebutton verwenden will, kann man auf die zugrundeliegende IBOX verzichten. In diesem Fall ist dann aber der Popupbutton mit dem Status SHADOWED zu versehen. Links neben den Popupbutton kann ein String plaziert werden. Dieser sollte ein tastaturbedienbarer String mit dem erweiterten Typ 18 sein und Auskunft ber das Popumen geben; er sollte einen Doppelpunkt enthalten. Ferner sollten die Flags TOUCHEXIT bzw. EXIT und SELECTABLE gesetzt sein, so daž das Popupmen auch mit der Tastatur aufgeklappt werden kann. Stehen mehrere Popupbuttons mit zugeh”rigem String in einer Dialogbox untereinander, so sollten die Doppelpunkte untereinander stehen. L. PDIAL und nichtmodale Fensterdialoge Nichtmodale Dialoge (oder auf gut Deutsch 'modeless dialog boxes') liegen in einem Fenster. Bei ihnen hat man im Unterschied zu den normalen Dialogen Zugriff auf Fenster und Menleiste. Sie zwingen mit anderen Worten den Benutzer nicht in einen Modus. Dies ist besonders interessant in einer Multitaskingumgebung, da damit ein Taskwechsel m”glich bleibt. Daneben gibt es noch modale Fensterdialoge, die den Zugriff auf die Fenster und die Menleiste nur der eigenen Applikation verwehren, einen Taskwechsel aber erm”glichen. Wie mit PDIAL unmodale Fensterdialoge zu programmieren sind, kann man dem Listing MODELESS.PAS entnehmen. Das Prinzip besteht darin, aus der Hauptereignisschleife des Programmes die fr den Fensterdialog bestimmten Maus- und Tastaturereignisse herauszufischen. Dies erledigt in dem Listing die Funktion pform_win. Auf die Programmierung einer fertigen Unit fr solche Dialoge haben wir verzichtet, da dies eine allgemeingltig formulierte Fensterverwaltung vorausgesetzt h„tte. Eine wirklich universelle Fensterverwaltung - wie sie etwa in dem GEM-Buch der Gebrder Geiž vorgestellt wird - bekommt aber wegen der vielf„ltigen denkbaren Kombinationsm”glichkeiten leicht monstr”se Zge und ist fr Dritte nur mhsam zu durchschauen. Schliežlich geht es hier ja auch nicht um Fensterverwaltung, sondern um Dialogboxen. M. PDIAL und modale Fensterdialoge Die Programmierung modaler Fensterdialoge mit PFORM wird im Listing MODAL.PAS vorgefhrt. N. PDIAL und Let 'em Fly Let 'em Fly ist ein Freeware-Utility von Oliver Scheel, das eine Reihe von AES-Routinen durch eigene ersetzt. Es drfte in jeder MAUS zu saugen sein. Es verleiht auch solchen Dialogboxen, die nicht mit einem Flydial-Clone wie PDIAL programmiert worden sind, Flugf„higkeit und Tastaturbedienbarkeit. Interessant im Zusammenhang mit PDIAL ist, daž die Flugroutinen von Let 'em Fly durch eine Schnittstelle nach aužen gefhrt sind. Wenn Let 'em Fly installiert sind, kann PDIAL so konfiguriert werden, daž auf die Allozierung eines eigenen Hintergrundpuffers verzichtet und stattdessen Hintergrundrestaurierung und Dialogverschiebung ausschliežlich ber Let 'em Fly erfolgen. Vorsicht ist allerdings anzuraten bei verschachtelten Dialogen: Let 'em Fly scheint mit einer Verschachtelungstiefe gr”žer 6 nicht fertig zu werden. Wir empfehlen, die Verwendung von Let 'em Fly in Anwenderprogrammen dem User in einem Konfigurationsdialog anzubieten. Prinzipbedingt kann die Einstellung aber erst NACH dem n„chsten Programmstart ausgewertet werden - die Voreinstellung muž also abgespeichert werden k”nnen. O. PDIAL und Interface Da die Codierung der erweiterten Objekttypen weitgehend kompatibel zu der in den My-Dials verwendeten ist, kann zum Austesten im RCS Interface das mit Interface gelieferte EXTOBFIX.PRG verwendet werden. Unterschiede ergeben sich aber hinsichtlich tastaturbedienbarer Strings und Groupboxberschriften mit dem kleinen AES-Zeichensatz. P. Wenn ein Fehler auftritt,... ...dann wendet euch bitte an uns! Als Programmierer wižt Ihr bestimmt, welche Informationen wir brauchen. Interessant w„re darber hinaus, ob die Probleme bereitende RCS-Datei mit dem Programm SHOWDIAL angezeigt werden kann. Auch fr Erweiterungsvorschl„ge haben wir ein offenes Ohr. Wir bitten aber um Verst„ndnis dafr, daž nur derjenige eine Antwort erh„lt, der einen selbstadressierten, ausreichend frankierten Briefumschlag - gegebenenfalls mit Diskette - beifgt. Unsere Anschriften lauten: Jrgen Holtkamp Jobststraže 65 44629 Herne Uwe Holtkamp Altenh”fenerstraže 75 44623 Herne Q. Literatur Nachfolgend nun ein Verzeichnis der verwendeten Aufs„tze und Bcher. Den Autoren sei an dieser Stelle herzlich gedankt. H”vener, Markus Menutune ST Computer 3/1992, 87f. Jankowski/Rabich/Reschke ATARI Profibuch 12. Auflage (4. berarbeitete Auflage) 1992 Dsseldorf 1991 Meisiek, Olaf Die MyDial-Funktionsbibliothek (Anleitung zu den MyDials im Lieferumfang von Interface) Oren, Tim Professional GEM 1985 (in diversen Mailboxen) Prssner, Laurenz Verdeckte Ermittlungen ST Magazin 6/1992, 91 Rabich, Dietmar Flexible Alertbox ST Computer 11/1992, 84ff. derselbe Mehr Bedienungskomfort ST Magazin 12/1992, 106ff. Rudolph, Ralf Pascal fr Umsteiger (Teil 6) Atari Journal 12/92, 71ff. Sattler, Wolfgang form-keybd & form_button in MAXON-Pascal ST Copmuter 2/1992, 83ff. Scheel, Oliver Three Flights Up (Programmieranleitung zu Let 'em Fly) Schlter, Axel Fly Deals TOS 12/1992, 58f.; TOS 1/93 Tolksdorf, Robert AUTOFLY, Nur Fliegen ist sch”ner ST Computer 6/1991,101ff.