Jump to content

Smooth Horizontal/Vertical Scroll via RawInput and SendInput


Recommended Posts

Opt("TrayAutoPause",0)


Global Const $moveThresh = 20 ; Chromium-based browsers and apps seems to drop inputs lower than 20ct
Global Const $timeThresh = 16 ; Chromium-based browsers and apps seems to drop inputs faster than 16ms


Global Const $user32dll = DllOpen("user32.dll")
GUIRegisterMsg(0x00FF,WM_INPUT)
Local $struct = DllStructCreate('struct;ushort UsagePage;ushort Usage;dword Flags;hwnd Target;endstruct')
$struct.UsagePage=0x01
$struct.Usage=0x02
$struct.Flags=0x00000100
$struct.Target=GUICreate('')
DllCall('user32.dll', 'bool', 'RegisterRawInputDevices', 'struct*', $struct, 'uint', 1, 'uint', DllStructGetSize(DllStructCreate('struct;ushort UsagePage;ushort Usage;dword Flags;hwnd Target;endstruct')))

Do
Until GUIGetMsg()=-3

Func ScrollFilter($dx, $dy)
     Local Static $accuX=0, $accuY=0, $lastTime=TimerInit()
     Local $cacheX = $accuX + $dx, $cacheY = $accuY + $dy
     $accuX += $dx
     $accuY += $dy
     If TimerDiff($lastTime) >= $timeThresh Then
        $lastTime = TimerInit()
         Local $sendX = abs($cacheX) >= $moveThresh ? $cacheX : 0, $sendY = abs($cacheY) >= $moveThresh ? $cacheY : 0
        $accuX -= $sendX
        $accuY -= $sendY
        ScrollMouseXY($sendX, $sendY, $user32dll)
     EndIf
EndFunc
Func WM_INPUT($hWnd,$Msg,$wParam,$lParam)
     Local Static $HEADER ='struct;dword Type;dword Size;handle hDevice;wparam wParam;endstruct;'
     Local Static $TAG = $HEADER & 'ushort flag;ushort Alignment;ushort bflg;short bdta;ulong rbtn;long dx;long dy;ulong info;'
     Local Static $HEADSIZE = DllStructGetSize(DllStructCreate($HEADER))
     Local Static $TAGSIZE = DllStructGetSize(DllStructCreate($TAG))

     Local Static $locked = False
     Local $input = DllCall($user32dll, 'uint','GetRawInputData', 'handle', $lParam, 'uint', 0x10000003, 'struct*', DllStructCreate($TAG), 'uint*', $TAGSIZE, 'uint', $HEADSIZE )
     Local $_ = $input[3]
     If $_.bflg Then
        If BitAnd(16,$_.bflg) Then
           Local $aCall = DllCall($user32dll,"dword","GetMessagePos")
           Local $x=BitAnd(0xffff,$aCall[0]),$y=BitShift($aCall[0],16)
           Local $clip = DllStructCreate("struct;long left;long top;long right;long bottom;endstruct")
           $clip.left   = $x
           $clip.top    = $y
           $clip.right  = $x+1
           $clip.bottom = $y+1
           DllCall( $user32dll, "bool", "ClipCursor", "struct*", $clip )
           $locked = True
        Endif
        If BitAnd(32,$_.bflg) Then
           DllCall( $user32dll, "bool", "ClipCursor", "struct*", Null )
           $locked = False
        Endif
     ElseIf $locked Then
        ScrollFilter($_.dx,-$_.dy)
     EndIf
     If $wParam Then Return 0
EndFunc
Func ScrollMouseXY($x, $y, $dll='user32.dll')
     Local Static $SIZE = DllStructGetSize(DllStructCreate('dword;struct;long;long;dword;dword;dword;ulong_ptr;endstruct;'))
     Local $count = ($x?1:0)+($y?1:0)
     Local $struct, $arr = DllStructCreate('byte[' & $count*$SIZE & ']'), $ptr = DllStructGetPtr($arr)
     If $x Then
        $struct = DllStructCreate('dword type;struct;long;long;dword data;dword flag;dword;ulong_ptr;endstruct;', $ptr)
        DllStructSetData($struct,1,0)
        DllStructSetData($struct,4,$x)
        DllStructSetData($struct,5,0x1000)
     EndIf
     If $y Then
        $struct = DllStructCreate('dword type;struct;long;long;dword data;dword flag;dword;ulong_ptr;endstruct;', $ptr+($x?$SIZE:0))
        DllStructSetData($struct,1,0)
        DllStructSetData($struct,4,$y)
        DllStructSetData($struct,5,0x0800)
     EndIf
     Return $count ? DllCall( $dll, 'uint', 'SendInput', 'uint', $count, 'struct*', $ptr, 'int', $SIZE )[0] : 0
EndFunc

Hold down middle click, the cursor will get locked in place and your mouse x/y motion are converted to horizontal and vertical scrolls.

Best tested in Firefox and/or spreadsheet applications, as this script sends fine-grained scroll inputs (some legacy applications ignore scroll inputs that are less than +/- 120).

If you want to coarse-scroll in legacy applications, just use the scrollwheel on your mouse.

 

 

------- v1.2 adds time and delta thresholds for better compatibility with poorly written software such as Chrome -------

tpmiddle-v1.2.au3tpmiddle-v1.2.exe

------- v1.1 is the smoothest scrolling (v1.0 as well, just structured slightly differently) -------

tpmiddle-v1.1.au3 tpmiddle-v1.1.exe

------- v1.0 -------

tpmiddle.exe tpmiddle.au3

Edited by AutoXenon
Link to post
Share on other sites
  • AutoXenon changed the title to Smooth Horizontal/Vertical Scroll via RawInput and SendInput
  • Moderators

AutoXenon,

Quote

request to move thread to autoit technical discussion

Why? That forum is for: "Technical discussions, betas, editors, help file, add-on tools, etc."

It looks fine to me right here: "cool AutoIt scripts, UDFs and applications"

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to post
Share on other sites

Well, I was hoping for some more feedback and/or discussion on the usage of the API, which seems more fitting on the technical discussion board. Do you suppose then that I should make a separate thread there, then?

Edited by Melba23
Removed quote
Link to post
Share on other sites
  • Moderators

AutoXenon,

First, when you reply in future, please use the "Reply to this topic" button at the top of the thread or the "Reply to this topic" editor at the bottom rather than the "Quote" button - responders know what they wrote and it just pads the thread unnecessarily. Thanks in advance for your cooperation in this matter.

Now, as to getting comments - why do you think they will not be made here? If you get none here, then I doubt changing to a less-well read location will help. But if you want to start a collaborative project, then I would be happy to move this thread to the "AutoIt Projects and Collaboration" sub-forum. Just let me know.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to post
Share on other sites

I made this after getting annoyed at viewing multi-column PDFs/comic pages and zooming in/out of micrographs, which are quite tedious with scroll bars, and precision touchpads have varying quality that is inconsistent from laptop to laptop. 

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...