Seite 1 von 2

drei Fenster?

Verfasst: 07.04.2015 22:22
von kartmanne
HI,

bin erst seit paar Tagen mit PB unterwegs. Ic schreibe meine Projektchen als hobby. Erwartet also keine Expertenkenntnisse :-)

Meine erste Frage:
Ich habe ein Hauptfenster und lade zwei mit dem form-designer erstellte Fenster nach (includefile). Alle Gadgets des Projektes haben unterschiedliche Namen (obwohl der form-designer immer mit text_0, o.ä. beginnt, nenne ich die um).

Ich habe eine Hauptschleife im Hauptfenster. Dort nutze ich waitwindowevent. Durch Drücken eines buttons im Hauptfenster kann ich ein inkludiertes Fenster öffnen (vorher per iswindow die Existenz abgefragt, um doppeltes öffnen zu verhindern) und mit dessen ende-button auch schließen. In der Hauptschleife unterscheide ich die events zuerst mit eventwndow. Das geht auch mit dem zweiten Fenster.

Nach ein paar Mal die zwei zusätzlichen Fenster öffnen und Schließen, kann ich das zweite (und immer das zweite, das per eventwindow abgefragt wird) nicht mehr vollständig öffnen. Es erschenit wie ein Blitz und schließt wieder. Ich habe nach dem öffnen ein delay(1000) eingebaut und bemerke, dass es den einzigen button nicht mal erstellt, bevor˚s sich schließt.

Hat jemand eine Idee, warum das so ist? oder worauf ich achten muß?

Ich nutze die pb5.31demo.

Gruß
Manne

Re: drei Fenster?

Verfasst: 08.04.2015 05:58
von Imhotheb
Moin, etwas Code, z.B. der Event wo das Window geöffnet wird, wäre hilfreich ... so aus "dem Bauch" heraus würde ich sagen das sich einige Konstanten überschneiden, irgendwo ein Überlauf ist oder mit den Eventschleifen stimmt etwas nicht.
Vielleicht wissen die Anderen mehr.

Re: drei Fenster?

Verfasst: 08.04.2015 07:24
von Bisonte
Imhotheb hat geschrieben:Vielleicht wissen die Anderen mehr.
Ohne Code ? Unwahrscheinlich. In Delphi ist man sich dessen sicher ;)

Re: drei Fenster?

Verfasst: 08.04.2015 08:03
von Imhotheb
Bin ja selbst Anfänger ... deshalb wollte ich das lieber "Anderen" zuschieben ... hat wohl nicht so ganz funktioniert ^^

Am besten wäre natürlich ein lauffähiger Code, aber ohne wirds schwer

Re: drei Fenster?

Verfasst: 08.04.2015 09:51
von kartmanne
HI,

ja manchmal kennt jemand sowas und hat ein zwei Tips. OK. Ich hab den code soweit reduziert, wie's geht, damit's das wesentliche zeigt. Das Verhalten ist geblieben. Nach ein paar Öffnungen von "einstellungen" und "test", öffnet sich das Test-fenster nur blitzartzig und erstellt keinen button; das Einstellungen-fenster funktioniert bisher.

Schonmal Dank für's durchstöbern...

Programm-code:

Code: Alles auswählen

IncludeFile "Hauptdialog-db.pbf";
IncludeFile "Einstellungendialog-db.pbf"
IncludeFile "Testdialog-db.pbf"
OpenWindow_hd_0()
SetGadgetState(Combo_hd_0,0)
AddWindowTimer(Window_hd_0,1,200); für turnusmäßige COM-Abfrage

;***MAIN - Hauptschleife
Repeat
  event = WaitWindowEvent()
                           ;***windowevents auswerten 
  Select EventWindow() 
    Case Window_e_0 ;einstellungendialog
      Select event
        Case #PB_Event_Gadget
          Select EventGadget()
            Case Button_e_0 ;ende
              ende_e=1
          EndSelect
        Case #PB_Event_CloseWindow
          ende_e=1
        EndSelect
      
      If ende_e =1                         ; einstellungen beenden 
        CloseWindow(Window_e_0)
      EndIf
      
    Case Window_t_0;Testdialog
      Select event
        Case #PB_Event_Gadget
          Select EventGadget()
            Case Button_t_0 ;ende
              ende_t=1
          EndSelect
        Case #PB_Event_CloseWindow
          ende_t=1
          
      EndSelect
      If ende_t =1                         ; einstellungen beenden 
        CloseWindow(Window_t_0)
      EndIf
      
    Case Window_hd_0 ;hauptdialog
      Select event
        Case #PB_Event_Gadget ;buttons abfragen
          Select EventGadget()
                 Case Button7_hd_0 ; Test
              If IsWindow(Window_t_0)=0
                OpenWindow_t_0()
                ende_t=0 ;abbruch_variable für einstellungenfenster
              EndIf
            Case button8_hd_0 ; Einstellungen 
              If IsWindow(Window_e_0)=0 ; wenn fenster schon offen, nicht nochmal öffnen
                OpenWindow_e_0() 
                ende_e=0 ;abbruch_variable für einstellungenfenster 
              EndIf                                                                                         
          EndSelect
          
        Case #PB_Event_CloseWindow
          ende_hd=1
          
        Case #PB_Event_Timer
          If EventTimer()=1
            ;***Datenholen, turnusmäßig
           endif
      EndSelect
   
      If ende_hd=1 ;ende vorbereitet, jetzt Sicherheitsfenster abfragen
        ergebnis=MessageRequester("Beenden?","Möchten Sie ohne Speichern beenden?",#PB_MessageRequester_YesNo)
        If ergebnis=#PB_MessageRequester_Yes
          ende_hd=2
        Else
          ende_hd=0
        EndIf
      EndIf
      
  EndSelect 
  
Until Ende_hd=2 ; wirklich beenden
If IsSerialPort(0): CloseSerialPort(0): EndIf
End
Fenster-code(Einstellungendialog-db.pbf):

Code: Alles auswählen

Global Window_e_0
Global Button_e_0, Texte_0
Procedure OpenWindow_e_0(x = 0, y = 0, width = 616, height = 236)
  Window_e_0 = OpenWindow(#PB_Any, x, y, width, height, "v0.5", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Button_e_0 = ButtonGadget(#PB_Any, 532, 199, 70, 30, "Fertig")
  Texte_0 = TextGadget(#PB_Any, 190, 10, 100, 20, "Spul:")
EndProcedure
Fenster-code(Testdialog-db.pbf):

Code: Alles auswählen

Global Window_t_0
Global Textt_0, Button_t_0
Procedure OpenWindow_t_0(x = 0, y = 0, width = 600, height = 400)
  Window_t_0 = OpenWindow(#PB_Any, x, y, width, height, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Textt_0 = TextGadget(#PB_Any, 220, 190, 100, 25, "Ist noch nicht in Funktion")
  Button_t_0 = ButtonGadget(#PB_Any, 502, 359, 70, 30, "Fertig")
EndProcedure
Fenster-code(Hauptdialog-db.pbf):

Code: Alles auswählen

Global Window_hd_0
Global Button1_hd_0, Button7_hd_0, Button8_hd_0
Procedure OpenWindow_hd_0(x = 0, y = 0, width = 795, height = 600)
  Window_hd_0 = OpenWindow(#PB_Any, x, y, width, height, "Einstellungen", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Button1_hd_0 = ButtonGadget(#PB_Any, 684, 562, 100, 30, "Ende")
  Button7_hd_0 = ButtonGadget(#PB_Any, 684, 529, 100, 30, "Test")
  Button8_hd_0 = ButtonGadget(#PB_Any, 378, 562, 100, 30, "Einstellungen")
EndProcedure
_______________
formatiert -- A.

Re: drei Fenster?

Verfasst: 08.04.2015 10:17
von HeX0R
Das Problem hier ist die ziemlich unstrukturierte Schleife.

Grundsätzlich:
Schliesst Du ein dynamisch erstelltes Fenster (also eins mit #PB_Any) und öffnest ein neues, kann es sein, dass dieses neue Fenster die selbe Adresse zugewiesen bekommt, wie das zuvor geschlossene.
In Deinem Fall:
Du öffnest das Einstellungsfenster und Window_e_0 bekommt irgendeine Adresse zugewiesen.
Schliesst Du das nun, beinhaltet Window_e_0 natürlich immernoch diese Adresse, auch wenn das Fenster zu ist (ein IsWindow() würde fehlschlagen).
Nun öffnest Du Dein Test-Fenster und Window_t_0 bekommt die selbe Adresse (da das Einstellungsfenster ja zu ist, diese Adresse also wieder frei ist).
Window_t_0 ist nun = Window_e_0.

Einfacher ware es mit Konstanten zu arbeiten, dann brauchst Du Dir darüber keine Gedanken zu machen.

Oder aber du änderst Dein Eventhandling.
Z.B. diese ende_ Variablen entfernen und direkt bei Auftreten des Events entsprechend handeln.

Re: drei Fenster?

Verfasst: 08.04.2015 13:44
von kartmanne
HI,

Danke für's code formatieren ;-)

ok. Dass window_e_0 den Inhalt nicht ändert, leuchtet ein. Dann weise ich statt #pb_any eine Zahl zu. z.B. für jedes meiner Fenster 1,2 und 3. Oder sollte das anders geschehen?

Ich habe mal die iswindow() durch die Abfrage der Variablen ende_e (analog auch ende_t) ersetzt. Diese var spiegelt ja quasi der Status "fenster aufgebaut oder geschlossen)

Code: Alles auswählen

If ende_e=1 ; wenn fenster schon offen(=0), nicht nochmal öffnen
                OpenWindow_e_0() 
                ende_e=0 ;abbruch_variable für einstellungenfenster 
                SetGadgetText(ladezeit_e,Str(ladezeit*250)) 
                SetGadgetText(zylinderzahl_e,Str(zylinderzahl)) 
              EndIf 
Kein Unterschied im Verhalten des test-Fensters.

Das handle Window_e_0 wird ja neu belegt (#pb_any), wenn das Fenster eröffnet wird. Abgefragt wird das handle nur, wenn das Fenster einen event erzeugt hat, sonst nicht. Also kann es m.E. nach obiger code-Anpassung bei #pb_any bleiben - oder nicht?

Für das struktiurierte handling (ende_e weglassen) fällt mir derzeit nix deutlilch struktutierteres und kürzeres ein. Haste einen Denkanstoß? Vielleicht hab das Handhaben der events und #pb_xyz noch nicht gut verinnerlicht. Ich hab mich halt durch die Hilfe ge-klickt und die Beispiele benutzt.

Re: drei Fenster?

Verfasst: 08.04.2015 14:17
von Imhotheb
ich mache das immer ungefähr so ...

Code: Alles auswählen

declare close()

Enumerate Windows
#Win1
#Win2
#Win3
endenumerate

OpenWindow(#Win1, ...)
OpenWindow(#Win2,...)
...

Repeat

if ende
  close()
endif

forever

procedure Close()
   Abfrage
   End
endprocedure 
sry, vom Handy ist etwas beschränkt zu schreiben, hoffe du verstehst was ich meine

Re: drei Fenster?

Verfasst: 08.04.2015 16:30
von HeX0R
So in der Art würde ich das vorschlagen:

Code: Alles auswählen

IncludeFile "Hauptdialog-db.pbf";
IncludeFile "Einstellungendialog-db.pbf"
IncludeFile "Testdialog-db.pbf"


OpenWindow_hd_0()
;SetGadgetState(Combo_hd_0,0)
AddWindowTimer(Window_hd_0,1,200); für turnusmäßige COM-Abfrage

;***MAIN - Hauptschleife
Repeat
	;***windowevents auswerten
	Select WaitWindowEvent()
		Case #PB_Event_Gadget
			Select EventGadget()
				Case Button_t_0 ;ende
					CloseWindow(Window_t_0)
					Window_t_0 = 0
				Case Button_e_0 ;ende
					CloseWindow(Window_e_0)
					Window_e_0 = 0
				Case Button7_hd_0 ; Test
					If Window_t_0 = 0
						OpenWindow_t_0()
					EndIf
				Case button8_hd_0 ; Einstellungen 
					If Window_e_0 = 0 ; wenn fenster schon offen, nicht nochmal öffnen
						OpenWindow_e_0() 
					EndIf
				Case Button1_hd_0
					Break
			EndSelect
		Case #PB_Event_CloseWindow
			Select EventWindow()
				Case Window_t_0
					CloseWindow(Window_t_0)
					Window_t_0 = 0
				Case Window_e_0
					CloseWindow(Window_e_0)
					Window_e_0 = 0
				Case Window_hd_0
					Break
			EndSelect
		Case #PB_Event_Timer
			If EventTimer()=1
				;***Datenholen, turnusmäßig
			EndIf
	EndSelect
ForEver

If IsSerialPort(0): CloseSerialPort(0): EndIf
End
Aber eigentlich würde ich es eher mit Konstanten machen, also so wie Imhotheb.
Dynamische Gadgets/Fenster verwende ich nur da, wo sie Sinn machen, wo Fenster also dynamisch erweitert werden.

Re: drei Fenster?

Verfasst: 08.04.2015 19:10
von kartmanne
HI,

danke ihr beiden. :allright:

@HeX0R:
ja, das sieht sehr "schlank" aus. Allerdings ist mein obiger code extrem eingekürzt, um möglicherweise den Wurm zu entdecken. Ich habe in den Fenstern bis zu ca. 50 gadgets, auch Text-Gadgets, die verändert werden können und werden (wenn die COM Daten liefert). Insoweit ist mir eine Struktur, die die Aktionen der Fenster "clustert" übersichtlicher, als wenn ich die "eventtypen" clustere.

Aus Schleifen per break rausspringen... sowas mag ich nicht. Ich mag auch das basic-typische Goto nicht (benutze es nur, um bei der Fehlersuche zeitweise große code-Blöcke inaktiv zu setzten).

Ein paar Anregungen habe ich gesehen und werde sie beherzigen.

Aber... ich hab immer noch nicht erkannt, warum mein code das Verhalten des Testfensters provoziert... :?