How to properly call Track Mouse Event?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Chappier
Posts: 44
Joined: 21 Aug 2021, 21:58

How to properly call Track Mouse Event?

07 Apr 2022, 18:47

Im trying to get this script post by @lexikos here, working:
https://www.autohotkey.com/board/topic/16842-trackmouseevent/


In her script the message OnMouseHover never get fired, imt not sure if its something related to x32/x64 versions
as its a old script.

Code: Select all

Gui, Add, Text, vTxt1, first text
Gui, Add, Text, vTxt2, second text
Gui, Add, Text, vTxt3, third text
Gui, Add, Edit, vEdt1, edit!
Gui, Show

OnMessage(0x200, "OnMouseMove")     ; WM_MOUSEMOVE
OnMessage(0x2A1, "OnMouseHover")    ; WM_MOUSEHOVER

return

GuiClose:
ExitApp

OnMouseMove(wParam, lParam, msg, hwnd)
{
    static TrackWnd, TrackPos
    
    ; Ignore repeat WM_MOUSEMOVE messages if position hasn't changed.
    if (TrackWnd = hwnd && TrackPos = lParam)
        return
    
    ToolTip
    
    VarSetCapacity(ET, 16)
    NumPut(16   , ET,  0)
    NumPut(0x3  , ET,  4)   ; TME_HOVER=1, TME_LEAVE=2
    NumPut(hwnd , ET,  8)
    NumPut(500  , ET, 12)
    
    TrackWnd := hwnd
    TrackPos := lParam

    DllCall("TrackMouseEvent", "uint", &ET)
}

OnMouseHover(wParam, lParam, msg, hwnd)
{
    WinGetClass, class, ahk_id %hwnd%
    ToolTip %class%
}


Below is the code im working based on lexikos script, its working parcially
WM_NCMOUSEHOVER is not getting fired when i hover the VScroll of the Listbox
as its a non client area, it should fire this msg dont?
Im using Win10.

https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-trackmouseevent
0x13:
TME_HOVER
0x00000001
The caller wants hover notification. Notification is delivered as a WM_MOUSEHOVER message.
If the caller requests hover tracking while hover tracking is already active, the hover timer will be reset.

This flag is ignored if the mouse pointer is not over the specified window or area.

TME_LEAVE
0x00000002
The caller wants leave notification. Notification is delivered as a WM_MOUSELEAVE message. If the mouse is not over the specified window or area, a leave notification is generated immediately and no further tracking is performed.
TME_NONCLIENT
0x00000010

Code: Select all

OnMessage(0x200,  "WM_MOUSEMOVE")   
OnMessage(0x02A1, "WM_MOUSEHOVER")   ; WM_MOUSEHOVER
OnMessage(0x02A3, "WM_MOUSELEAVE")  ; WM_MOUSELEAVE

OnMessage(0x02A0, "WM_NCMOUSEHOVER")

Gui, +E0x02000000 +E0x00080000
Gui, Add, Text, vTxt1, first text
Gui, Add, Text, vTxt2, second text
Gui, Add, Text, vTxt3, third text
Gui, Add, Edit, vEdt1, edit!

x:= -10
Gui, Add, button, x%x% w200 h50, button
Gui, Add, ListBox, xm r7 +VScroll, TEST|RED|BLUE|Green|1|2|3|4|5|6|7|8
Gui, Show, w400 h300
Return



WM_MOUSEMOVE(wParam, lParam, msg, hwnd) {
   
   Static TrackWnd, TrackPos

   ; Ignore repeat WM_MOUSEMOVE messages if position hasn't changed.
   ;if (TrackWnd = hwnd && TrackPos = lParam)
   ;    return
   If (TrackWnd = hwnd)
      Return

   ;ToolTip, hWnd: %hWnd%
   
   VarSetCapacity(ET, 24)
   NumPut(24   , ET,  0, "int")
   NumPut(0x13  , ET,  4, "int")   ; TME_HOVER = 1, TME_LEAVE=2
   NumPut(hwnd , ET,  8, "int")
   NumPut(300  , ET, 16, "int")
   
   TrackWnd := hwnd
   TrackPos := lParam

   DllCall("TrackMouseEvent", "uint", &ET)

}



WM_MOUSEHOVER(wParam, lParam, msg, hwnd) {
    WinGetClass, class, ahk_id %hwnd%
    ToolTip %class%
}



WM_NCMOUSEHOVER(wParam, lParam, msg, hwnd) {
   WinGetClass, class, ahk_id %hwnd%
   ToolTip WM_NCMOUSEHOVER: %class%
}



WM_MOUSELEAVE(wParam, lParam, msg, hwnd) {
   FileAppend, WM_MOUSELEAVE! `n,*
}
Chappier
Posts: 44
Joined: 21 Aug 2021, 21:58

Re: How to properly call Track Mouse Event?

10 Apr 2022, 10:42

Code: Select all




global WM_MOUSEMOVE  := 0x200
     , WM_MOUSEHOVER := 0x2A1
     , WM_MOUSELEAVE := 0x2A3
     , WM_NCMOUSEMOVE  := 0xA0
     , WM_NCMOUSEHOVER := 0x02A0
     , WM_NCMOUSELEAVE := 0x2A2



Gui, +E0x02000000 +E0x00080000
Gui, Add, Text, vTxt1, first text
Gui, Add, Text, vTxt2, second text
Gui, Add, Text, vTxt3, third text
Gui, Add, Edit, vEdt1, edit!

x:= -10
Gui, Add, button, x%x% w200 h50, button
Gui, Add, ListBox, xm r7 +VScroll, TEST|RED|BLUE|Green|1|2|3|4|5|6|7|8

SS_NOTIFY      := 0x100
SS_CENTERIMAGE := 0x200
Gui, Add, Text, w150 h35 center border hwndhText %SS_NOTIFY% %SS_CENTERIMAGE%, WM_MOUSELEAVE
Gui, Show, w500 h350


for k, msg in [WM_MOUSEMOVE, WM_MOUSEHOVER, WM_MOUSELEAVE, WM_NCMOUSEMOVE, WM_NCMOUSEHOVER, WM_NCMOUSELEAVE]
   OnMessage(msg, "TrackMouseEvent")
Return



WM_MOUSEMOVE(wParam, lParam, msg, hWnd) {
   static arr:={}

   if (!arr[hWnd]) {
      arr[hWnd] := 1
      TrackMouseEvent(hWnd, 10)
   }
}



TrackMouseEvent(hCtrl, time, msg := "", hwnd := "") {

   static flags := 0x13, TRACKMOUSEEVENT, hover := false, _hCtrl
   static msg2  := {,
     , 0x200  : "WM_MOUSEMOVE"
     , 0x2A1  : "WM_MOUSEHOVER"
     , 0x2A3  : "WM_MOUSELEAVE"
     , 0xA0   : "WM_NCMOUSEMOVE"
     , 0x02A0 : "WM_NCMOUSEHOVER"
     , 0x2A2  : "WM_NCMOUSELEAVE"}

   wm_msg := msg2[msg]



   if !msg {
      _hCtrl := hCtrl
      VarSetCapacity(TRACKMOUSEEVENT, len := 8 + A_PtrSize*2, 0)
      NumPut(len   , TRACKMOUSEEVENT)
      NumPut(flags , TRACKMOUSEEVENT, 4)
      NumPut(hCtrl , TRACKMOUSEEVENT, 8)
      NumPut(time  , TRACKMOUSEEVENT, 8 + A_PtrSize, "UInt")
   }

   if (!hover && hwnd = _hCtrl) {
      if (msg = WM_MOUSEMOVE) or (msg = WM_NCMOUSEMOVE) {
         hover := true
         DllCall("TrackMouseEvent", "Ptr", &TRACKMOUSEEVENT)
      }
   }



   if (msg = WM_MOUSEHOVER) or (msg = WM_NCMOUSEHOVER)
      ToolTip, %hWnd% %wm_msg%



   if (msg  = WM_MOUSELEAVE) or (msg = WM_NCMOUSELEAVE) {
      hover := false
      ToolTip, %hWnd% %wm_msg%
   }

}

@teadrinker do you know how to support WM_NC messages in TrackMouseEvent?
i tried to adapt your code including WM_NCMOUSEHOVER WM_NCMOUSELEAVE but NCMOUSEHOVER never get called when i hover any non client area, like listbox scrollbar.
teadrinker
Posts: 4388
Joined: 29 Mar 2015, 09:41
Contact:

Re: How to properly call Track Mouse Event?

10 Apr 2022, 14:09

Code: Select all

global WM_NCMOUSEMOVE  := 0x0A0
     , WM_NCMOUSEHOVER := 0x2A0
     , WM_NCMOUSELEAVE := 0x2A2

Gui, New, +hwndhGui, Nonclient area
Gui, Add, Text, y50 w200 h35 center
Gui, Show, h120
TrackMouseEvent(hGui, 10)

for k, msg in [WM_NCMOUSEMOVE, WM_NCMOUSEHOVER, WM_NCMOUSELEAVE]
   OnMessage(msg, "TrackMouseEvent")
Return

GuiClose() {
   ExitApp
}

TrackMouseEvent(hGui, time, msg := "", hwnd := "") {
   static flags := (TME_HOVER := 0x1) | (TME_LEAVE := 0x2) | (TME_NONCLIENT := 0x10)
        , TRACKMOUSEEVENT, hover := false, _hGui
   if !msg {
      _hGui := hGui
      VarSetCapacity(TRACKMOUSEEVENT, len := 8 + A_PtrSize*2, 0)
      NumPut(len   , TRACKMOUSEEVENT)
      NumPut(flags , TRACKMOUSEEVENT, 4)
      NumPut(hGui  , TRACKMOUSEEVENT, 8)
      NumPut(time  , TRACKMOUSEEVENT, 8 + A_PtrSize, "UInt")
   }
   if (!hover && hwnd = _hGui && msg = WM_NCMOUSEMOVE) {
      hover := true
      DllCall("TrackMouseEvent", "Ptr", &TRACKMOUSEEVENT)
   }
   if (msg = WM_NCMOUSEHOVER)
      GuiControl,, Static1, WM_NCMOUSEHOVER
   if (msg = WM_NCMOUSELEAVE) {
      hover := false
      GuiControl,, Static1, WM_NCMOUSELEAVE
   }
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: AlFlo, VaritySpice and 113 guests