Fehler im Code

Anfängerfragen zum Programmieren mit PureBasic.
dietmar
Beiträge: 97
Registriert: 19.09.2005 19:11
Wohnort: Zuhause

Fehler im Code

Beitrag von dietmar »

Hallo alle miteinander,

ich hab mir mit dem Formdesigner drei Fenster erstellt, diese verbinde ich in einer Datei zu dem untenstehenden Code, ich möchte in Fenster in dem es mehrer Buttons gibt. Wird einer der Knöpfe gedrückt soll sich ein Fenster öffnen. Die Fenster zwei und drei bekommen unterschiedliche Nummern, solange ich diese gleichzeitig geöffnet habe.
Mein Problem ist das wenn ich Fenster zwei öffne und schließe und anschließend Fenster drei öffne bekommt es die selbe Nummer zugewiesen wie Fenster zwei. Füge ich ein window_x = 0 hinter closeWindow(Window_x) geht es auch wieder.

Code: Alles auswählen

Global Window_1, Window_2, Window_3

Global Button_0, Button_1

Procedure OpenWindow_1(x = 0, y = 0, width = 600, height = 400)
  Window_1 = OpenWindow(#PB_Any, x, y, width, height, "Fenster_1", #PB_Window_SystemMenu)
  Button_0 = ButtonGadget(#PB_Any, 20, 10, 100, 25, "Fenster_2")
  Button_1 = ButtonGadget(#PB_Any, 20, 50, 100, 25, "Fenster_3")
EndProcedure

Procedure OpenWindow_2(x = 0, y = 0, width = 600, height = 400)
  Window_2 = OpenWindow(#PB_Any, x, y, width, height, "Fenster_2", #PB_Window_SystemMenu)
EndProcedure

Procedure OpenWindow_3(x = 0, y = 0, width = 600, height = 400)
  Window_3 = OpenWindow(#PB_Any, x, y, width, height, "Fenster_3", #PB_Window_SystemMenu)
EndProcedure

openwindow_1()

Procedure Hauptschleife (Event)
  Debug "Fenster 1: " + Window_1
  Debug "Fenster 2: " + Window_2
  Debug "Fenster 3: " + Window_3
  
  
  Select EventWindow()
    Case Window_1
      Select event  
        Case #PB_Event_Gadget
          Select EventGadget()
            Case Button_0
              OpenWindow_2()
            Case Button_1
              OpenWindow_3()
          EndSelect
        Case #PB_Event_CloseWindow
          CloseWindow(Window_1)
          window_1 = 0
          Exit = #True
      EndSelect
    Case Window_2
      Select event  
        Case #PB_Event_CloseWindow
          
          CloseWindow(Window_2)
      EndSelect
    Case Window_3
      Select event  
        Case #PB_Event_CloseWindow
          CloseWindow(Window_3)
      EndSelect
  EndSelect
  ProcedureReturn Exit
EndProcedure

Exit = #False

Repeat
  Exit = Hauptschleife(WaitWindowEvent())
Until Exit = #True

End
Danke und Gruß
Dietmar
Wir leben alle unter dem gleichen Sternenhimmel, aber wir haben nicht alle den gleichen Horizont.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Fehler im Code

Beitrag von ts-soft »

Das einzige Problem was ich sehe, was auch im Bug-Thread angesprochen wurde, beim Button-Klick wird ein neues Fenster
geöffnet, das die globale Variable des noch geöffneten Fensters überschreibt, für dieses Fenster steht keine ID mehr zur Verfügung und es reagiert deshalb im Event-Loop auch nicht mehr.
Korrigierter Code:

Code: Alles auswählen

Global Window_1, Window_2, Window_3

Global Button_0, Button_1

Procedure OpenWindow_1(x = 0, y = 0, width = 600, height = 400)
  Window_1 = OpenWindow(#PB_Any, x, y, width, height, "Fenster_1", #PB_Window_SystemMenu)
  Button_0 = ButtonGadget(#PB_Any, 20, 10, 100, 25, "Fenster_2")
  Button_1 = ButtonGadget(#PB_Any, 20, 50, 100, 25, "Fenster_3")
EndProcedure

Procedure OpenWindow_2(x = 0, y = 0, width = 600, height = 400)
  Window_2 = OpenWindow(#PB_Any, x, y, width, height, "Fenster_2", #PB_Window_SystemMenu)
EndProcedure

Procedure OpenWindow_3(x = 0, y = 0, width = 600, height = 400)
  Window_3 = OpenWindow(#PB_Any, x, y, width, height, "Fenster_3", #PB_Window_SystemMenu)
EndProcedure

openwindow_1()

Procedure Hauptschleife (Event)
  Debug "Fenster 1: " + Window_1
  Debug "Fenster 2: " + Window_2
  Debug "Fenster 3: " + Window_3
 
 
  Select EventWindow()
    Case Window_1
      Select event 
        Case #PB_Event_Gadget
          Select EventGadget()
            Case Button_0
              If IsWindow(Window_2)
                CloseWindow(Window_2)
              EndIf
              OpenWindow_2()
            Case Button_1
              If IsWindow(Window_3)
                CloseWindow(Window_3)
              EndIf
              OpenWindow_3()
          EndSelect
        Case #PB_Event_CloseWindow
          CloseWindow(Window_1)
          window_1 = 0
          Exit = #True
      EndSelect
    Case Window_2
      Select event 
        Case #PB_Event_CloseWindow
         
          CloseWindow(Window_2)
      EndSelect
    Case Window_3
      Select event 
        Case #PB_Event_CloseWindow
          CloseWindow(Window_3)
      EndSelect
  EndSelect
  ProcedureReturn Exit
EndProcedure

Exit = #False

Repeat
  Exit = Hauptschleife(WaitWindowEvent())
Until Exit = #True

End
Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Fehler im Code

Beitrag von STARGÅTE »

Das ist logisch.

#PB_Any erzeugt/gibt eine Nummer aus einem Pool von Zahlen (in wirklichkeit Speicherpositionen der internen PB-Objektverwaltung) zurück.

Solange diese Nummer besetzt ist, wird für ein anderes Fenster eben eine neue Nummer gesucht.
Aber wenn du das Fenster 2 schießt, verliert die Nummer auch ihre gültigkeit und wird frei, sodass Fenster 3 diese nummer selbst nutzen kann, wenn es geöffnet wird.

Lösungsvorschlag:

Öffne sofort alle Fenster und lasse sie offen. Danach kannst du mit HideWindow() alle anderen Fenster verstecken.
Bei den Buttons wird dann kein OpenWindow_2() aufgerufen, sondern HideWindow(Window_2, #False).
Beim schließen der Fenster das selbe, kein Close, sondern ein HideWindow(Window_2, #True).
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
matbal
Beiträge: 261
Registriert: 30.03.2011 20:53

Re: Fehler im Code

Beitrag von matbal »

dietmar hat geschrieben:Mein Problem ist das wenn ich Fenster zwei öffne und schließe und anschließend Fenster drei öffne bekommt es die selbe Nummer zugewiesen wie Fenster zwei. Füge ich ein window_x = 0 hinter closeWindow(Window_x) geht es auch wieder.
Ich sehe kein Problem. Wenn das Fenster geschlossen ist, ist die PB-Nummer wieder frei und kann für das andere Fenster verwendet werden.

Ich habe auch mal mit dem FormDesigner und den dynamischen PB-Nummern herumgespielt. Eigentlich hatte ich nach einer Lösung gesucht, dynamische Fenster mit dem FormDesigner zu erstellen. Und es sollen alle Funktionen, die im PBF-Dateien und dem Designer möglich sind, weiter funktionieren. (Ereignis-Procedure, resizen der Gadgets).

Ich habe das Test-Programm so erweitert, daß ich die vergebenen PB-Nummer sehe. Man kann da gut sehen, daß oft die gleichen Nummern wieder verteilt werden (4 bis 5 Nummern der zuletzt geschlossenen Fenster werden bei mir meistens wieder verwendet).

Ich habe den Code (3 Dateien) als ZIP: subwin.zip
dietmar
Beiträge: 97
Registriert: 19.09.2005 19:11
Wohnort: Zuhause

Re: Fehler im Code

Beitrag von dietmar »

Nur noch am Rande für mich zum Verständnis, bei den Gadgets verhält es sich bestimmt ähnlich. Diese bekommen innerhalb des Fensteraufrufs eine unterschiedliche Nummer? Es können aber in unterschiedlichen Fenstern die gleiche Nummer für Gadgets vergeben werden, weil im zuerst das Fenster abgefragt wird und dann erst nach dem Gadget das ein Event auslöst?
Wir leben alle unter dem gleichen Sternenhimmel, aber wir haben nicht alle den gleichen Horizont.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Fehler im Code

Beitrag von ts-soft »

Nein, die ID, eines jedem gleichem Objekttyps (siehe Hilfe), muß immer, im gesamtem Programm, eindeutig sein!

Bei statischen IDs, wird durch erneutes verwenden derselben ID, das vorherige Objekt
automatisch freigegeben, bei dynamischen IDs nicht (wäre ja auch gar nicht möglich :wink: )

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten