Ich wuerde es so machen :
Code: Alles auswählen
ImportC "msvcrt.lib"
_beginthread(proc,stack_size,param)
EndImport
Structure event
event.l
hwnd.l
job.l
EndStructure
#WM_JOB_DONE = #WM_USER
#WM_JOB_ABORT = #WM_USER + 1
#JOB_NORMAL = 0
#JOB_ABORT = 1
Procedure Thread(*ev.event)
While 1
;THREAD WARTET BIS SETEVENT AUFGRUFEN WURDE
WaitForSingleObject_(*ev\event,#INFINITE)
; JOB ANFANG
For i = 0 To 999
If *ev\job = #JOB_ABORT: Break : EndIf ; WAEHREND DES JOBS AUF ABBRUCH PRUEFEN
SetGadgetState(1,i)
Delay(2)
Next
; JOB ENDE
; FENSTER MITTEILEN OB DER JOB ABGEBROCHEN ODER NORMAL BEENDET WURDE
If i = 1000
PostMessage_(*ev\hwnd,#WM_JOB_DONE,0,0)
Else
PostMessage_(*ev\hwnd,#WM_JOB_ABORT,0,0)
EndIf
; ZURUECKSETZEN
*ev\job = #JOB_NORMAL
Wend
EndProcedure
Procedure Progress()
hwnd = OpenWindow(1,#PB_Ignore,#PB_Ignore,200,100,"Progress Test",#PB_Window_WindowCentered,WindowID(0))
CreateGadgetList(hwnd)
ProgressBarGadget(1,10,10,180,20,0,1000)
ButtonGadget(2,60,50,75,23,"Stop")
DisableWindow(0,1)
EndProcedure
Procedure Main()
Protected hwnd
Protected ev.event
Protected thread
hwnd = OpenWindow(0,#PB_Ignore,#PB_Ignore,430,150,"Thread Test")
CreateGadgetList(hwnd)
ButtonGadget(0,20,20,75,23,"start")
TextGadget(3,20,50,75,23,"Status : ")
; EVENT ERZEUGEN
ev\event = CreateEvent_(0,0,0,0)
; MESSAGE FENSTER SETZEN
ev\hwnd = hwnd
; THREAD STARTEN
_beginthread(@Thread(),0,@ev)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case 0
Progress()
SetGadgetText(3,"Status : run")
; THREAD MITTEILEN DAS ER NUN STARTEN KANN
SetEvent_(ev\event)
Case 2
; THREAD MITTEILEN DAS ER STOPPEN KANN
ev\job = #JOB_ABORT
EndSelect
Case #WM_JOB_DONE
SetGadgetText(3,"Status : done")
DisableWindow(0,0)
CloseWindow(1)
Case #WM_JOB_ABORT
SetGadgetText(3,"Status : abort")
DisableWindow(0,0)
CloseWindow(1)
Case #PB_Event_CloseWindow
CloseHandle_(ev\event)
Break
EndSelect
ForEver
EndProcedure:Main()
Sieht etwas komplex aus, ist aber eigentlich sehr einfach.
Der Thread wird gleich zu beginn gestartet und mit
WaitForSingleObject "geparkt". Sobald man nun mit SetEvent,
das vorher erzeugte, Event feuert, startet die eigentliche Arbeit
in dem Thread. WaitForSingleObject ist in etwa mit WaitWindowEvent
zu vergleichen. Sie machen so lange nichts bis etwas ankommt.
Ausserdem kann man so den Thread von aussen leicht steuern und
es wird keine extra CPU Zeit benoetigt.
Das Idee stammt aus dem Buch "Windows Programmierung" von Petzold.