Seite 1 von 2

Frage zu Fenstern

Verfasst: 31.12.2011 19:07
von fabulouspaul
Hallo zuasammen,

ich habe ein Problem, mit dem ich nicht voran komme.
Aus einem geöffneten Hauptfenster (mit Menü und ein paar Gadgets) rufe ich eine Prozedur auf, die einige Zeit benötigt um irgendwelche Dinge zu tun. Um dem Benutzer eine visuelle Rückmeldung zu geben, lasse ich in einem 2. kleinen Fenster eine ProgressBar anzeigen.
Wenn man nun während die Progressbar läuft in eines der Fenster klickt (manchmal auch erst nach ein paar Mal), bleibt die ProgressBar stehen und in der Titelzeile des 2. Fensters erscheint "(Keine Rückmeldung)". Das Programm arbeitet im Hintergrund aber weiter und wenn es fertig ist, kehrt es auch ins Hauptfenster zurück.

Hier mal eine Kurzfassung des Codes um zu zeigen was ich meine:

Code: Alles auswählen

;**** Fenster-Test ***


; Fenster
Enumeration
  #Window_0
  #Window_1
EndEnumeration

; Menüs
Enumeration
  #MenuBar_0
  #MENU_3   ;öffnen
  #MENU_4   ;schliessen
  #MENU_5   ;ende
EndEnumeration

;Gadgets
Enumeration
  #Frame3D_0
  #Frame3D_2
  #ProgressBar
  #StatusBar
  #StatusText
  #Text_0
EndEnumeration

Procedure Open_Window_0()  ; Hauptfenster
  If OpenWindow(#Window_0, 216, 0, 800, 550, "Viewer",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
    If CreateMenu(#MenuBar_0, WindowID(#Window_0))
      MenuTitle("Datei")
      MenuItem(#MENU_3, "Arbeiten")
      MenuItem(#MENU_4, "Schliessen")
      MenuItem(#MENU_5, "Ende")
    EndIf
    
    If CreateStatusBar(#StatusBar, WindowID(#Window_0))
      AddStatusBarField(300)
      AddStatusBarField(480)
      StatusBarText(#StatusBar, 0, "Programmstart")
      StatusBarText(#StatusBar, 1, "", #PB_StatusBar_Right)
    EndIf
    
    If CreateGadgetList(WindowID(#Window_0))
      Frame3DGadget(#Frame3D_0, 190, 0, 610, 90, "Aufnahme-Daten")
      Frame3DGadget(#Frame3D_2, 190, 90, 605, 415, "Image") 
    EndIf
  EndIf
EndProcedure

Procedure Open_Window_1()  ; Progress-Bar
  If OpenWindow(#Window_1, 216, 0, 270, 70, "Fortschrittanzeige",#PB_Window_WindowCentered, WindowID(#Window_0))
    If CreateGadgetList(WindowID(#Window_1))
      ProgressBarGadget(#ProgressBar, 10, 40, 250, 20, 0, 100, #PB_ProgressBar_Smooth)
      TextGadget(#StatusText, 20, 10, 230, 20, "Statusinformation", #PB_Text_Center)
    EndIf
  EndIf
  StickyWindow(#Window_1,1)
EndProcedure

Procedure Arbeite()
  
  Protected i
  Protected j
  
  Open_Window_1()
  
  For j = 1 To 10
    For i = 0 To 100 Step 1
      SetGadgetState(#ProgressBar, i) 
      Delay(10)
    Next

    For i = 100 To 0 Step -1
      SetGadgetState(#ProgressBar, i) 
      Delay(10)
    Next i
  Next j
  
  CloseWindow(#Window_1)
EndProcedure

Open_Window_0()
StatusBarText(#StatusBar, 0, "")

Repeat                                  ; Schleife Hauptfenster
 
  Event = WaitWindowEvent()             ; auf Ereignis warten
  WindowID = EventWindow()              ; welches Fenster?
  GadgetID = EventGadget()              ; welches Gadget?
  EventType = EventType()               ; welches Ereignis

  If WindowID = #Window_0               ; im Hauptfenster ist was passiert...

    Select Event
      Case  #PB_Event_Menu              ; Menü wurde gewählt 
        Select EventMenu()              ; welches Menü?
          Case #MENU_3                  ;  -> Arbeiten
            MessageRequester("Info", "Menü: Arbeiten")
            Arbeite()
          Case #MENU_4                  ;  -> Schliessen
            MessageRequester("Info", "Menü: Schliessen")
          Case #MENU_5                  ;  -> Ende
            MessageRequester("Info", "Menü: Ende")
            Goto Ende
        EndSelect
        
      Case #PB_Event_Gadget             ; Gadget wurde gewählt
        ;....
    EndSelect
     
  EndIf
Until WindowID = #Window_0 And Event = #PB_Event_CloseWindow ; Fenster schliessen

ende:
CloseWindow(#Window_0)
End    
Was mache ich denn da falsch? Vermutlich ist es etwas Grundlegendes, aber ich komme nicht drauf.

In diesem Sinne... guten Rutsch!

Re: Frage zu Fenstern

Verfasst: 31.12.2011 19:22
von RSBasic
1. Bitte benutze keine Sprungmarken (Goto). Das ist nicht sehr sinnvoll.
2. Wenn du die neuste Version von PureBasic benutzt, kannst du die Zeile "CreateGadgetList()" entfernen, da diese Funktion veraltet ist und nicht mehr gebraucht wird, weil diese Gadget-Liste automatisch beim Erstellen eines Fensters erstellt wird.
3. Warum dein Fenster sich aufhängt, liegt daran, dass die Haupt-Eventschleife gestoppt wird. Und zwar durch das Aufrufen deiner Prozedur "Arbeite()". Solange deine Prozedur ausgeführt wird, kann dein Fenster auch keine weiteren Events empfangen. Aus dem Grund hängt sich das Fenster auf.
Da ich grad keine Zeit habe, kann ich dir leider auch kein Lösungscode posten.

Re: Frage zu Fenstern

Verfasst: 31.12.2011 19:50
von Waldixxl
Hallo fabulouspaul

Du musst dafür sorgen das die Events abgeholt werden.
Zu Beispiel mit

Code: Alles auswählen

Procedure RefreshWindows(Durchlauf = 15)
      For i = 1 To Durchlauf
     WindowEvent()
   Next   
EndProcedure
Einfach in der Schleife von Arbeiten aufrufen.

Code: Alles auswählen

For j = 1 To 10
    For i = 0 To 100 Step 1
      SetGadgetState(#ProgressBar, i)
      Delay(10)
      RefreshWindows()
    Next

    For i = 100 To 0 Step -1
      SetGadgetState(#ProgressBar, i)
      Delay(10)
      RefreshWindows()
    Next i
  Next j
Guten Rutsch
Walter

Re: Frage zu Fenstern

Verfasst: 31.12.2011 20:21
von Nino
Waldixxl hat geschrieben:Du musst dafür sorgen das die Events abgeholt werden.
Zu Beispiel mit

Code: Alles auswählen

Procedure RefreshWindows(Durchlauf = 15)
      For i = 1 To Durchlauf
     WindowEvent()
   Next   
EndProcedure
Wäre es nicht besser, alle noch in der Warteschlange befindlichen Ereignisse abzuarbeiten?

Code: Alles auswählen

Macro DoEvents
   While WindowEvent(): Wend
EndMacro
Als Alternative käme noch in Frage, den Hintergrundprozess in einem Thread auszuführen.

Allen einen Guten Rutsch wünscht
Nino

Re: Frage zu Fenstern

Verfasst: 21.01.2012 18:03
von fabulouspaul
Vielen Dank für die Hilfe!

Wie beschrieben hat es bereits geholfen, in der Arbeitsschleife regelmässig mal die Events abzuholen. :allright:

Re: Frage zu Fenstern

Verfasst: 21.01.2012 19:25
von ts-soft
fabulouspaul hat geschrieben:Wie beschrieben hat es bereits geholfen, in der Arbeitsschleife regelmässig mal die Events abzuholen. :allright:
Da damit aber nicht mehr auf die Eingaben des Benutzers reagiert wird / bzw. kann, sollte man alle Gadgets vorher disablen um den
Anwender nicht zur Weißglut anlaufen zu lassen!

Re: Frage zu Fenstern

Verfasst: 22.01.2012 15:31
von fabulouspaul
ts-soft hat geschrieben:
fabulouspaul hat geschrieben:Wie beschrieben hat es bereits geholfen, in der Arbeitsschleife regelmässig mal die Events abzuholen. :allright:
Da damit aber nicht mehr auf die Eingaben des Benutzers reagiert wird / bzw. kann, sollte man alle Gadgets vorher disablen um den
Anwender nicht zur Weißglut anlaufen zu lassen!
Guter Hinweis!
Das werde ich noch einbauen.

Re: Frage zu Fenstern

Verfasst: 10.02.2013 11:43
von ozoffi
Hallo!
Ihr habt auch mir mit diesem Beitrag sehr geholfen - danke!

Frage noch zum "Durchlauf": weshalb 15? Oder ist das unkritisch?

Re: Frage zu Fenstern

Verfasst: 10.02.2013 13:19
von HeX0R
ozoffi hat geschrieben:Frage noch zum "Durchlauf": weshalb 15? Oder ist das unkritisch?
Nimm die Lösung von Nino, das andere ist relativ untauglich.

Re: Frage zu Fenstern

Verfasst: 11.02.2013 13:35
von ozoffi
Hallo!
Beides probiert - die For - Next Schleife funktioniert ... der Macro nicht wirklich.