How to create unblocked Events
Posted: Wed Oct 21, 2015 8:19 pm
Menu or Resize Windows blocked events. AddGadgetItem from the Thread don't work exactly.
PostEvent lost sometime valid EventData and sometime crashed the program.
Stable example, but Menu or ResizeWindows blocked the Thread
PostEvent lost sometime valid EventData and sometime crashed the program.
Stable example, but Menu or ResizeWindows blocked the Thread
Code: Select all
;-TOP
; ***************************************************************************************
;- Include SendEvent
; 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
; ***************************************************************************************
;- Part Declare Main
Enumeration ;Window
#Main
EndEnumeration
Enumeration ; Menu
#Menu
EndEnumeration
Enumeration ; MenuItems
#MenuExit
EndEnumeration
Enumeration ; Gadgets
#Splitter
#List
#Edit
EndEnumeration
Enumeration ; Statusbar
#Status
EndEnumeration
; Global Variable
Global exit
; ***************************************************************************************
; Functions
Procedure UpdateWindow()
Protected x, y, dx, dy, menu, status
menu = MenuHeight()
If IsStatusBar(#Status)
status = StatusBarHeight(#Status)
Else
status = 0
EndIf
x = 0
y = 0
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - menu - status
ResizeGadget(#Splitter, x, y, dx, dy)
EndProcedure
; ***************************************************************************************
;- Part Write Logs
Procedure MyLogs(Text.s)
Protected temp.s, c
temp = FormatDate("%HH.%II.%SS - ", Date())
temp + Text
AddGadgetItem(#List, -1, temp)
c = CountGadgetItems(#List)
If c > 1000
RemoveGadgetItem(#List, 0)
c - 1
EndIf
c - 1
SetGadgetState(#List, c)
SetGadgetState(#List, -1)
EndProcedure
Global MutexLogs = CreateMutex()
Macro Logs(Text)
LockMutex(MutexLogs) : MyLogs(Text) : UnlockMutex(MutexLogs)
EndMacro
; ***************************************************************************************
;- Part Thread
Enumeration #PB_Event_FirstCustomValue
#My_Event_Data
EndEnumeration
; Thread
Procedure MyThread(Void)
Protected c, result, text.s
text = "Init Thread"
SendEvent(#My_Event_Data, 0, 0, 0, @text)
Repeat
text = "Counter " + Str(c)
result = SendEvent(#My_Event_Data, 0, 0, 0, @text)
;Debug "Result: " + Str(result)
c + 1
Delay(1000)
Until c > 3600
text = "Exit Thread"
SendEvent(#My_Event_Data, 0, 0, 0, @text)
EndProcedure
Procedure MyEventHandler()
Protected MyEvent, *MyEventText
MyEvent = EventData()
*MyEventText = SendEventData(MyEvent)
Logs(PeekS(*MyEventText))
DispatchEvent(MyEvent, #True)
EndProcedure
; ***************************************************************************************
;- Part Main
Procedure Main()
Protected event, style, dx, dy
style = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
dx = 800
dy = 600
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, dx, dy, "Main", style)
; Menu
; CreateMenu(#Menu, WindowID(#Main))
; MenuItem(#MenuExit, "Be&enden")
; Gadgets
ListViewGadget(#List, 0, 0, 0, 0)
EditorGadget(#Edit, 0, 0, 0, 0)
SplitterGadget(#Splitter, 0, 0, dx ,dy, #List, #Edit)
SetGadgetState(#Splitter, dy * 2 / 3)
; Statusbar
CreateStatusBar(#Status, WindowID(#Main))
AddStatusBarField(#PB_Ignore)
; For Mac
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
; Enable Fullscreen
Protected NewCollectionBehaviour
NewCollectionBehaviour = CocoaMessage(0, WindowID(#Main), "collectionBehavior") | $80
CocoaMessage(0, WindowID(#Main), "setCollectionBehavior:", NewCollectionBehaviour)
; Mac default menu´s
If Not IsMenu(#Menu)
CreateMenu(#Menu, WindowID(#Main))
EndIf
MenuItem(#PB_Menu_About, "")
MenuItem(#PB_Menu_Preferences, "")
CompilerEndIf
UpdateWindow()
; Init
BindEvent(#My_Event_Data, @MyEventHandler())
CreateThread(@MyThread(), 0)
; Main Loop
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_Menu
Select EventMenu()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Case #PB_Menu_About
MessageRequester("Info", "Basis v1.0")
Case #PB_Menu_Preferences
Case #PB_Menu_Quit
exit = #True
CompilerEndIf
Case #MenuExit
exit = #True
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #List
Case #Edit
EndSelect
Case #PB_Event_SizeWindow
Select EventWindow()
Case #Main
UpdateWindow()
EndSelect
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Main
exit = #True
EndSelect
EndSelect
Until exit
EndIf
EndProcedure : Main()
End
;- BOTTOM