Hallo,
gibt es irgendeinen Trick, um bei einem Aufruf wie
BindGadgetEvent(#Gadget, @Callback() [, EventTyp])
an Callback Werte (außer den Eventeigenschaften) zu übergeben?
Kann man vielleicht dazu die Eventeigenschaften umfunktionieren?
Parameterübergabe bei BindGadgetEvent möglich?
- ProgOldie
- Beiträge: 236
- Registriert: 19.05.2012 17:09
- Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02
Parameterübergabe bei BindGadgetEvent möglich?
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Re: Parameterübergabe bei BindGadgetEvent möglich?
Mit mit BindGadgetEvent habe ich das noch nicht ausprobiert, aber mit BindEvent.
Dazu gibt es EventData(). Diese sind aber nur gültig bei Verwendung eines benutzerdefinierten Ereignisses.
Hier mal ein Beispiel was aber irgendwann zu einen Speicherfehler führen kann
da der Thread eventuell schon beendet ist, bevor die String gelesen wurden.
Dazu habe ich irgendwann mal SendEvent geschrieben. Dieser warte so lange bis die Nachricht verarbeitet wurde. (DispatchEvent)
Dazu gibt es EventData(). Diese sind aber nur gültig bei Verwendung eines benutzerdefinierten Ereignisses.
Hier mal ein Beispiel was aber irgendwann zu einen Speicherfehler führen kann
da der Thread eventuell schon beendet ist, bevor die String gelesen wurden.
Code: Alles auswählen
; Alle unsere beutzerdefinierten Ereignisse
Enumeration #PB_Event_FirstCustomValue
#EventBeginProcessing
#EventProcessingFinished
EndEnumeration
Procedure Thread(Value)
Protected data1.s, data2.s
data1.s = "Thread begin processing"
data2.s = "Thread processing finished"
PostEvent(#EventBeginProcessing, 0 ,0, 0, @Data1)
Delay(3000)
PostEvent(#EventProcessingFinished, 0 ,0, 0, @Data2)
Delay(1000)
EndProcedure
Procedure MyBind()
Debug PeekS(EventData())
EndProcedure
OpenWindow(0, 200, 200, 100, 100, "PostEvent")
BindEvent(#EventBeginProcessing, @MyBind())
BindEvent(#EventProcessingFinished, @MyBind())
CreateThread(@Thread(), 0)
Repeat
Event = WaitWindowEvent()
Select Event
; Case #EventBeginProcessing
; Debug "Thread begin processing "
;
; Case #EventProcessingFinished
; Debug "Thread processing finished"
EndSelect
Until Event = #PB_Event_CloseWindow
Code: Alles auswählen
; ***************************************************************************************
;-TOP
; Comment : SendEvent
; Author : mk-soft
; Version : v1.05
;- Structure
Structure udtSendEvent
Signal.i
Result.i
*pData
EndStructure
; ---------------------------------------------------------------------------------------
Procedure SendEvent(Event, Window = 0, Object = 0, EventType = 0, pData = 0, Semaphore = 0)
Protected MyEvent.udtSendEvent, result
With MyEvent
If Semaphore
\Signal = Semaphore
Else
\Signal = CreateSemaphore()
EndIf
\pData = pData
PostEvent(Event, Window, Object, EventType, @MyEvent)
WaitSemaphore(\Signal)
result = \Result
If Semaphore = 0
FreeSemaphore(\Signal)
EndIf
EndWith
ProcedureReturn result
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure SendEventData(*MyEvent.udtSendEvent)
ProcedureReturn *MyEvent\pData
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure DispatchEvent(*MyEvent.udtSendEvent, result)
*MyEvent\Result = result
SignalSemaphore(*MyEvent\Signal)
EndProcedure
; ***************************************************************************************
;- Test
Enumeration
#Window
EndEnumeration
;- Constants
Enumeration #PB_Event_FirstCustomValue
#My_Event_Question
EndEnumeration
; Thread
Procedure Test(Null)
Protected result
Debug "Init Thread"
Repeat
Delay(500)
result = SendEvent(#My_Event_Question, 0, 0, 0, Random(100))
Select result
Case #PB_MessageRequester_Yes
Debug "Antwort Ja"
Case #PB_MessageRequester_No
Debug "Antwort Nein"
Case #PB_MessageRequester_Cancel
Debug "Antwort Abbrechen"
EndSelect
Until result = #PB_MessageRequester_Cancel
Debug "Exit Thread"
EndProcedure
; BindEvent
Procedure MyEvent()
Protected MyEvent
MyEvent = EventData()
Value = SendEventData(MyEvent)
Debug "Es kommt ein SendEvent: " + Str(Value)
result = MessageRequester("Frage", "Wie soll es weiter gehen?", #PB_MessageRequester_YesNoCancel)
DispatchEvent(MyEvent, result)
EndProcedure
If OpenWindow(#Window, 0, 0, 800, 600, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
BindEvent(#My_Event_Question, @MyEvent())
hThread = CreateThread(@Test(), #Null)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
exit = 1
Case #PB_Event_Gadget
EndSelect
Until exit
If IsThread(hThread)
Debug "Thread läuft"
KillThread(hThread)
EndIf
EndIf
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Parameterübergabe bei BindGadgetEvent möglich?
Geht auch mit BindGadgetEvent...
P.S. Beispiel geändert...
Beispiel mit übergabe eines Zeigers auf Daten
P.S. Beispiel geändert...
Code: Alles auswählen
; ***************************************************************************************
;-TOP
; Comment : SendEvent
; Author : mk-soft
; Version : v1.05
;- Structure
Structure udtSendEvent
Signal.i
Result.i
*pData
EndStructure
; ---------------------------------------------------------------------------------------
Procedure SendEvent(Event, Window = 0, Object = 0, EventType = 0, pData = 0, Semaphore = 0)
Protected MyEvent.udtSendEvent, result
With MyEvent
If Semaphore
\Signal = Semaphore
Else
\Signal = CreateSemaphore()
EndIf
\pData = pData
PostEvent(Event, Window, Object, EventType, @MyEvent)
WaitSemaphore(\Signal)
result = \Result
If Semaphore = 0
FreeSemaphore(\Signal)
EndIf
EndWith
ProcedureReturn result
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure SendEventData(*MyEvent.udtSendEvent)
ProcedureReturn *MyEvent\pData
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure DispatchEvent(*MyEvent.udtSendEvent, result)
*MyEvent\Result = result
SignalSemaphore(*MyEvent\Signal)
EndProcedure
; ***************************************************************************************
;- Test
Enumeration
#Window
EndEnumeration
;- Constants
Enumeration #PB_Event_FirstCustomValue
#My_Event_Data
EndEnumeration
; Thread
Procedure Test(Null)
Protected result
Debug "Init Thread"
Repeat
Delay(1000)
result = SendEvent(#PB_Event_Gadget, 0, 0, #My_Event_Data, Random(100))
Debug "Result: " + Str(result)
Until result = 0
Debug "Exit Thread"
EndProcedure
; BindEvent
Procedure MyButtonEvent()
Protected MyEvent
Select EventType()
Case #PB_EventType_LeftClick
Debug "Left Click"
Case #My_Event_Data
MyEvent = EventData()
Value = SendEventData(MyEvent)
Debug "Es kommt ein SendEvent: " + Str(Value)
result = value * 1000
DispatchEvent(MyEvent, result)
EndSelect
EndProcedure
If OpenWindow(#Window, 0, 0, 800, 600, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 120, 25, "Button")
BindGadgetEvent(0, @MyButtonEvent(), #PB_All)
hThread = CreateThread(@Test(), #Null)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
exit = 1
Case #PB_Event_Gadget
EndSelect
Until exit
If IsThread(hThread)
Debug "Thread läuft"
KillThread(hThread)
EndIf
EndIf
Code: Alles auswählen
; ***************************************************************************************
;-TOP
; Comment : SendEvent
; Author : mk-soft
; Version : v1.05
;- Structure
Structure udtSendEvent
Signal.i
Result.i
*pData
EndStructure
; ---------------------------------------------------------------------------------------
Procedure SendEvent(Event, Window = 0, Object = 0, EventType = 0, pData = 0, Semaphore = 0)
Protected MyEvent.udtSendEvent, result
With MyEvent
If Semaphore
\Signal = Semaphore
Else
\Signal = CreateSemaphore()
EndIf
\pData = pData
PostEvent(Event, Window, Object, EventType, @MyEvent)
WaitSemaphore(\Signal)
result = \Result
If Semaphore = 0
FreeSemaphore(\Signal)
EndIf
EndWith
ProcedureReturn result
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure SendEventData(*MyEvent.udtSendEvent)
ProcedureReturn *MyEvent\pData
EndProcedure
; ---------------------------------------------------------------------------------------
Procedure DispatchEvent(*MyEvent.udtSendEvent, result)
*MyEvent\Result = result
SignalSemaphore(*MyEvent\Signal)
EndProcedure
; ***************************************************************************************
;- Example
Enumeration
#Window
EndEnumeration
;- Constants
Enumeration #PB_Event_FirstCustomValue
#My_Event_Data
EndEnumeration
Structure udtMydata
iVal.i
sVal.s
EndStructure
; Thread
Procedure Test(Null)
Protected result
Protected daten.udtMydata
Debug "Init Thread"
Repeat
Delay(1000)
daten\iVal = Random(100)
daten\sVal = "Value = " + Str(daten\iVal)
result = SendEvent(#PB_Event_Gadget, 0, 0, #My_Event_Data, @daten)
Debug "Result: " + Str(result)
Until result = 0
Debug "Exit Thread"
EndProcedure
; BindEvent
Procedure MyButtonEvent()
Protected MyEvent
Protected *daten.udtMydata
Select EventType()
Case #PB_EventType_LeftClick
Debug "Left Click"
Case #My_Event_Data
MyEvent = EventData()
*daten = SendEventData(MyEvent)
Debug "Es kommen Daten: " + *daten\sVal
result = *daten\iVal * 1000
DispatchEvent(MyEvent, result)
EndSelect
EndProcedure
If OpenWindow(#Window, 0, 0, 800, 600, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
ButtonGadget(0, 10, 10, 120, 25, "Button")
BindGadgetEvent(0, @MyButtonEvent(), #PB_All)
hThread = CreateThread(@Test(), #Null)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
exit = 1
Case #PB_Event_Gadget
EndSelect
Until exit
If IsThread(hThread)
Debug "Thread läuft"
KillThread(hThread)
EndIf
EndIf
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive