WaitWindowEvent() und herausfinden ob Thread beendet wurde??

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
nco2k
Beiträge: 892
Registriert: 08.09.2004 23:13

WaitWindowEvent() und herausfinden ob Thread beendet wurde??

Beitrag von nco2k »

hi folks,

jetzt hat es auch mich erwischt. :D

wie kann ich am besten herausfinden, ob mein thread beendet wurde??

ich habe das jetzt mal so gelöst:

Code: Alles auswählen

Global ThreadEnd.l

Procedure Thread()
  ThreadEnd = #False
  ;tue dies tue jenes...
  ThreadEnd = #True
EndProcedure

#Title = "TEST"
If OpenWindow(0, 0, 0, 480, 320, #PB_Window_TitleBar | #PB_Window_SystemMenu | #PB_Window_ScreenCentered, #Title)
  
  If CreateThread(@Thread(), 0)
    
    Repeat
      WinEvent.l = WaitWindowEvent()
      If WinEvent = #PB_Event_CloseWindow
        Break
      EndIf
    Until ThreadEnd = #True
    
    If ThreadEnd = #True
      MessageRequester(#Title, "Programm wurde NACH dem ThreadEnd beendet!")
    Else
      MessageRequester(#Title, "Programm wurde VOR dem ThreadEnd beendet!")
    EndIf
    
  EndIf
  
EndIf

End
das problem dabei ist jedoch, dass ein WindowEvent geschehen muss damit das programm die variable ThreadEnd überprüfen kann. aus diversen gründen kann ich leider in meinem progamm WindowEvent() anstelle von WaitWindowEvent() nicht benützen.

c ya,
nco2k
~|__/
..o.o.. <--- This is Einkaufswagen. Copy Einkaufswagen into your signature to help him on his way to world domination.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: WaitWindowEvent() und herausfinden ob Thread beendet wur

Beitrag von Kiffi »

> wie kann ich am besten herausfinden, ob mein thread beendet wurde??

Nur so 'ne Idee: Wenn der Thread beendet wird, sendest Du mit PostMessage
eine entsprechende Meldung an Dein Programm, die Du dann in einem
CallBack auswerten kannst.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
nco2k
Beiträge: 892
Registriert: 08.09.2004 23:13

Beitrag von nco2k »

@Kiffi
hab ich mir auch schon überlegt, dass problem dabei ist, dass ich das fenster noch für andere zwecke später benötige und dort einen eigenen callback dafür anlege. jetzt weiss ich nicht, ob dann der erste callback vom neuen später überschrieben wird?!

-> öffne fenster
-> setze callback
-> waitwindowevent
-> modifiziere fenster
-> setze callback

c ya,
nco2k
~|__/
..o.o.. <--- This is Einkaufswagen. Copy Einkaufswagen into your signature to help him on his way to world domination.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

> jetzt weiss ich nicht, ob dann der erste callback vom neuen später
> überschrieben wird?!

wieso überschreiben? Du benötigst doch nur einen CallBack, weil Du im
CallBack doch eine Unterscheidung der Messages machst, oder?

Code: Alles auswählen

#ThreadEnd = #wm_user+1

[...]

Procedure CallBack(WindowID, Message, wParam, lParam)
  
  Result = #PB_ProcessPureBasicEvents
  ;
  Select Message
    
    Case #WM_LBUTTONDOWN 

    Case ...
      
    Case #ThreadEnd 
       ; Der Thread ist beendet
      
  EndSelect
  
  ProcedureReturn Result
  
EndProcedure

[...]

Procedure Thread()
  ;tue dies tue jenes...
  PostMessage_(DeinFenster, #ThreadEnd, 0, 0)
EndProcedure 

so, oder so ähnlich.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
nco2k
Beiträge: 892
Registriert: 08.09.2004 23:13

Beitrag von nco2k »

@Kiffi
wieso überschreiben? Du benötigst doch nur einen CallBack, weil Du im CallBack doch eine Unterscheidung der Messages machst, oder?
ja nur, dass ich diese unterscheidung da noch nicht brauche, sondern erst später nachdem der thread endet und das fenster modifiziert wurde. ich weiss nicht wieso ich schon am anfang ein callback setzen soll, welcher auf messages prüft, die erst später benötigt werden und eventuel noch garnicht zurückgegeben werden können bzw. nicht ausgelöst werden dürfen. dann müsste ich bei den überprüfungen, die später erst benötigt werden auch das If ThreadEnd = #True im callback anhängen. :| deswegen dachte ich an zwei callbacks. im ersten callback prüfe ich nur auf das ThreadEnd mehr brauch ich da auch nicht, dann im zweiten welcher den ersten überschreibt, auf das ganze andere zeug was ich da noch so brauche. fühlst du wie ich denk?? :mrgreen:

p.s.: sieht so aus als ob callbacks überschrieben/ersetzt werden können.

//EDIT1:

Code: Alles auswählen

Global ThreadEnd.l

Procedure Thread()
  ;tue dies tue jenes...
  ThreadEnd = #True
  SendMessage_(WindowID(0), #WM_USER+1, 0, 0)
EndProcedure

Procedure WinCallback(hwnd, msg, wParam, lParam)
  Select msg
    Case #WM_USER+1
      ;wie verlasse ich nun die WaitWindowEvent Schleife??
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure  

#Title = "TEST"
If OpenWindow(0, 0, 0, 480, 320, #PB_Window_TitleBar | #PB_Window_SystemMenu | #PB_Window_ScreenCentered, #Title)
  
  If SetWindowCallback(@WinCallback())
    
    If CreateThread(@Thread(), 0)
      
      Repeat
        WinEvent.l = WaitWindowEvent()
        If WinEvent = #PB_Event_CloseWindow
          Break
        EndIf
      ForEver
      
      If ThreadEnd = #True
        MessageRequester(#Title, "Programm wurde NACH dem ThreadEnd beendet!")
      Else
        MessageRequester(#Title, "Programm wurde VOR dem ThreadEnd beendet!")
      EndIf
      
    EndIf
      
  EndIf
  
EndIf

End
tja nur wie verlasse ich jetzt die WaitWindowEvent schleife?? dann könnte ich es doch gleich so machen:

Code: Alles auswählen

Global ThreadEnd.l

Procedure Thread()
  ;tue dies tue jenes...
  ThreadEnd = #True
  ResizeWindow(WindowWidth() + 1, WindowHeight() + 1)
EndProcedure

#Title = "TEST"
If OpenWindow(0, 0, 0, 480, 320, #PB_Window_TitleBar | #PB_Window_SystemMenu | #PB_Window_ScreenCentered, #Title)
  
  If CreateThread(@Thread(), 0)
    
    Repeat
      WinEvent.l = WaitWindowEvent()
      If WinEvent = #PB_Event_SizeWindow
        If ThreadEnd = #True
          Break
        EndIf
      ElseIf WinEvent = #PB_Event_CloseWindow
        Break
      EndIf
    ForEver
    
    If ThreadEnd = #True
      MessageRequester(#Title, "Programm wurde NACH dem ThreadEnd beendet!")
    Else
      MessageRequester(#Title, "Programm wurde VOR dem ThreadEnd beendet!")
    EndIf
    
  EndIf
  
EndIf

End
//EDIT2:

arghs, du hast natürlich recht... mit PostMessage_() gehts. :oops:

Code: Alles auswählen

#Title = "Thread-Test"

Procedure Thread()
  ;do stuff...
  MessageRequester(#Title, "a hello from our Thread")
  ;end thread...
  PostMessage_(WindowID(0), #WM_USER+1, 0, 0)
EndProcedure

If OpenWindow(0, 0, 0, 480, 320, #PB_Window_TitleBar | #PB_Window_SystemMenu | #PB_Window_ScreenCentered, #Title)
  
  If CreateThread(@Thread(), 0)
    
    Repeat
      WinEvent.l = WaitWindowEvent()
      Select WinEvent
        Case #WM_USER+1
          ThreadEnd.l = #True
          Break
        Case #PB_Event_CloseWindow
          WindowEnd.l = #True
          Break
      EndSelect
    ForEver
    
    If WindowEnd = #False And ThreadEnd = #True
      MessageRequester(#Title, "App was closed AFTER the Thread has finished")
    Else
      MessageRequester(#Title, "App was closed BEFORE the Thread could finished")
    EndIf
    
  EndIf
  
EndIf

End
danke! :allright:

c ya,
nco2k
~|__/
..o.o.. <--- This is Einkaufswagen. Copy Einkaufswagen into your signature to help him on his way to world domination.
Antworten