DESTROY eines GUI-Fensters

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Werner
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 120
Registriert: Sa, 18. Mär 2006 16:08

DESTROY eines GUI-Fensters

Beitrag von Werner »

Hi!

ich versuche seit Tagen vergeblich ein GUI-Fenster, das angezeigt wurde, anschließend zu schließen bzw. zu löschen. Das Ganze sieht etwa so bei mir aus:

@ 20,2 DCPUSCHBUTTON CAPTION "XYZ";
SIZE 12,2;
OBJECT ogrund;
TABSTOP TABGROUP XBP_BEGIN_GROUP;
ACTION { II auswahl(1) }

....

@ 20,45 DCPUSHBUTTON CAPTION "ABC";
SIZE 12,2;
TABSTOP TABGROUP XBP_END_GROUP;
ACTION { II AppQuit() }

DCGETOPTIONS;
WINDOWHEIGHT 720;
WINDOWWIDTH 1024;
ROWSPACE 25;
GETFONT oFont;
SYHEIGHT 25;
GETHEIGHT 25;
NOMAXBUTTON;
NOMINBUTTON

DCREAD GUI;
TITLE "XXXXXX";
OPTIONS Getoptions;
SETFOCUS @ogrund;
PARENT @odlg;
TIMEOUT {300, {II vs_clock(), .F.}};
TO lOk

Wie kann ich dieses Fenster nach der Anzeige bzw. nach der Auswahl eines PUSHBUTTONS schließen bzw. zerstören? Muss ich dem Fenster vorher einen Namen geben und wenn ja, wie bzw. wo muss ich das tun?
Hat das TIMEOUT etwas damit zu tun?

Vielen Dank für Eure Mühe im Voraus!

Gruß Werner
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9355
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: DESTROY eines GUI-Fensters

Beitrag von Tom »

Hallo, Werner.

Du musst das Fenster nicht explizit zerstören - das macht "DCREAD GUI" am Ende automatisch, wenn das Fenster verlassen/geschlossen wird. Es gibt Fälle, in denen lässt man solche Dialoge stehen, verlässt aber die Eventloop (DCREAD GUI EXIT NOESTROY). In solchen Fällen zerstört man das Dialogobjekt und alle Kinder später mit "oDialog:Destroy". "oDialog" ist die Variable, die man bei DCREAD GUI als PARENT wählt, in Deinem Fall "odlg". "PARENT @oDlg" bewirkt, dass der Dialog in der Variablen "oDlg" gespeichert wird, manipuliert und später auch gelöscht werden kann - was, wie gesagt, nicht erforderlich ist, wenn man das Fenster schließt, da eXpress++ selbst dafür sorgt. Das kannst Du auch prüfen, indem Du Dir später irgendwo "oDlg" anzeigen lässt. Es wird NIL sein.
Herzlich,
Tom
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2934
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: DESTROY eines GUI-Fensters

Beitrag von Wolfgang Ciriack »

Einfach in den ACTION Block des entsprechenden Pushbuttons ein
DC_ReadGuiEvent(DCGUI_EXIT_ABORT,GetList) oder DC_ReadGuiEvent(DCGUI_EXIT_OK,GetList).
Bei ..._ABORT ist dann lok .F., bei ..._OK dann .T.
Viele Grüße
Wolfgang
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9355
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: DESTROY eines GUI-Fensters

Beitrag von Tom »

Ah, ich hatte die Frage falsch verstanden (komplizierter, als sie war).

DCREAD GUI eröffnet die eXpress++-eigene Eventloop. Das Programm erzeugt das Fenster und alle Elemente und handelt die Events ab. Das macht es so lange, bis diese (!) Eventloop beendet wird. Dein Code verharrt quasi direkt hinter dem DCREAD. Das Fenster kann, wenn es keine weiteren entsprechenden Möglichkeiten enthält, über den Schließen-Button (X) oder Alt-F4 verlassen werden. Das hätte zur Folge, dass der Code hinter dem DCREAD abgearbeitet wird. Mit der Option "ADDBUTTONS" würden zwei Schaltflächen ("OK" und "Abbruch") hinzugefügt werden, die genau das täten, was Wolfgang angemerkt hat. "DC_ReadGUIEvent(DCGUI_EXIT_OK,GetList)" beendet eine Eventloop, setzt die OK-Variable (TO ...) auf .T. und, wichtig, lässt die Werte im Dialog so, wie sie dort verändert wurden. "DC_ReadGUIEvent(DCGUI_EXIT_ABORT,GetList) beendet die Eventloop auch, setzt die OK-Variable auf .F. und restauriert die Werte so, wie sie vor dem Aufruf des Dialogs waren - Änderungen werden also rückgängig gemacht. Der Code für Deinen "Ende-Button" müsste also so lauten:

Code: Alles auswählen

@ 20,45 DCPUSHBUTTON CAPTION "ABC";
SIZE 12,2;
TABSTOP TABGROUP XBP_END_GROUP;
ACTION { ||DC_ReadGuiEvent(DCGUI_EXIT_OK,GetList) }
Das Fenster verschwindet, alle Objekte werden gelöscht, der Code hinter dem DCREAD wird ausgeführt.

TIMEOUT bewirkt, dass der Dialog nach x Hundertstelsekunden der Benutzeruntätigkeit (in Deinem Fall 300, also 3 Sekunden) den zweiten Teil des Codeblocks evaluiert. Gibt er .T. zurück, beendet sich der Dialog, gibt er .F. zurück (bei Dir fest), läuft der Dialog weiter. Ich nehme an, dass "v_clock()" irgendein Textfeld aktualisiert (Uhrzeit).

Wichtig ist, dass der Dialog eine möglichst lokale Arrayvariable GetList kennt, die am Anfang initialisiert wird. Sie enthält später alle Dialogobjekte. Dadurch stehen dann auch Funktionen wie "DC_GetRefresh(GetList)" zur Verfügung, die beispielsweise alle Objekte aktualisieren. Dadurch kann z.B. ein SLE einen Codeblock enthalten, wodurch sich die Caption des Textstatics ändern kann:

Code: Alles auswählen

n := 1
@ 1,1 DCSAY {||IF(n=1,'Mann','Frau')} SIZE 10,1
@ 2,1 DCPUSHBUTTON CAPTION 'Test' SIZE 5,1 ACTION {||n:=IF(n=1,2,1),DC_GetRefresh(GetList)}
Wenn man den Pushbutton betätigt, ändert sich das DCSAY von "Mann" in "Frau". Als kleines Beispiel.

Apropos Beispiel: Schau Dir unbedingt die ausführlichen Beispiele an!
Herzlich,
Tom
Antworten