Fenster schliessen

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
JanR
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 129
Registriert: Di, 18. Okt 2005 14:44

Fenster schliessen

Beitrag von JanR »

Hallo,

habe folgendes Problem. Ich rufe von einem Fenster über einen Button ein weiteres Fenster auf. Wenn ich das zweite Fenster über das X rechts oben schliesse, schliesst er das Fenster und arbeitet weiter. Im Beispiel gibt er eine MessageBox aus. Wenn ich allerdings das Fenster über einen Button schliessen will, kommt die MessageBox nicht. Was mache ich hier falsch? In der :close() methode des XbpDialogs steht das selbe drin wie in der activate() methode des XbpPushButton.

Hier der Quellcode:

Code: Alles auswählen

#include "appevent.ch"
#include "xbp.ch"

PROCEDURE AppSys()
RETURN


PROCEDURE Main()
   LOCAL n := 1

   oDlg1         := XbpDialog():new( ,, {50,30}, {300,200} ) 
   oDlg1:title   := "Parent is Application Window" 
   oDlg1:create() 
   oDlg1:close := {|| oDlg1:destroy()}

   oPB := XbpPushButton():new(oDlg1, oDlg1, {10,10}, {80,25})
   oPB:caption := "Test"
   oPB:create()
   oPB:activate := {|| Test(oDlg1, n)}

   nEvent := 0 
      DO WHILE nEvent <> xbeP_Close 
         nEvent := AppEvent( @mp1, @mp2, @oXbp ) 
         oXbp:handleEvent( nEvent, mp1, mp2 ) 
      ENDDO 
RETURN


FUNCTION Test(oDlg1,n)
   IF n == 1
      CreateNewWindow()
      MsgBox("Test")
   ENDIF
RETURN


FUNCTION CreateNewWindow(oDlg1)
   oDlg2         := XbpDialog():new(oDlg1 ,oDlg1, {200,30}, {300,200} ) 
   oDlg2:title   := "Parent is Application Window" 
   oDlg2:create() 
   oDlg2:close := {|| oDlg2:destroy()}   

   oPB := XbpPushButton():new(oDlg2, oDlg2, {10,10}, {80,25})
   oPB:caption := "Schliessen"
   oPB:create()
   oPB:activate := {||oDlg2:destroy()}

   nEvent := 0 
      DO WHILE nEvent <> xbeP_Close 
         nEvent := AppEvent( @mp1, @mp2, @oXbp ) 
         oXbp:handleEvent( nEvent, mp1, mp2 ) 
      ENDDO 
RETURN
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: Fenster schliessen

Beitrag von AUGE_OHR »

hi,
JanR hat geschrieben: In der :close() methode des XbpDialogs steht das selbe drin wie in
der activate() methode des XbpPushButton.

Code: Alles auswählen

      CreateNewWindow()

FUNCTION CreateNewWindow(oDlg1)
   oDlg2:close := {|| oDlg2:destroy()}   

   oPB:activate := {||oDlg2:destroy()}

   nEvent := 0 
      DO WHILE nEvent <> xbeP_Close 
         nEvent := AppEvent( @mp1, @mp2, @oXbp ) 
         oXbp:handleEvent( nEvent, mp1, mp2 ) 
      ENDDO 

RETURN
also ich meine das du oPB:activate := {||oDlg2:destroy()} nicht so
benutzten kannst. Das oDlg2:destroy() würde ich nach dem ENDDO
ansetzten und "nEvent <> xbeP_Close" durch ".NOT. lExit" zum
"schliessen" ersetzen.

Code: Alles auswählen

LOCAL lExit := .F.
...
   oDlg2:close := {|| lExit := .T.}   
...
*   oPB:activate := {||oDlg2:close()}
// sorry muss wie Hubert schreibt
   oPB:activate := {|| postappevent(xbeP_Close)}
...
   DO WHILE .NOT. lExit
...
   ENDDO
...
oDlg2:destroy()
gruss by OHR
Jimmy
Zuletzt geändert von AUGE_OHR am Di, 01. Aug 2006 16:03, insgesamt 2-mal geändert.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Fenster schliessen

Beitrag von brandelh »

JanR hat geschrieben:

Code: Alles auswählen

#include "appevent.ch"
#include "xbp.ch"

PROCEDURE AppSys()
RETURN


PROCEDURE Main()
...
FUNCTION Test(oDlg1,n)
   IF n == 1
      CreateNewWindow() <- hier hängt das Fenster 2, bis es geschlossen wird.
      MsgBox("Test")
   ENDIF
RETURN

FUNCTION CreateNewWindow(oDlg1)
   ...
    nEvent := 0 
      DO WHILE nEvent <> xbeP_Close   // diese Ereignisschleife zieht !
         nEvent := AppEvent( @mp1, @mp2, @oXbp ) 
         oXbp:handleEvent( nEvent, mp1, mp2 ) 
      ENDDO 
RETURN
während des X oben rechts einen close-event auslöst, was die Fenster schön der Reihe nach schließt (hier hat die MSGBOX Zeit) wird im 2. Falle sofort der 2. Dialog zerstört, was automatisch auch den ersten ins nirwana schickt.

Grundsätzlich kann ich nur davon abraten, FUNCTION-CODE zu benutzen.
Außerdem soll man keine 2 Eventschleifen haben.
Ist es wirklich Absicht, dass das 2. Fenster in der Funktion Test(oDlg1,n)
stehen bleibt ?

Um den PushButton mit dem X-Button gleichzusetzen, muß man ihn den gleichen Event erzeugen lassen, also statt:

Code: Alles auswählen

oPB:activate := {||oDlg2:destroy()} 
muss man:

Code: Alles auswählen

oPB:activate := {|| postappevent(xbeP_Close)}
eingeben. Bei den Close sollte man auch nicht auf lokale Variablen referenzieren, da diese eigentlich zur Codeblockausführungszeit nicht mehr da sind. Sobald der Close-Event ausgelöst wird, gibt er als 3. Parameter das Fenster zurück, sodass man am besten definiert:

Code: Alles auswählen

oDlg2:close  := {|n1,n2,oXbp| oXbp:destroy()}
somit stimmt es immer.

Im Class-Code würde man für solche Verweise immer Instanzvariablen benutzen, diese sind solange verfügbar, wie das Objekt (Fenster etc.) da ist. Auch könnte man dann diese bei der postappevent() Steuerung genau benutzen, d.h. genau das gewünschte Fenster oder das gewünschte Kontroll angeben an das die Nachricht (event) gesendet werden soll.

Das alles funktioniert im function-Code nicht richtig.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

was mir noch auffällt:

Du gibst als parent und owner das Fenster selbst an, laut Handbuch muss dies jedoch die drawingarea sein !

Ich denke folgendes Programm verhält sich so, wie du es erwartet hast:

Code: Alles auswählen

#include "appevent.ch"
#include "xbp.ch"

PROCEDURE AppSys()
RETURN


PROCEDURE Main()
   LOCAL n := 1
   local oDlg1, oPB, nEvent, mp1:=NIL, mp2:=NIL, oXbp:=NIL

   set charset to ansi

   oDlg1         := XbpDialog():new( ,, {50,30}, {300,200} )
   oDlg1:title   := "Parent is Application Window"
   oDlg1:tasklist := .t.
   oDlg1:create()
   oDlg1:close := {|n1,n2,oXbp| oXbp:destroy()}

   oPB := XbpPushButton():new(oDlg1:drawingarea, , {10,10}, {80,25})
   oPB:caption := "Tester"
   oPB:create()
   oPB:activate := {|| Test(oDlg1, n)}

   nEvent := 0
   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      oXbp:handleEvent( nEvent, mp1, mp2 )
      // 2. Fenster wurde geschlossen
      if nEvent = xbeP_Close
         if oXbp = oDlg1
            msgbox("Programm ist zu Ende")
         else
            msgbox("CLOSE bei "+var2char(oXbp))
            nEvent := 0
         endif
      endif
   ENDDO
RETURN


FUNCTION Test(oDlg1,n)
   IF n == 1
      CreateNewWindow()
      MsgBox("Test - Fenster ist erzeugt.")
   ENDIF
RETURN nil


FUNCTION CreateNewWindow(oDlg1)
   local oDA, oDLG2, oPB
   oDlg2         := XbpDialog():new(oDlg1 ,oDlg1, {200,30}, {300,200} )
   oDlg2:title   := "Parent is Application Window"
   oDlg2:create()
   oDlg2:close := {|n1,n2,oXbp| oXbp:destroy()}

   oDA := oDlg2:drawingarea  // bei XbpDialog immer drawingarea angeben !!!!!

   oPB := XbpPushButton():new(oDA, , {10,10}, {80,25})
   oPB:caption := "Schließen"
   oPB:create()
   oPB:activate := {|u1,u2,oXbp| postappevent(xbeP_Close,,,;
                                          oXbp:SetParent():SetParent())}
RETURN nil
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag von AUGE_OHR »

hi,

Hubert hat ja nun eine "schöne" Lösung präsentiert.

Was mich allerdings wundert:
warum ist das "X" im "erzeugten" Fenster oben rechts "so klein" ?

gruss by OHR
Jimmy
JanR
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 129
Registriert: Di, 18. Okt 2005 14:44

Beitrag von JanR »

Vielen Dank Hubert und Jimmy.

Jetzt klappt es.


Grüsse,
Jan
Antworten