Page 1 of 1

MouseWatch - Addtional Mouse-in/out-Gadget Messages

Posted: Fri May 28, 2004 8:45 pm
by GPI
Code updated for 5.20+

Try:

Code: Select all

;
; MouseWatch
;
; This code activate additional messages, when a mouse move in and out of a gadget.
;

;Definite the Messages
; WM_APP through 0xBFFF are free to use (Platform-SDK)
; When you need other values, change here:
#MouseWatch_MoveIn  = #WM_APP
#MouseWatch_MoveOut = #WM_APP+1

;Some additional Structure
Structure MouseWatch
  GadgetId.i
  hWnd.i
  OldCallback.i
EndStructure

;I Need a own List
Global NewList MouseWatch.MouseWatch()

;Procedures
Procedure FindMouseWatch(hWnd); - #True, if mouse watch is activ on the GadgetID(!) and set the LinkedList to the active element
  Result=#False
  ResetList(MouseWatch())
  While NextElement(MouseWatch())
    If MouseWatch()\hWnd=hWnd
      Result=#True
      Break
    EndIf
  Wend
  ProcedureReturn Result
EndProcedure

Procedure MyMouseWatchCallback(hWnd,uMsg,wParam,lParam); - Internal use
  Static MouseWatchOldIn_
  If FindMouseWatch(hWnd)
    If uMsg=#WM_MOUSEMOVE
      If MouseWatchOldIn_<>hWnd
        TE.TrackMouseEvent
        TE\cbSize=SizeOf(TrackMouseEvent)
        TE\dwFlags=#TME_LEAVE
        TE\hwndTrack=hWnd
        TE\dwHoverTime=0
        TrackMouseEvent_(TE)
        PostMessage_(hWnd,#MouseWatch_MoveIn,MouseWatch()\GadgetId,0)
        MouseWatchOldIn_=hWnd
      EndIf
    ElseIf uMsg=#WM_MOUSELEAVE
      If MouseWatchOldIn_=hWnd
        MouseWatchOldIn_=0
      EndIf
      PostMessage_(hWnd,#MouseWatch_MoveOut,MouseWatch()\GadgetId,0)
    EndIf
    
    ProcedureReturn CallWindowProc_(MouseWatch()\OldCallback,hWnd,uMsg,wParam,lParam)
  EndIf
EndProcedure

Procedure StartMouseWatch(GadgetNb); - Activate MouseWatch-Message for a Gadget
  AddElement(MouseWatch())
  MouseWatch()\GadgetId=GadgetNb
  MouseWatch()\hWnd=GadgetID(GadgetNb)
  MouseWatch()\OldCallback=SetWindowLong_(MouseWatch()\hWnd,#GWL_WNDPROC,@MyMouseWatchCallback())
  ProcedureReturn #True
EndProcedure
Procedure StopMouseWatch(GadgetNb); - Deactivate MouseWatch-Message for a Gadget
  Result=#False
  ForEach MouseWatch()
    If MouseWatch()\GadgetId=GadgetNb
      SetWindowLong_(MouseWatch()\hWnd,#GWL_WNDPROC,MouseWatch()\OldCallback)
      DeleteElement(MouseWatch())
      LastElement(MouseWatch())
      Result=#True
    EndIf
  Next
  ProcedureReturn Result
EndProcedure


;Example
If OpenWindow(1,0,0,200,200,"Test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  ButtonGadget(0,0,50,50,100,"on",#PB_Button_Toggle)
  ButtonGadget(1,75,50,50,100,"on",#PB_Button_Toggle)
  ButtonGadget(2,200-50,50,50,100,"on",#PB_Button_Toggle)
  
  StartMouseWatch(0)
  StartMouseWatch(1)
  StartMouseWatch(2)
  
  Repeat
    event=WaitWindowEvent()
    Select event
      Case #PB_Event_Gadget
        Gadget=EventGadget()
        Debug "Push:"+Str(Gadget)
        If FindMouseWatch(GadgetID(Gadget))
          Debug "OFF"
          SetGadgetText(Gadget,"off")
          StopMouseWatch(Gadget)
        Else
          Debug "ON"
          SetGadgetText(Gadget,"on")
          StartMouseWatch(Gadget)
        EndIf
      Case #MouseWatch_MoveIn
        Gadget=EventwParam() ; Which Gadget
        ; IMPORTANT: Other Comands, like SetGadgetState() can destroy the value of EventwParam()
        SetGadgetState(Gadget,#True)
        Debug "IN:"+Str(Gadget)
      Case #MouseWatch_MoveOut
        Gadget=EventwParam() ; Which Gadget
        ; IMPORTANT: Other Comands, like SetGadgetState() can destroy the value of EventwParam()
        SetGadgetState(Gadget,#False)
        Debug "Out:"+Str(Gadget)
    EndSelect
  Until event=#PB_Event_CloseWindow
EndIf