A little MouseHover Library (last update: August 10, 2016)
Posted: Sat Aug 19, 2006 11:13 pm
This is a little includefile which will keep track of Mouse Enter/Leave events for gadgets on a window. Certain gadgets lend themselves well to such events and others do not. Those that don't are typically made up of multiple components, such as the IPAddress gadget, SpinGadget, PanelGadget, ComboBox, and a few others. I don't try to overcome this by treating these gadgets by window rectangle because I don't see a lot of use in catching mouse hover events for them anyway.
Library compiles fine with Tailbite if that's your preference.
Commands are:
InitHoverEvents(WindowID) ; Fire up the library
AddHoverGadget(GadgetID) ; Add a gadget to the list of those generating hover events
RemoveHoverGadget(GadgetID) ; Remove a single gadget from hover events (not necessary if you're executing EndHoverEvents() )
EndHoverEvents(WindowID) ; Remove all gadgets from hover events and free all resources used by the library
Here's the code:
Library compiles fine with Tailbite if that's your preference.
Commands are:
InitHoverEvents(WindowID) ; Fire up the library
AddHoverGadget(GadgetID) ; Add a gadget to the list of those generating hover events
RemoveHoverGadget(GadgetID) ; Remove a single gadget from hover events (not necessary if you're executing EndHoverEvents() )
EndHoverEvents(WindowID) ; Remove all gadgets from hover events and free all resources used by the library
Here's the code:
Code: Select all
;=====================================================
; Program: Hover.pbi
; Author: netmaestro, srod
; Date: August 19, 2006 (Version 1.0)
; January 30, 2011 (Version 2.0)
; August 10, 2016 (Version 3.0)
; Target OS: Windows all
; Target Compiler: PureBasic 4.0 and above
;=====================================================
;
Import ""
PB_Gadget_SendGadgetCommand(hwnd, EventType)
EndImport
#HoverEvent_EnterGadget = #WM_USER + 100
#HoverEvent_LeaveGadget = #WM_USER + 101
Procedure CallWndProc(nCode, wParam, lParam)
Static NewMap HotStack.RECT()
Static current_hotgadget.i
*mhs.MOUSEHOOKSTRUCT = lparam
If GetProp_(*mhs\hwnd, "track_hover_events")
If current_hotgadget <> *mhs\hwnd
If MapSize(hotstack())
ForEach HotStack()
GetCursorPos_(@cp.POINT)
If PtInRect_(HotStack(), PeekQ(@cp)) = 0 Or IsWindowVisible_(Val(MapKey(HotStack()))) = 0
PB_Gadget_SendGadgetCommand(Val(MapKey(HotStack())), #HoverEvent_LeaveGadget)
DeleteMapElement(HotStack())
EndIf
Next
EndIf
If Not FindMapElement(HotStack(), Str(*mhs\hwnd))
PB_Gadget_SendGadgetCommand(*mhs\hwnd, #HoverEvent_EnterGadget)
AddMapElement(HotStack(), Str(*mhs\hwnd))
GetWindowRect_(*mhs\hwnd, FindMapElement(HotStack(), Str(*mhs\hwnd)))
EndIf
current_hotgadget = *mhs\hwnd
EndIf
Else
If MapSize(hotstack())
ForEach HotStack()
GetCursorPos_(@cp.POINT)
If PtInRect_(HotStack(), PeekQ(@cp)) = 0 Or IsWindowVisible_(Val(MapKey(HotStack()))) = 0
PB_Gadget_SendGadgetCommand(Val(MapKey(HotStack())), #HoverEvent_LeaveGadget)
DeleteMapElement(HotStack())
EndIf
Next
EndIf
If current_hotgadget
current_hotgadget = 0
EndIf
EndIf
ProcedureReturn CallNextHookEx_(0, nCode, wParam, lParam)
EndProcedure
ProcedureDLL InitHoverEvents(hwnd)
Shared hook
hook = SetWindowsHookEx_(#WH_MOUSE, @CallWndProc(), #Null, GetCurrentThreadId_())
If hook
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
ProcedureDLL AddHoverGadget(hwnd)
If SetProp_(hwnd, "track_hover_events", #True)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
ProcedureDLL RemoveHoverGadget(hwnd)
If RemoveProp_(hwnd, "track_hover_events")
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure EnumControls(hwnd, lParam)
If GetProp_(hwnd, "track_hover_events")
RemoveProp_(hwnd, "track_hover_events")
EndIf
ProcedureReturn 1
EndProcedure
ProcedureDLL EndHoverEvents(hwnd)
Shared hook
EnumChildWindows_(hwnd, @EnumControls(), 0)
If UnhookWindowsHookEx_(hook)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
;========================================================
; End of Library Code
;========================================================
CompilerIf #PB_Compiler_IsMainFile
OpenWindow(0, 0, 0, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
PanelGadget(0, 8, 8, 300, 300)
AddGadgetItem(0,0,"Tab 1")
ContainerGadget(30, 5,5,260,220,#PB_Container_Flat)
ContainerGadget(20, 15,15,220,180,#PB_Container_Flat)
ButtonGadget(10, 25, 25, 100, 30, "")
CloseGadgetList()
CloseGadgetList()
AddGadgetItem(0,1,"Tab 2")
ButtonGadget(11, 10, 40, 200, 30, "")
CloseGadgetList()
InitHoverEvents(WindowID(0))
AddHoverGadget(GadgetID(10))
AddHoverGadget(GadgetID(11))
AddHoverGadget(GadgetID(20))
AddHoverGadget(GadgetID(30))
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_Gadget
If EventType() = #HoverEvent_EnterGadget
Debug "Entered Gadget " + EventGadget()
GetWindowRect_(GadgetID(EventGadget()), @wr.RECT)
MapWindowPoints_(0, WindowID(0), @wr, 2)
StartDrawing(WindowOutput(0))
DrawingMode(#PB_2DDrawing_Outlined)
Box(wr\left-1, wr\top-1, wr\right-wr\left+2, wr\bottom-wr\top+2, #Red)
StopDrawing()
ElseIf EventType() = #HoverEvent_LeaveGadget
Debug "Left Gadget " + EventGadget()
GetWindowRect_(GadgetID(EventGadget()), @wr.RECT)
MapWindowPoints_(0, WindowID(0), @wr, 2)
StartDrawing(WindowOutput(0))
DrawingMode(#PB_2DDrawing_Outlined)
Box(wr\left-1, wr\top-1, wr\right-wr\left+2, wr\bottom-wr\top+2, GetSysColor_(#COLOR_3DFACE))
StopDrawing()
EndIf
EndSelect
Until EventID = #PB_Event_CloseWindow
EndHoverEvents(WindowID(0))
CompilerEndIf