Code: Select all
;======================================================
; Library: EnhanceGadgetCursor
; Author: Lloyd Gallant (netmaestro)
; Date: October 26, 2008
; Target OS: Microsoft Windows All
; Target Compiler: PureBasic 4.0 and later
; License: Free, unrestricted, no warranty
;======================================================
;
; Library commands: EnhanceGadgetCursor( gadget [,cursor] )
; ResetGadgetCursor( gadget [,stopevents] )
;
; EnhanceGadgetCursor adds two event types to the gadget:
;
; #Custom_EventType_MouseEnter, fires the first time the mouse enters the gadget
; #Custom_EventType_MouseLeave, fires when the mouse is no longer inside the gadget
;
; These events are tested in the native fashion, using EventGadget() and EventType()
;
; If you load or create a custom cursor and pass its handle to EnhanceGadgetCursor
; it will be displayed whenever the mousepointer is inside the gadget.
;
; ResetGadgetCursor removes the custom cursor from the gadget and optionally stops
; the enter-leave events from firing.
;
; Window properties are used to store the needed data, so you can enhance as many
; gadgets as you like in your project and there will be no conflicts. Globals are
; not used.
;
; A thread is used to monitor the mousepointer but there is nothing in it that
; would require the threadsafe switch if it's the only thread in your program.
Import ""
PB_Gadget_SendGadgetCommand(hWnd, EventType)
EndImport
#Custom_EventType_MouseEnter = 15000
#Custom_EventType_MouseLeave = 15001
Procedure gc_MonitorGadgetMouse(hwnd)
Protected threadrunning = #True
Protected mousewindow
While threadrunning
GetCursorPos_(cp.POINT)
MapWindowPoints_(0,GetParent_(hwnd),cp,1)
mousewindow = ChildWindowFromPoint_(GetParent_(hwnd), cp\x, cp\y)
If mousewindow <> hwnd
PB_Gadget_SendGadgetCommand(hwnd, #Custom_EventType_MouseLeave)
threadrunning = #False
EndIf
Delay(1)
Wend
SetProp_(hwnd, "cursorstate", 0)
EndProcedure
Procedure gc_GadgetProc(hwnd, msg, wparam, lparam)
Protected oldproc = GetProp_(hwnd, "oldproc")
Protected ctrlid = GetProp_(hwnd, "PB_ID")
Protected cursorstate = GetProp_(hwnd, "cursorstate")
Protected cursor = GetProp_(hwnd, "cursor")
Select msg
Case #WM_SETCURSOR
If Not cursorstate
cursorstate = #True
SetProp_(hwnd, "cursorstate", #True)
PB_Gadget_SendGadgetCommand(hwnd, #Custom_EventType_MouseEnter)
CreateThread(@gc_MonitorGadgetMouse(), hwnd)
EndIf
If cursor
SetCursor_(cursor)
ProcedureReturn 0
EndIf
Case #WM_NCDESTROY
RemoveProp_(hwnd, "oldproc")
RemoveProp_(hwnd, "cursorstate")
RemoveProp_(hwnd, "cursor")
EndSelect
ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam)
EndProcedure
ProcedureDLL EnhanceGadgetCursor(gadget, cursor=0)
SetProp_(GadgetID(gadget), "oldproc", SetWindowLong_(GadgetID(gadget),#GWL_WNDPROC,@gc_GadgetProc()))
SetProp_(GadgetID(gadget), "cursor", cursor)
EndProcedure
ProcedureDLL ResetGadgetCursor(gadget, stopevents=0)
SetProp_(GadgetID(gadget), "cursor", 0)
If stopevents
SetWindowLong_(GadgetID(gadget),#GWL_WNDPROC, GetProp_(GadgetID(gadget), "oldproc"))
EndIf
EndProcedure
Code: Select all
IncludeFile "gadgetcursor.pbi"
CreateImage(0, 128,128)
StartDrawing(ImageOutput(0))
Box(0,0,128,128,#Blue)
StopDrawing()
CreateImage(1, 128,128)
StartDrawing(ImageOutput(1))
Box(0,0,128,128,#Red)
StopDrawing()
OpenWindow(0,0,0,640,480,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ImageGadget(1,100,100,128,128,ImageID(0))
ImageGadget(2,250,100,128,128,ImageID(1))
hand = LoadCursor_(0, #IDC_HAND)
cross = LoadCursor_(0, #IDC_CROSS)
EnhanceGadgetCursor(1, cross)
EnhanceGadgetCursor(2, hand)
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_Gadget
Select EventType()
Case #Custom_EventType_MouseEnter
Debug "Mouse enter gadget "+Str(EventGadget())
Case #Custom_EventType_MouseLeave
Debug "Mouse leave gadget "+Str(EventGadget())
EndSelect
EndSelect
Until EventID = #PB_Event_CloseWindow