EM_EventManager (crossplattform)

Share your advanced PureBasic knowledge/code with the community.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

EM_EventManager (crossplattform)

Post by ts-soft »

This is my version of a EventManger :wink:

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
If you found any bugs, so tell me.

Greetings - Thomas
Last edited by ts-soft on Sat Mar 30, 2013 2:57 pm, edited 6 times in total.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: EM_EventManager (crossplattform)

Post by jassing »

Nice - I love the concept -- and it seems to be every bit as fast too...
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: EM_EventManager (crossplattform)

Post by netmaestro »

I didn't find any bugs yet, good work! But I do have one small suggestion. CallFunctionFast, while it works fine in this project, would be better left in the museum. A prototype is easy to implement here, I offer this few modifications as an idea for you to consider:

Add the line:
Prototype ProcessEvent(Event)

Change the CallFunctionFast lines to:
ProcessThisEvent.ProcessEvent = __EM_Map__\GadgetEvents()\event()
ProcessThisEvent( Event)


(Gadget example provided only)
Last edited by netmaestro on Sun Mar 03, 2013 6:10 pm, edited 1 time in total.
BERESHEIT
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: EM_EventManager (crossplattform)

Post by ts-soft »

Thx for your suggestion, i have implemented this :wink:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
said
Enthusiast
Enthusiast
Posts: 342
Joined: Thu Apr 14, 2011 6:07 pm

Re: EM_EventManager (crossplattform)

Post by said »

Nice work :D
I see we are slowly moving towards a cross-platform 'VB6' environment, good for PB (it deserves much more) - i just love PB :mrgreen:


And thanks for sharing ts-soft! I appreciate your contributions
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: EM_EventManager (crossplattform)

Post by idle »

You beat me to it Thomas :)
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: EM_EventManager (crossplattform)

Post by ts-soft »

thx to all :D

Here an example, modified from PB-Helpfile:

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - Drag & Drop
;
;    (c) 2007 - Fantaisie Software
;
; ------------------------------------------------------------
;
; changed to work with EM_EventManger.pbi by ts-soft
EnableExplicit

XIncludeFile "EM_EventManager.pbi"

#Window = 0

Enumeration    ; Images
  #ImageSource
  #ImageTarget
EndEnumeration

Enumeration    ; Gadgets
  #SourceText
  #SourceImage
  #SourceFiles
  #SourcePrivate
  #TargetText
  #TargetImage
  #TargetFiles
  #TargetPrivate1
  #TargetPrivate2
EndEnumeration

Procedure SourceText_DragStart(*ev.EM_Events)
  Protected Text$ = GetGadgetItemText(#SourceText, GetGadgetState(#SourceText))
  DragText(Text$)
EndProcedure

Procedure SourceImage_DragStart(*ev.EM_Events)
  DragImage(ImageID(#ImageSource))
EndProcedure

Procedure SourceFiles_DragStart(*ev.EM_Events)
  Protected i
  Protected Files$ = ""       
  For i = 0 To CountGadgetItems(#SourceFiles)-1
    If GetGadgetItemState(#SourceFiles, i) & #PB_Explorer_Selected
      Files$ + GetGadgetText(#SourceFiles) + GetGadgetItemText(#SourceFiles, i) + Chr(10)
    EndIf
  Next i 
  If Files$ <> ""
    DragFiles(Files$)
  EndIf
EndProcedure

Procedure SourcePrivate_DragStart(*ev.EM_Events)
  If GetGadgetState(#SourcePrivate) = 0
    DragPrivate(1)
  Else
    DragPrivate(2)
  EndIf
EndProcedure

Procedure Event_GadgetDrop(*ev.EM_Events)
  Protected Files$, i, Count
  
  Select *ev\EventGadget
  
    Case #TargetText
      AddGadgetItem(#TargetText, -1, EventDropText())
    
    Case #TargetImage
      If EventDropImage(#ImageTarget)
        SetGadgetState(#TargetImage, ImageID(#ImageTarget))
      EndIf
    
    Case #TargetFiles
      Files$ = EventDropFiles()
      Count  = CountString(Files$, Chr(10)) + 1
      For i = 1 To Count
        AddGadgetItem(#TargetFiles, -1, StringField(Files$, i, Chr(10)))
      Next i
    
    Case #TargetPrivate1
      AddGadgetItem(#TargetPrivate1, -1, "Private type 1 dropped")
            
    Case #TargetPrivate2
      AddGadgetItem(#TargetPrivate2, -1, "Private type 2 dropped")
    
  EndSelect
EndProcedure

Procedure Window_Close(*ev.EM_Events)
  End
EndProcedure

Macro DoEvent()
  Repeat : WaitWindowEvent() : ForEver
EndMacro

Define i

If OpenWindow(#Window, 0, 0, 760, 310, "Drag & Drop", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  EM_SetEventHandler(#PB_Event_CloseWindow, #EM_Special, @Window_Close())
  ; Create some images for the image demonstration
  ; 
  CreateImage(#ImageSource, 136, 136)
  If StartDrawing(ImageOutput(#ImageSource))
    Box(0, 0, 136, 136, $FFFFFF)
    DrawText(5, 5, "Drag this image", $000000, $FFFFFF)        
    For i = 45 To 1 Step -1
      Circle(70, 80, i, Random($FFFFFF))
    Next i        
    
    StopDrawing()
  EndIf  
  
  CreateImage(#ImageTarget, 136, 136)
  If StartDrawing(ImageOutput(#ImageTarget))
    Box(0, 0, 136, 136, $FFFFFF)
    DrawText(5, 5, "Drop images here", $000000, $FFFFFF)
    StopDrawing()
  EndIf  
  
  
  ; Create and fill the source gadgets
  ;
  ListIconGadget(#SourceText,       10, 10, 140, 140, "Drag Text here", 130)
  EM_SetEventHandler(#SourceText, #EM_Gadget, @SourceText_DragStart(), #PB_EventType_DragStart)
  ImageGadget(#SourceImage,        160, 10, 140, 140, ImageID(#ImageSource), #PB_Image_Border)
  EM_SetEventHandler(#SourceImage, #EM_Gadget, @SourceImage_DragStart(), #PB_EventType_DragStart)
  ExplorerListGadget(#SourceFiles, 310, 10, 290, 140, GetHomeDirectory(), #PB_Explorer_MultiSelect)
  EM_SetEventHandler(#SourceFiles, #EM_Gadget, @SourceFiles_DragStart(), #PB_EventType_DragStart)
  ListIconGadget(#SourcePrivate,   610, 10, 140, 140, "Drag private stuff here", 260)
  EM_SetEventHandler(#SourcePrivate, #EM_Gadget, @SourcePrivate_DragStart(), #PB_EventType_DragStart)
     
  AddGadgetItem(#SourceText, -1, "hello world")
  AddGadgetItem(#SourceText, -1, "The quick brown fox jumped over the lazy dog")
  AddGadgetItem(#SourceText, -1, "abcdefg")
  AddGadgetItem(#SourceText, -1, "123456789")
  
  AddGadgetItem(#SourcePrivate, -1, "Private type 1")
  AddGadgetItem(#SourcePrivate, -1, "Private type 2")
  

  ; Create the target gadgets
  ;
  ListIconGadget(#TargetText,  10, 160, 140, 140, "Drop Text here", 130)
  ImageGadget(#TargetImage,    160, 160, 140, 140, ImageID(#ImageTarget), #PB_Image_Border) 
  ListIconGadget(#TargetFiles, 310, 160, 140, 140, "Drop Files here", 130)
  ListIconGadget(#TargetPrivate1, 460, 160, 140, 140, "Drop Private Type 1 here", 130)
  ListIconGadget(#TargetPrivate2, 610, 160, 140, 140, "Drop Private Type 2 here", 130)

  
  ; Now enable the dropping on the target gadgets
  ;
  EnableGadgetDrop(#TargetText,     #PB_Drop_Text,    #PB_Drag_Copy)
  EnableGadgetDrop(#TargetImage,    #PB_Drop_Image,   #PB_Drag_Copy)
  EnableGadgetDrop(#TargetFiles,    #PB_Drop_Files,   #PB_Drag_Copy)
  EnableGadgetDrop(#TargetPrivate1, #PB_Drop_Private, #PB_Drag_Copy, 1)
  EnableGadgetDrop(#TargetPrivate2, #PB_Drop_Private, #PB_Drag_Copy, 2)
  
  EM_SetEventHandler(#PB_Event_GadgetDrop, #EM_Special, @Event_GadgetDrop())

EndIf

DoEvent()

PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: EM_EventManager (crossplattform)

Post by ts-soft »

PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: EM_EventManager (crossplattform)

Post by ts-soft »

Update:
History wrote:; Version 1.3 (March 05, 2013)
; fixed a memoryleak with maps, comes with Version 1.2
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: EM_EventManager (crossplattform)

Post by Danilo »

A gift for you on my birthday:
; Version 1.4 (March 30, 2013)
; added #EM_SysTray for SysTrayIcon events

Code: Select all

;======================================================================
; Library:         EM_EventManager.pbi
;
; Author:          Thomas (ts-soft) Schulz
; Date:            March 30, 2013
; Version:         1.4
; 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 (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_Gadget and #EM_SysTray
;
; EM_RemoveEventHandler(ID, ObjectType, EventType = -1)
;     ID = ID of Object (Gadget, MenuItem, Timer, SysTray icon or EventNumber like #PB_Event_CloseWindow, #PB_Event_SizeWindow, #PB_Event_FirstCustomValue ...
;     EventType = the #PB_EventType for Type #EM_Gadget and #EM_SysTray
;
; History:
; Version 1.4 (March 30, 2013)
; 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!
;
Enumeration ; ObjectType
  #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 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_Gadget
        If IsGadget(ID)
          __EM_Map__\GadgetEvents(Str(ID) + ":" + EventType) = *function
        EndIf
        
      Case #EM_SysTray
        If IsSysTrayIcon(ID)
          __EM_Map__\SysTrayEvents(Str(ID) + ":" + 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_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
        If FindMapElement(__EM_Map__\GadgetEvents(), Str(\EventGadget) + ":" + Str(\EventType))
          If __EM_Map__\GadgetEvents()
            ProcessThisEvent = __EM_Map__\GadgetEvents()
            ProcessThisEvent(Event)
          EndIf
        ElseIf FindMapElement(__EM_Map__\GadgetEvents(), Str(\EventGadget) + ":-1")
          If __EM_Map__\GadgetEvents()
            ProcessThisEvent = __EM_Map__\GadgetEvents()
            ProcessThisEvent(Event)
          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()
            ProcessThisEvent(Event)
          EndIf
        ElseIf FindMapElement(__EM_Map__\SysTrayEvents(), Str(\EventSysTray) + ":-1")
          If __EM_Map__\GadgetEvents()
            ProcessThisEvent = __EM_Map__\SysTrayEvents()
            ProcessThisEvent(Event)
          EndIf        
        EndIf
      Case #PB_Event_Menu
        If FindMapElement(__EM_Map__\MenuEvents(), Str(\EventMenu))
          If __EM_Map__\MenuEvents()
            ProcessThisEvent = __EM_Map__\MenuEvents()
            ProcessThisEvent(Event)
          EndIf
        EndIf
      Case #PB_Event_Timer
        If FindMapElement(__EM_Map__\TimerEvents(), Str(\EventTimer))
          If __EM_Map__\TimerEvents()
            ProcessThisEvent = __EM_Map__\TimerEvents()
            ProcessThisEvent(Event)
          EndIf
        EndIf
      Default
        If FindMapElement(__EM_Map__\SpecialEvents(), Str(\Event))
          If __EM_Map__\SpecialEvents()
            ProcessThisEvent = __EM_Map__\SpecialEvents()
            ProcessThisEvent(Event)
          EndIf
        EndIf
    EndSelect
  
    ProcedureReturn Event\Event
  EndWith
EndProcedure

Macro WaitWindowEvent(timeout = -1)
  __EM_WaitWindowEvent__(timeout)
EndMacro

Macro WindowEvent()
  __EM_WaitWindowEvent__(0)
EndMacro

CompilerIf Not #PB_Compiler_IsIncludeFile
; 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(#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
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: EM_EventManager (crossplattform)

Post by Danilo »

I want to handle each window with different event procedures.

The following line is used to set the event handler for #PB_Event_CloseWindow

Code: Select all

EM_SetEventHandler(#PB_Event_CloseWindow, #EM_Special, @Event_CloseWindow())
This handler is used for all windows.

So here a version with #EM_Window to set different handlers for different windows:
; Version 1.5 (March 30, 2013) - by Danilo
; added #EM_Window for window events
; added #PB_Event_GadgetDrop to gadget event system
It is compatible to the old way:

Code: Select all

EM_SetEventHandler(#PB_Event_CloseWindow, #EM_Special, @Event_CloseWindow())
still works to set a handler for all windows, and

Code: Select all

EM_SetEventHandler(0, #EM_Window, @Event_CloseWindow(), #PB_Event_CloseWindow)
can be used to set the handler for a specific window.

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!
;
EnableExplicit

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 Not #PB_Compiler_IsIncludeFile
    ; 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

DisableExplicit
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: EM_EventManager (crossplattform)

Post by Danilo »

Changed a bug/typo in the last code above (v1.5). Using '\Event' and 'Event' in the same procedure is very dangerous! :twisted:

Compare a structure to a constant:

Code: Select all

EnableExplicit

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

Define Event.EM_Events

Event\Event = #PB_Event_GadgetDrop

With Event

    If Event = #PB_Event_GadgetDrop ; Event instead \Event
        Debug "True"
    Else
        Debug "False"
    EndIf
    
EndWith
Nice.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: EM_EventManager (crossplattform)

Post by Danilo »

mevedia.de wrote:Happy Birthday Danilo :D
Thanks! :)
mevedia.de wrote:Nice additions, but it's more extensive to use Callbacks for Gadgets, so all Events will be available for a Canvas for Example. (also Size-Messages) This is possible on Windows and Linux with equal calls, currently working on a port for MacOS. :D Also adding Properties to an Gadget is better than SetGadgetData - only 1 Slot.

Why is MacOS so expensive :evil:
I use it for an object oriented system, so I can handle size messages in my object system. canvas\SetSize() could send an event.
gadget\SetData() can also have more slots in my system.

Looks like this atm:

Code: Select all

XIncludeFile "Window.pbi"

Define win1.Window

Procedure Event_CloseWindow(*ev.EM_Events)
    If MessageRequester("Question","Are you sure you want to quit?",#PB_MessageRequester_YesNo)=#PB_MessageRequester_Yes
        EndEvents()
    EndIf
EndProcedure

win1 = New Window(0,0,800,600,"Object Based Interfaces",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

win1\OnClose(@Event_CloseWindow())

win1\SetSize(320,200)

DoEvents()

Delete( win1 )
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: EM_EventManager (crossplattform)

Post by ts-soft »

Happy Birthday Danilo :D

Updated first post with enhancement by Danilo
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: EM_EventManager (crossplattform)

Post by Danilo »

[OFFTOPIC]
mevedia.de wrote:Yes, but Users have to manually update the Control. A Callback reacts on the general GUI Event, like (on Windows) MoveWindow_() and ResizeGadget(). There also Messages PB doesn't send like #WM_SIZE, #WM_EXITSIZE. Would be nice to see this native in PB.
Makes only sense for messages that are available on all 3 platforms.
mevedia.de wrote:Problem is, there's no Event like #PB_EventType_Size, so if the Canvas get's sized, you manually have to update it. :D
Try something like this:

Code: Select all

Enumeration #PB_Event_FirstCustomValue
    #PB_EventType_Size
EndEnumeration

Procedure _ResizeGadget(gadget,x,y,width,height)
    ResizeGadget(gadget,x,y,width,height)
    PostEvent(#PB_Event_Gadget,0,gadget,#PB_EventType_Size)
EndProcedure

Macro ResizeGadget(gadget,x,y,width,height)
    _ResizeGadget(gadget,x,y,width,height)
EndMacro
ts-soft wrote:Happy Birthday Danilo :D
Thank you, too! :)

[/OFFTOPIC]

Sorry for off-topic.
Post Reply