Parameterübergabe bei BindGadgetEvent möglich?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Parameterübergabe bei BindGadgetEvent möglich?

Beitrag von ProgOldie »

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?
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Parameterübergabe bei BindGadgetEvent möglich?

Beitrag von mk-soft »

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.

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
Dazu habe ich irgendwann mal SendEvent geschrieben. Dieser warte so lange bis die Nachricht verarbeitet wurde. (DispatchEvent)

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
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Parameterübergabe bei BindGadgetEvent möglich?

Beitrag von mk-soft »

Geht auch mit BindGadgetEvent...

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
Beispiel mit übergabe eines Zeigers auf Daten

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
Antworten