drei Fenster?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
kartmanne
Beiträge: 108
Registriert: 19.03.2015 18:16
Wohnort: Altenstadt
Kontaktdaten:

drei Fenster?

Beitrag 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
Benutzeravatar
Imhotheb
Beiträge: 192
Registriert: 10.10.2014 13:14
Computerausstattung: Intel 8086, 640 KB RAM, Hercules Video Adapter, 2 x 5 1/4" 360kb Floppy, MS-DOS 3
Wohnort: Wolfenbüttel

Re: drei Fenster?

Beitrag 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.
weil einfach einfach einfach ist ... mach' ich es anders
Benutzeravatar
Bisonte
Beiträge: 2468
Registriert: 01.04.2007 20:18

Re: drei Fenster?

Beitrag von Bisonte »

Imhotheb hat geschrieben:Vielleicht wissen die Anderen mehr.
Ohne Code ? Unwahrscheinlich. In Delphi ist man sich dessen sicher ;)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
Imhotheb
Beiträge: 192
Registriert: 10.10.2014 13:14
Computerausstattung: Intel 8086, 640 KB RAM, Hercules Video Adapter, 2 x 5 1/4" 360kb Floppy, MS-DOS 3
Wohnort: Wolfenbüttel

Re: drei Fenster?

Beitrag 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
Zuletzt geändert von Imhotheb am 08.04.2015 09:59, insgesamt 1-mal geändert.
weil einfach einfach einfach ist ... mach' ich es anders
Benutzeravatar
kartmanne
Beiträge: 108
Registriert: 19.03.2015 18:16
Wohnort: Altenstadt
Kontaktdaten:

Re: drei Fenster?

Beitrag 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.
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: drei Fenster?

Beitrag 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.
Benutzeravatar
kartmanne
Beiträge: 108
Registriert: 19.03.2015 18:16
Wohnort: Altenstadt
Kontaktdaten:

Re: drei Fenster?

Beitrag 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.
Benutzeravatar
Imhotheb
Beiträge: 192
Registriert: 10.10.2014 13:14
Computerausstattung: Intel 8086, 640 KB RAM, Hercules Video Adapter, 2 x 5 1/4" 360kb Floppy, MS-DOS 3
Wohnort: Wolfenbüttel

Re: drei Fenster?

Beitrag 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
weil einfach einfach einfach ist ... mach' ich es anders
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: drei Fenster?

Beitrag 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.
Benutzeravatar
kartmanne
Beiträge: 108
Registriert: 19.03.2015 18:16
Wohnort: Altenstadt
Kontaktdaten:

Re: drei Fenster?

Beitrag 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... :?
Antworten