Inhaltsverzeichnis: 1. Einfhrung 2. Beschreibung der Routinen 3. Tips fr die Programmierung 4. Bugs 5. Kontakte 1. Einfhrung Die Routinen von WINDDIAL dienen zur Verwaltung von Dialogboxen in normalen GEM-Fenstern. Jede Menge Leute werden jetzt schon wissen, wozu das gut ist. Diese brauchen dann erst den n„chsten Abschnitt lesen. Warum also Dialoge in Fenstern? Die Darstellung irgendwelcher Informationen (wie z.B. der Dialogbox) ist unter GEM nur in Fenstern m”glich, wenn man nicht alle anderen Aktivit„ten des Rechners lahmlegen will oder mit dem šberschreiben seiner Infos rechnen will. Die normale form_do()-Routine muž daher mit einem wind_update() geschtzt werden, die dem AES Schreiboperationen auf dem Bildschirm untersagt. Dadurch geht die Kontrolle ber den Rechner sozusagen auf die Dialogbox ber, andere Programme (oder Accessorys) k”nnen w„hrend der Zeit der Dialogabarbeitung nichts unternehmen. L„žt man das wind_update() weg, muž man bei der erstbesten Gelegenheit damit rechnen, daž die Dialogbox bermalt wird. Auf einem normalen Atari mag es durchaus akzeptabel sein, daž erst die Dialogbox fertig bearbeitet wird, unter MULTITOS, wenn mehrere Programme sichtbar sind, ist das jedoch „užerst unpraktisch. Legt man nun den Dialog in ein Fenster, wird man vom AES informiert, wenn die Informationen aufgefrischt werden mssen. Man kann also getrost vorbergehend die Kontrolle abgeben und die Dialogbox kann gnadenlos bermalt werden: wenn sie dann wieder gebraucht wird, bekommt man ja die Nachricht, alles neu zu zeichnen. Im XCONTROL.ACC von Atari wird es bereits so gemacht. Mit dem hier vorgestellten Routinen kann jeder Programmierer fr seine Programme Dialogboxen in Fenster legen und verwalten lassen. 2. Beschreibung der Routinen WINDDIAL wurde so entwickelt, daž m”glichst wenig Aufwand bei der Umgestaltung eigener Programme mit normalen Dialogboxen entsteht. Ich glaube dennoch nicht, das dadurch unn”tig ineffektiv programmiert wurde. Es werden 3 Routinen angeboten, die 3 AES-Funktionsaufrufe ersetzen: - form_wind(...) kommt fr form_dial(FMD_START,...) - wind_do(...) kommt fr form_do(...) - form_wclose(...) kommt fr form_dial(FMD_FINISH,...) Die Prototypen sind "winddial.h" angegeben. Eine wesentliche Rolle spielt die Datenstruktur "wi_data", in der alle n”tigen Informationen ber das Fenster und den Objektbaum enthalten sind. Ein Zeiger auf diese Struktur ersetzt bzw. erweitert den Zeiger auf den Objektbaum bei den obigen Funktionsaufrufen. /* struct zum Verwalten der Windows */ typedef struct { unsigned drawed: 1; /* Flag fr erstes Redraw */ unsigned auto_top: 1; /* andere Fenster toppen */ unsigned ltmf: 1; /* let 'em fly nutzen */ } wi_flags; drawed verhindert das doppelte Zeichnen der Dialogbox beim ersten Aufruf (einmal durch den Nutzer und dann nach Eintreffen der Redraw- Meldung), auto_top sorgt darr, daž auch andere Fenster als das der Dialogbox getopt werden (d.h. wenn eine WM_TOPPED-Message kommt, wird im True-Fall das gemeldete Fenster als oberstes Fenster gesetzt. Das kann Arbeit sparen, aber auch unerwnscht sein). ltmf schliežlich steuert die Nutzung von Let 'em fly. typedef struct{ int wi_handle; /* Window-Handle */ OBJECT *obj; /* Zugeh”riger Object-Baum */ int *m,*n,*o,*p; /* Clipping-Koordinaten */ wi_flags flags; /* Flags fr Fenster*/ }wi_data; Kommen wir zur Beschreibung der Routinen: /******************************************************** * form_wind() * * initialisieren und zeichnen des Fensterrahmens * * erste 5 Parameter: wie form_center * * wind : Zeiger auf zu bearbeitende Window-Struktur * * title: Titel des Fensters * * return: im Fehlerfall !=0 , sonst 0 * ********************************************************/ int form_wind(OBJECT *ptr,int *center_x,int *center_y, int *center_w,int *center_h, wi_data *wind,char *title); Die ersten 5 Parameter sollten direkt aus form_center bernommen werden. Als n„chstes folgt die Adresse einer wi_data-Struktur, die in dieser Funktion ausgefllt wird. Und schliežlich wird ein Zeiger auf einen String bergeben, der als Titelzeile des Fensters dient. Kann kein Fenster ge”ffnet werden, wird eine normale Dialogbox ge”ffnet, die von wind_update() geklammert wird. Es wird hierzu form_do() aufgerufen. /************************************ * form_wclose() * * Dialog beenden, Fenster schliežen * * Parameter: * * wind: Zeiger auf Fensterstruktur * ************************************/ int form_wclose(wi_data *wind); Ganz einfach schliežen des Fenstes mit der Dialogbox. /***************************************************************** * form_do() in Fenstern: wind_do() * * Parameter: * * wind : von form_wind() bearbeitetes wind-Objekt * * start_field: Objektnummer, in dem sich der Textcursor zuerst * * befinden soll * * buf[8] : Messagepuffer * * return : Nummer des angesprochenen Objektes oder * * -1 Nach Eintreffen einer Message * *****************************************************************/ /* aus dem Profibuch (form_do()), erweitert um Message-Handling */ int wind_do(wi_data *wind,int start_field,int *buf); Hier war das meiste zu tun. wind_do() bernimmt die komplette Verwaltung der Dialogbox einschliežlich aller Redraws. Nach Rckkehr aus dieser Routine, wenn ein Exit-Object angesprochen wurde, kann man sicher sein, das die Box so aussieht, wie sie es soll. Der dritte Parameter buf dient zur Abspeicherung der eingetroffenen Nachrichten. Alle eingegangenen Nachrichten werden weitergemeldet, auch Redraws, die schon abgearbeitet wurden. Ein Redraw innerhalb von wind_do() bezieht sich immer nur auf den angegebenen Objektbaum (analog zu CPX-Modulen). Die Nachricht WM_TOPPED fhrt in Abh„ngigkeit vom Flag auto_top zum Toppen des angegeben Fensters. Der entsprechende wind_set()-Aufruf braucht also vom Hauptprogramm nicht get„tigt werden. Wird wind_do() in Accessorys verwendet und das Dialogfenster ist gerade nicht sichtbar, fhrt ein Anklicken des Accessory-Menintrages zu einem Sichtbarmachen des Fensters. Von T34 (Thomas Baade) wurde ein weiteres Feature eingebaut: In den Edit- Feldern kann der Cursor mittels der Maus positioniert werden. 3. Tips fr die Programmierung Ein Beispielprogramm sieht z.B. so aus { .... int x,y,w,h,mesg_buf[8]; int form; wi_data wind; form_center(tree,&x,&y,&w,&h); form_wind(tree,&x,&y,&w,&h,&wind," Titel "); /* war: form_dial(FMD_START,...) */ form_dial(FMD_GROW,0,0,0,0,x,y,w,h); objc_draw(tree,0,8,x,y,w,h); form=wind_do(&wind,0,mesg_buf[8]); switch(form) { case -1: HandleMesg(); break; .... } form_dial(FMD_SHRINK,0,0,0,0,x,y,w,h); form_wclose(&wind); /* war: form_dial(FMD_FINISH,...) */ ... } Die Unterschiede sind sind also zun„chst nicht umwerfend. Sie liegen aber im Detail. Insbesondere mssen die Ergebnisse von wind_do() erweitert betrachtet werden: - darauf achten, daž bei return: -1 (Message) kein Objekt versucht zu zeichnen (tree[-1] macht wohl kaum einen Sinn) - wie auch bei form_do() wird ein Doppelklick durch setzen des obersten Bits im Returnwert gekennzeichnet. Also bei Bedarf ausmas- kieren (form&0x7fff). Dadurch wird natrlich die Messagekennung auch zu 0x7fff (statt -1). - Es k”nnen natrlich auch Mens, andere Fenster ... angew„hlt werden. Das sollte beachtet werden. - Es k”nnen mehrere Dialoge parallel bearbeitet werden. (wenn vom Programm untersttzt) - Die Fenster und damit die Dialoge k”nnen verschoben werden. - Das Fenster hat einen Schliežknopf. Die Meldung WM_CLOSED sollte also ausgewertet werden. - Bei Einsatz in Accessorys muž die Meldung AC_CLOSE unbedingt zum Schliežen des Fensters fhren. - Fr die Behandlung der beiden obigen Meldungen schlage ich gleiche Behandlung wie bei CPX-Modulen vor: WM_CLOSED als Abbruch und AC_CLOSE als OK. (sofern es in dieser Art einen Sinn macht) Ach so, wenn Let 'em fly installiert ist, wird dieses zur Auswertung von Tastaturshortcuts genutzt (in Abh„ngigkeit vom Flag ltmf). 4. Bugs Viele Fehler sind uns noch nicht aufgefallen. Aber in Zusammenarbeit mit Let 'em fly gibt es einige (zwei) Probleme: - Aus ungekl„rten Grnden strzt der Rechner ab, wenn zwei wind_dials() aktiv sind und ein - Programm die Dialogbox schliežt, - wind_update(BEG_MCTRL) macht, - dann die Fileselectbox aufruft, - ein wind_update(END_MCTRL) macht. Wahrscheinlich im zweiten wind_update passiert der Absturz. Zum Probieren am besten zweimal RENUMBER als Accessory laden und aus einem eine Datei ausw„hlen. - Wird der Dialog teilweise aus dem Bildschirm geschoben, werden die Unter- stricht von Let 'em fly mitten auf dem Schirm plaziert. Das liegt wahr- scheinlich daran, das in Let 'em fly kein VDI-Clipping gemacht wird. Bei der Erstellung der winddials stand mir Let 'em fly Version 1.14 zur Verfgung. 5. Kontakte Fr Kommentare, Anfeindungen, Danksagungen, Tips e.t.c. bin ich im Mausnetz unter Jan Starzynski @ HRO zu erreichen. PS: Im Programm "RENUMBER.PRG" wird von diesen Dialogen Gebrauch gemacht.