
Code: Select all
;======================================================================
; Library: EM_EventManager.pbi
;
; Author: Thomas (ts-soft) Schulz
; Date: March 30, 2013
; Version: 1.5
; Target Compiler: PureBasic 5.1+
; Target OS: Windows, Linux, MacOS
; License: Free, unrestricted, no warranty whatsoever
; Use at your own risk
;======================================================================
; Description:
; All parts of the normal event loop can be used without restriction or
; replaced by eventhandlers. Integration into existing projects should no problem
;
; EM_SetEventHandler(ID, ObjectType, *function, EventType = -1)
; ID = ID of Object (Window, Gadget, MenuItem, Timer, SysTray icon or EventNumber like #PB_Event_CloseWindow, #PB_Event_SizeWindow, #PB_Event_FirstCustomValue ...
; ObjectType = see ObjectType Enumeration
; *function = Address of Procedure to handle event, should only have one parameter: Procedure Foo(*ev.EM_Events)
; EventType = the #PB_EventType for Type #EM_Window, #EM_Gadget, and #EM_SysTray
;
; EM_RemoveEventHandler(ID, ObjectType, EventType = -1)
; ID = ID of Object (Window, Gadget, MenuItem, Timer, SysTray icon or EventNumber like #PB_Event_CloseWindow, #PB_Event_SizeWindow, #PB_Event_FirstCustomValue ...
; EventType = the #PB_EventType for Type #EM_Window, #EM_Gadget, and #EM_SysTray
;
; History:
; Version 1.5 (March 30, 2013) - by Danilo
; added #EM_Window for window events
; added #PB_Event_GadgetDrop to gadget event system
;
; Version 1.4 (March 30, 2013) - by Danilo
; added #EM_SysTray for SysTrayIcon events
;
; Version 1.3 (March 05, 2013)
; fixed a memoryleak with maps, comes with Version 1.2
;
; Version 1.2 (March 04, 2013)
; Codeoptimization (removed map events(), some FindMapElement ...
;
; Version 1.1
; changed from CallFunctionFast to Prototype, thx to netmaestro!
;
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
Enumeration ; ObjectType
#EM_Window
#EM_Gadget
#EM_Menu
#EM_SysTray
#EM_Timer
#EM_Special
EndEnumeration
Structure EM_Events
Event.i
EventType.i
EventWindow.i
EventGadget.i
EventMenu.i
EventSysTray.i
EventTimer.i
EventData.i
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
EventwParam.i
EventlParam.i
CompilerEndIf
EndStructure
Structure __EM_Maps__
Map WindowEvents.i()
Map GadgetEvents.i()
Map MenuEvents.i()
Map SysTrayEvents.i()
Map TimerEvents.i()
Map SpecialEvents.i()
EndStructure
Prototype __EM_ProcessEvent__(*Event.EM_Events)
Global __EM_Map__.__EM_Maps__
Procedure EM_SetEventHandler(ID, ObjectType, *function.__EM_ProcessEvent__, EventType = -1)
If *function <> 0
Select ObjectType
Case #EM_Window
If IsWindow(ID)
__EM_Map__\WindowEvents(Str(ID) + ":" + Str(EventType)) = *function
EndIf
Case #EM_Gadget
If IsGadget(ID)
__EM_Map__\GadgetEvents(Str(ID) + ":" + Str(EventType)) = *function
EndIf
Case #EM_SysTray
If IsSysTrayIcon(ID)
__EM_Map__\SysTrayEvents(Str(ID) + ":" + Str(EventType)) = *function
EndIf
Case #EM_Menu
__EM_Map__\MenuEvents(Str(ID)) = *function
Case #EM_Timer
__EM_Map__\TimerEvents(Str(ID)) = *function
Case #EM_Special
__EM_Map__\SpecialEvents(Str(ID)) = *function
EndSelect
EndIf
EndProcedure
Procedure EM_RemoveEventHandler(ID, ObjectType, EventType = -1)
Select ObjectType
Case #EM_Window
DeleteMapElement(__EM_Map__\WindowEvents(), Str(ID) + ":" + Str(EventType))
Case #EM_Gadget
DeleteMapElement(__EM_Map__\GadgetEvents(), Str(ID) + ":" + Str(EventType))
Case #EM_SysTray
DeleteMapElement(__EM_Map__\SysTrayEvents(), Str(ID) + ":" + Str(EventType))
Case #EM_Menu
DeleteMapElement(__EM_Map__\MenuEvents(), Str(ID))
Case #EM_Timer
DeleteMapElement(__EM_Map__\TimerEvents(), Str(ID))
Case #EM_Special
DeleteMapElement(__EM_Map__\SpecialEvents(), Str(ID))
EndSelect
EndProcedure
Procedure __EM_WaitWindowEvent__(timeout.i = -1)
Protected Event.EM_Events, ProcessThisEvent.__EM_ProcessEvent__
With Event
\Event = WaitWindowEvent(timeout)
\EventType = EventType()
\EventWindow = EventWindow()
\EventGadget = EventGadget()
\EventMenu = EventMenu()
\EventTimer = EventTimer()
\EventData = EventData()
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
\EventwParam = EventwParam()
\EventlParam = EventlParam()
CompilerEndIf
Select \Event
Case #PB_Event_Gadget, #PB_Event_GadgetDrop
If \Event = #PB_Event_GadgetDrop
\EventType = \Event
EndIf
If FindMapElement(__EM_Map__\GadgetEvents(), Str(\EventGadget) + ":" + Str(\EventType))
If __EM_Map__\GadgetEvents()
ProcessThisEvent = __EM_Map__\GadgetEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
ElseIf FindMapElement(__EM_Map__\GadgetEvents(), Str(\EventGadget) + ":-1")
If __EM_Map__\GadgetEvents()
ProcessThisEvent = __EM_Map__\GadgetEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
; for compatibility with special events:
ElseIf \Event = #PB_Event_GadgetDrop And FindMapElement(__EM_Map__\SpecialEvents(), Str(\Event))
If __EM_Map__\SpecialEvents()
ProcessThisEvent = __EM_Map__\SpecialEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
EndIf
Case #PB_Event_SysTray
\EventSysTray = \EventGadget
If FindMapElement(__EM_Map__\SysTrayEvents(), Str(\EventSysTray) + ":" + Str(\EventType))
If __EM_Map__\SysTrayEvents()
ProcessThisEvent = __EM_Map__\SysTrayEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
ElseIf FindMapElement(__EM_Map__\SysTrayEvents(), Str(\EventSysTray) + ":-1")
If __EM_Map__\GadgetEvents()
ProcessThisEvent = __EM_Map__\SysTrayEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
EndIf
Case #PB_Event_Menu
If FindMapElement(__EM_Map__\MenuEvents(), Str(\EventMenu))
If __EM_Map__\MenuEvents()
ProcessThisEvent = __EM_Map__\MenuEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
EndIf
Case #PB_Event_Timer
If FindMapElement(__EM_Map__\TimerEvents(), Str(\EventTimer))
If __EM_Map__\TimerEvents()
ProcessThisEvent = __EM_Map__\TimerEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
EndIf
Case #PB_Event_CloseWindow,
#PB_Event_Repaint,
#PB_Event_SizeWindow,
#PB_Event_MoveWindow,
#PB_Event_MinimizeWindow,
#PB_Event_MaximizeWindow,
#PB_Event_RestoreWindow,
#PB_Event_ActivateWindow,
#PB_Event_DeactivateWindow,
#PB_Event_WindowDrop,
#PB_Event_RightClick,
#PB_Event_LeftClick,
#PB_Event_LeftDoubleClick
\EventType = \Event
If FindMapElement(__EM_Map__\WindowEvents(), Str(\EventWindow) + ":" + Str(\Event))
If __EM_Map__\WindowEvents()
ProcessThisEvent = __EM_Map__\WindowEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
ElseIf FindMapElement(__EM_Map__\WindowEvents(), Str(\EventWindow) + ":-1")
If __EM_Map__\WindowEvents()
ProcessThisEvent = __EM_Map__\WindowEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
; for compatibility with special events:
ElseIf FindMapElement(__EM_Map__\SpecialEvents(), Str(\Event))
If __EM_Map__\SpecialEvents()
ProcessThisEvent = __EM_Map__\SpecialEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
EndIf
Default
If FindMapElement(__EM_Map__\SpecialEvents(), Str(\Event))
If __EM_Map__\SpecialEvents()
ProcessThisEvent = __EM_Map__\SpecialEvents()
If ProcessThisEvent
ProcessThisEvent(Event)
EndIf
EndIf
EndIf
EndSelect
ProcedureReturn Event\Event
EndWith
EndProcedure
Macro WaitWindowEvent(timeout = -1)
__EM_WaitWindowEvent__(timeout)
EndMacro
Macro WindowEvent()
__EM_WaitWindowEvent__(0)
EndMacro
CompilerIf #PB_Compiler_IsMainFile
; small example
Procedure Event_CloseWindow(*ev.EM_Events)
End
EndProcedure
Procedure Event_btnOkay_Clicked(*ev.EM_Events)
Debug "Okay clicked"
EndProcedure
Procedure Event_btnCancel_Clicked(*ev.EM_Events)
Debug "Cancel clicked"
EndProcedure
Procedure Event_btnQuit_Clicked(*ev.EM_Events)
PostEvent(#PB_Event_CloseWindow, *ev\EventWindow, -1)
;Event_CloseWindow(*ev)
;End
EndProcedure
Procedure Event_SysTray_Clicked(*ev.EM_Events)
MessageRequester("INFO","SysTray Icon clicked: "+Str(*ev\EventSysTray))
EndProcedure
Procedure Event_SysTray1_RightClick(*ev.EM_Events)
Protected menu = CreatePopupMenu(#PB_Any)
If menu
MenuItem(1, "Item 1")
MenuItem(2, "Item 2")
MenuItem(3, "Item 3")
MenuItem(4, "Item 4")
DisplayPopupMenu(menu,WindowID(*ev\EventWindow))
EndIf
EndProcedure
OpenWindow(0, #PB_Ignore, #PB_Ignore, 340, 45, "EM_EventManager - Example")
EM_SetEventHandler(0, #EM_Window, @Event_CloseWindow(), #PB_Event_CloseWindow)
;EM_SetEventHandler(#PB_Event_CloseWindow, #EM_Special, @Event_CloseWindow())
ButtonGadget(0, 10, 10, 100, 25, "Okay")
EM_SetEventHandler(0, #EM_Gadget, @Event_btnOkay_Clicked(), #PB_EventType_LeftClick)
Define btnCancel = ButtonGadget(#PB_Any, 120, 10, 100, 25, "Cancel")
EM_SetEventHandler(btnCancel, #EM_Gadget, @Event_btnCancel_Clicked(), #PB_EventType_LeftClick)
ButtonGadget(1, 230, 10, 100, 25, "Quit")
EM_SetEventHandler(1, #EM_Gadget, @Event_btnQuit_Clicked(), #PB_EventType_LeftClick)
If CreateImage(1,16,16)
AddSysTrayIcon(1, WindowID(0), ImageID(1))
EM_SetEventHandler(1, #EM_SysTray, @Event_SysTray_Clicked(), #PB_EventType_LeftClick)
EM_SetEventHandler(1, #EM_SysTray, @Event_SysTray1_RightClick(), #PB_EventType_RightClick)
AddSysTrayIcon(2, WindowID(0), ImageID(1))
EM_SetEventHandler(2, #EM_SysTray, @Event_SysTray_Clicked(), #PB_EventType_LeftClick)
EndIf
Repeat
WaitWindowEvent()
ForEver
CompilerEndIf
Greetings - Thomas