Events, events, events...

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
klaver
Enthusiast
Enthusiast
Posts: 147
Joined: Wed Jun 28, 2006 6:55 pm
Location: Schröttersburg

Events, events, events...

Post by klaver »

Well, some basic events for PB gadgets are REALLY needed in my opinion. Here's show an example (Windows only) how I'd see it working. Maybe it's how it might (?) be done, at least for Windows?

Code: Select all

#PB_EventType_LeftClick2 = #PB_EventType_LeftClick+777
#PB_EventType_RightClick2 = #PB_EventType_RightClick+777
#PB_EventType_LeftDoubleClick2 = #PB_EventType_LeftDoubleClick+777
#PB_EventType_RightDoubleClick2 = #PB_EventType_RightDoubleClick+777
#PB_EventType_Focus2 = #PB_EventType_Focus+777
#PB_EventType_LostFocus2 = #PB_EventType_LostFocus+777

Import ""
  PB_Gadget_SendGadgetCommand(hWnd, EventType)
EndImport
Global hWin.i

Procedure CheckFocus(wParam, lParam)
  wParam = GetProp_(hWin, "OldFocus")
  Var3 = GetParent_(lParam)
  ;better method to determine if it's a PB gadget is
  ;needed because PB_ID returns 0 also for #Gadget = 0
  While GetProp_(lParam, "PB_ID") = 0 And Var3 <> 0
    lParam = Var3
    Var3 = GetParent_(Var3)
  WEnd
  If lParam <> wParam And Var3 <> 0
    SetProp_(hWin, "OldFocus", lParam)
    PB_Gadget_SendGadgetCommand(wParam, #PB_EventType_LostFocus2)
    PB_Gadget_SendGadgetCommand(lParam, #PB_EventType_Focus2)
  EndIf
EndProcedure

Procedure EventFunc(hWnd, uMsg, wParam, lParam)
  Protected Result.i = GetProp_(hWnd, "OldProc")
  If Result
    Result = CallWindowProc_(Result, hWnd, uMsg, wParam, lParam)
  EndIf
  
  Select uMsg
    Case #WM_LBUTTONDOWN;#WM_LBUTTONUP
      PB_Gadget_SendGadgetCommand(hWnd, #PB_EventType_LeftClick2)
    Case #WM_RBUTTONDOWN;#WM_RBUTTONUP
      PB_Gadget_SendGadgetCommand(hWnd, #PB_EventType_RightClick2)
    Case #WM_LBUTTONDBLCLK
      PB_Gadget_SendGadgetCommand(hWnd, #PB_EventType_LeftDoubleClick2)
    Case #WM_RBUTTONDBLCLK
      PB_Gadget_SendGadgetCommand(hWnd, #PB_EventType_RightDoubleClick2)
    Case #WM_SETFOCUS;, #WM_KILLFOCUS
      CheckFocus(wParam, hWnd)
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, "OldProc")
  EndSelect
  ProcedureReturn Result
EndProcedure

Procedure ChildFunc(hWnd, uMsg, wParam, lParam)
  Protected Result.i = GetProp_(hWnd, "OldProc")
  If Result
    Result = CallWindowProc_(Result, hWnd, uMsg, wParam, lParam)
  EndIf
  
  Select uMsg
    Case #WM_LBUTTONDOWN;#WM_LBUTTONUP
      PB_Gadget_SendGadgetCommand(GetParent_(hWnd), #PB_EventType_LeftClick2)
    Case #WM_RBUTTONDOWN;#WM_RBUTTONUP
      PB_Gadget_SendGadgetCommand(GetParent_(hWnd), #PB_EventType_RightClick2)
    Case #WM_LBUTTONDBLCLK
      PB_Gadget_SendGadgetCommand(GetParent_(hWnd), #PB_EventType_LeftDoubleClick2)
    Case #WM_RBUTTONDBLCLK
      PB_Gadget_SendGadgetCommand(GetParent_(hWnd), #PB_EventType_RightDoubleClick2)
    Case #WM_SETFOCUS;, #WM_KILLFOCUS
      CheckFocus(wParam, hWnd)
    Case #WM_NCDESTROY
      RemoveProp_(hWnd, "OldProc")
  EndSelect
  ProcedureReturn Result
EndProcedure

Procedure EnumChildProc(hWnd, lParam)
  SetProp_(hWnd, "OldProc", SetWindowLong_(hWnd, #GWL_WNDPROC, @ChildFunc()))
  ProcedureReturn #True
EndProcedure

Procedure SetEvents(hWnd, Child = #False)
  If Child
    EnumChildWindows_(hWnd, @EnumChildProc(), 0)
  EndIf
  SetProp_(hWnd, "OldProc", SetWindowLong_(hWnd, #GWL_WNDPROC, @EventFunc()))
EndProcedure

If OpenWindow(0, 0, 0, 400, 300 , "PB Events", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) : hWin = WindowID(0)
  DateGadget(3, 10, 10, 180, 22, "%mm/%dd/%yyyy Time: %hh:%ii", 0, #PB_Date_UpDown) : SetEvents(GadgetID(3), #True)
  
  IPAddressGadget(5, 10, 50, 160, 22) : SetEvents(GadgetID(5), #True)
  
  ComboBoxGadget(11, 10, 88, 180, 22) : SetEvents(GadgetID(11), #True)
  For i = 1 To 4
    AddGadgetItem (11, -1, "Item " + Str(i))
  Next
  
  OptionGadget(13, 10, 120, 60, 20, "Option") : SetEvents(GadgetID(13))
  ;CalendarGadget(13, 10, 120, 180, 140) : SetEvents(GadgetID(13));focus not supported for SysMonthCal32...
  
  ListViewGadget(7, 200, 10, 180, 120) : SetEvents(GadgetID(7))
  For i = 1 To 7
    AddGadgetItem (7, -1, "Item " + Str(i))
  Next
  
  ListIconGadget(9, 200, 140, 180, 120, "Column 1", 100) : SetEvents(GadgetID(9));, #True);header
  For i = 1 To 7
    AddGadgetItem (9, -1, "Item " + Str(i))
  Next
EndIf

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Gadget
      Select EventType()
        Case #PB_EventType_LeftClick2
          Debug "PB_EventType_LeftClick: "+Str(EventGadget())
        Case #PB_EventType_RightClick2
          Debug "PB_EventType_RightClick: "+Str(EventGadget())
        Case #PB_EventType_LeftDoubleClick2
          Debug "PB_EventType_LeftDoubleClick: "+Str(EventGadget())
        Case #PB_EventType_RightDoubleClick2
          Debug "PB_EventType_RightDoubleClick: "+Str(EventGadget())
        Case #PB_EventType_Focus2
          Debug "--> PB_EventType_Focus: "+Str(EventGadget())
        Case #PB_EventType_LostFocus2
          Debug "<-- PB_EventType_LostFocus: "+Str(EventGadget())
      EndSelect
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver
Last edited by klaver on Wed Aug 19, 2009 8:31 am, edited 1 time in total.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Outch outch outch! Don't do that.
Don't store callback or function pointers in the window properties...
They can not only be read but written to/changed by any other application,
a stupid app may also just end up messing them up by accident.
Use an internal structure or similar instead.


PS! Reason I point this out is that I recently read that Microsoft patched up a security hole just like this, related to WM_TIMER messages, although it did not involve window props, it too involved a callback/function pointer being passed publicly, via a the window message. (they patched that in XP SP1 btw)
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Here's an old post of mine.
Run it and see what lies hidden in so many windows props on your system
http://www.purebasic.fr/english/viewtopic.php?t=35655
Matt
Enthusiast
Enthusiast
Posts: 447
Joined: Sat May 21, 2005 1:08 am
Location: USA

Post by Matt »

It does get messy in the event loop when you have so much going on in the program and so many gadgets...
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Yeah! Hopefully by the time we get Window 10 there will be a more efficient alternative to the way windows messages work today.
Post Reply