Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Send mouse scrolls to window under mouse


  • Please log in to reply
142 replies to this topic
madda
  • Members
  • 1 posts
  • Last active: Dec 07 2005 12:00 PM
  • Joined: 07 Dec 2005
Hello

I thought I'd share this code that activates the window under the mouse whenever there is scroll wheel movement. It's very short, but took me a while to figure out (I'm new). Sorry if someone's already posted something similar.

It works quite well, but the originally focussed window still gets some scroll messages before the activation kicks in. I tried to get this to work with a hook instead of the ~ passthrough, but couldn't figure it out. If anyone adds this improvement, please post it here.

Cheers
Matthew


; -------------------------------------------------------------
; Send scroll wheel movements to the window the mouse is over
; instead of the currently active window
; (currently active window may scroll a little before the new
; activation kicks in because ~ is real pass-through, but I
; couldn't get this working with a proper hook)
;
; I originally checked to see if the current window was already
; active before activating it, but I think that's handled by
; WinActivate without impairing performance
; -------------------------------------------------------------
;
; Turn on WinActivateForce to prevent flashing
; Note -- this will apply to all functions from this point on
#WinActivateForce
~WheelDown::
   MouseGetPos,,,win ; Get the window below the mouse
   WinActivate, ahk_id %win%
return

~WheelUp::
   MouseGetPos,,,win ; Get the window below the mouse
   WinActivate, ahk_id %win%
return


Tester
  • Guests
  • Last active:
  • Joined: --
other approach:
Wheelup::
   SetMouseDelay, -1
   MouseGetPos,,,hovwin,hovcontrol
   WinGetClass, hovclass, ahk_id %hovwin%
   IfWinNotActive, ahk_id %hovwin%
      if hovclass <> #32769
      {
         WinActivate ahk_id %hovwin%
         ControlFocus %hovcontrol%, ahk_id %hovwin%
         return
      }
   mouseclick, wheelup
return 
Wheeldown::
   SetMouseDelay, -1
   MouseGetPos,,,hovwin,hovcontrol
   WinGetClass, hovclass, ahk_id %hovwin%
   IfWinNotActive, ahk_id %hovwin%
      if hovclass <> #32769
      {
         WinActivate ahk_id %hovwin%
         ControlFocus %hovcontrol%, ahk_id %hovwin%
         return
      }
   mouseclick, wheeldown
;return
detailed info in this topic: http://www.autohotke...opic.php?t=1411

ddh
  • Guests
  • Last active:
  • Joined: --
This is great!

On a related note, I have an app that does not respond to the mouse wheel at all. Could this be modified to make the mouse wheel work with such a program? The program will scroll the window with the arrow keys.

Babis
  • Members
  • 69 posts
  • Last active: Aug 26 2015 09:31 AM
  • Joined: 08 Dec 2005
The problem with both scripts is that is usable only in “parent windows”.
So when I am in Firefox and have the addresses’ drop down list open – if I scroll in the addresses drop down list, the list will close and the main firefox window will take the focus and this is not what it supposes to do (it should just scroll the list down).

Is there a way to overcome?

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
Probably worth mentioning about a program called KatMouse here in case you haven't heard of it - it scrolls the control under the mouse (behaviour I prefer but maybe not to everyone's taste) whether the window is active or not. I've been using it ever since it was released and would absolutely have tried to code the same in AHK if it wasn't such a great program already 8)

<!-- m -->http://ehiti.sdf-eu.org/katmouse/<!-- m -->

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005
Here is a simple alternative. It actually works quite well. Well enough that I have finally removed KatMouse from my system.

note: should work with Windows 98+

CoordMode, Mouse, Screen
return

WheelUp::
	MouseGetPos, m_x, m_y
	hw_m_target := DllCall( "WindowFromPoint", "int", m_x, "int", m_y )

	; WM_MOUSEWHEEL
	;	WHEEL_DELTA = 120
	SendMessage, 0x20A, 120 << 16, ( m_y << 16 )|m_x,, ahk_id %hw_m_target%
return

WheelDown::
	MouseGetPos, m_x, m_y
	hw_m_target := DllCall( "WindowFromPoint", "int", m_x, "int", m_y )

	; WM_MOUSEWHEEL
	;	WHEEL_DELTA = 120
	SendMessage, 0x20A, -120 << 16, ( m_y << 16 )|m_x,, ahk_id %hw_m_target%
return


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
The last script works perfect. Thanks, Shimanov!

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
There was another thread a while back that tried to do a similar thing with the scroll wheel that I remember now - this has the same problem in that, when trying to scroll fast (e.g. a long web page), you only end up scrolling half as far (compared to when not using a script or using KatMouse).

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005
to Laszlo:
Neither Kat nor Mouse required?
to evl:
I would hypothesize that when scrolling "too fast" some wheel events could be missed; but, I have not observed this deficiency, and cannot test that hypothesis.

Try changing "120 << 16" to "240 << 16", etc. You could also make the translation adaptive and introduce an acceleration factor.

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
@ shimanov: I can't for the life of me find the other thread that tried to do something like this, but with the other script I tried everything I could think of like setbatchlines -1, increasing the maximum number of threads, etc - it didn't seem to make any difference. (When I say scrolling fast, I mean almost flicking the wheel to try and get to the start or end of a page as fast as possible).

It's not a big deal for me as I'm quite happy to stick with KatMouse but just thought I'd mention it.

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005
to evl:
I didn't think there was a problem; but, after buffering the wheel events, I noticed a dramatic difference. Try this:

CoordMode, Mouse, Screen
return

WheelUp::
	Critical
	MouseGetPos, m_x, m_y
	hw_m_target := DllCall( "WindowFromPoint", "int", m_x, "int", m_y )

	; WM_MOUSEWHEEL
	;	WHEEL_DELTA = 120
	SendMessage, 0x20A, 120 << 16, ( m_y << 16 )|m_x,, ahk_id %hw_m_target%
return

WheelDown::
	Critical
	MouseGetPos, m_x, m_y
	hw_m_target := DllCall( "WindowFromPoint", "int", m_x, "int", m_y )

	; WM_MOUSEWHEEL
	;	WHEEL_DELTA = 120
	SendMessage, 0x20A, -120 << 16, ( m_y << 16 )|m_x,, ahk_id %hw_m_target%
return


evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
It doesn't seem to help that much here with fast scrolls - it's not a problem with "normal" scrolling speed, but I often flick up and down a page or so by very fast scrolling.

I found the other thread I was thinking about:
<!-- m -->http://www.autohotke...opic.php?t=8720<!-- m -->

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
I tried to add some wheel acceleration code to Shimanov's script. Experiment with this
CoordMode Mouse, Screen

WheelTime  = 500
WheelDelta:= 120 << 16
WheelMax  := 4 * WheelDelta

WheelUp::
   Critical
   If (A_ThisHotKey <> A_PriorHotKey OR A_TimeSincePriorHotkey > WheelTime)
        WCnt = %WheelDelta%
   Else If (WCnt < WheelMax)
        WCnt+=  WheelDelta
   MouseGetPos m_x, m_y
   hw_m_target := DllCall("WindowFromPoint", "int",m_x, "int",m_y)
   SendMessage 0x20A, WCnt, (m_y<<16)|m_x,,ahk_id %hw_m_target% ; WM_MOUSEWHEEL
return

WheelDown::
   Critical
   If (A_ThisHotKey <> A_PriorHotKey OR A_TimeSincePriorHotkey > WheelTime)
        WCnt = %WheelDelta%
   Else If (WCnt < WheelMax)
        WCnt+=  WheelDelta
   MouseGetPos m_x, m_y
   hw_m_target := DllCall("WindowFromPoint", "int",m_x, "int",m_y)
   SendMessage 0x20A,-WCnt, (m_y<<16)|m_x,,ahk_id %hw_m_target% ; WM_MOUSEWHEEL
return
Three parameters govern the acceleration. WheelTime tells how much time should pass until we reset the wheel event counter, CntDelta tells how much the scroll amount is incremented at a time, and WheelMax limits the speed of scrolling. When the wheel is fast turned, we see many calls of the hotkey routines, and the WCnt counter is incremented. It tells how large scroll is to be performed, that is, when the wheel is turned fast, the window will scroll more at each step.

The script is considerably slower, than Windows handling the wheel (see how many wheel events are buffered). I tried
SetBatchLines -1
SetMouseDelay -1
Process Priority,,R
without any noticeable difference. Checking if the mouse position is changed, and only then call the dll WindowFromPoint, does not help either.

shimanov
  • Members
  • 610 posts
  • Last active: Jul 18 2006 08:35 PM
  • Joined: 25 Sep 2005

I tried to add some wheel acceleration code


Works well.

evl
  • Members
  • 1237 posts
  • Last active: Oct 20 2010 11:41 AM
  • Joined: 24 Aug 2005
Interesting - could do with accelerating a bit more slowly (non-linear perhaps) - I'll probably play with the settings and see if it can scroll the control under the mouse as well as KatMouse. An acceleration feature is about the only thing that KatMouse lacks.

How do I "see how many wheel events are buffered"? I couldn't see anything in the manual to find how many events were queued up?

Oh and what does "120 << 16" do? I'm sure I've seen "<<" in the manual somewhere but can't locate it again.