home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 48
/
Amiga_Dream_48.iso
/
Atari
/
c
/
windial.lzh
/
WINDDIAL
/
WINDDIAL.TXT
< prev
Wrap
Text File
|
1993-04-11
|
10KB
|
237 lines
Inhaltsverzeichnis:
1. Einführung
2. Beschreibung der Routinen
3. Tips für die Programmierung
4. Bugs
5. Kontakte
1. Einführung
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()
geschützt 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 müssen. Man kann also
getrost vorübergehend 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 für 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 für form_dial(FMD_START,...)
- wind_do(...) kommt für form_do(...)
- form_wclose(...) kommt für 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 für 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 darür, 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 unerwünscht 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 für 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 ausgefüllt 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 Rückkehr
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 führt 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, führt ein Anklicken des Accessory-Menüintrages 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 für 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 müssen 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 natürlich die Messagekennung auch
zu 0x7fff (statt -1).
- Es können natürlich auch Menüs, andere Fenster ... angewählt werden.
Das sollte beachtet werden.
- Es können mehrere Dialoge parallel bearbeitet werden. (wenn vom Programm
unterstützt)
- 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 führen.
- Für 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 Gründen stürzt 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
Verfügung.
5. Kontakte
Für 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.