Use Middel mouse Button (Lenovo TrackPoint Button) to scroll like under Linux

Post your working scripts, libraries and tools for AHK v1.1 and older
jMichael
Posts: 1
Joined: 07 Apr 2017, 04:02

Use Middel mouse Button (Lenovo TrackPoint Button) to scroll like under Linux

Post by jMichael » 15 Nov 2020, 05:09

Hi,

I am new to AutoHotkey and new to use Windows on an Thinkpad. I was missing the optioion to use the middle mouse button as a middle mouse button and to scroll with it like it does under Linux so I searched for a solution and found this script from 2009: https://autohotkey.com/board/topic/39768-is-it-possible-to-scroll-with-middle-mouse-button-drag/

I played around and have a version with some improvements I want to share:
- supports scrolling in 4 directions
- the more the mouse is moved while scrolling the faster the scrolling is
- keeping the middle mouse button function (close tabs, open new window, ...)
- a simple and not feature complete middle mouse click to paste the selected text or whatever (but it does not manage to switch focus before clicking the middle mouse button)

Please feel free to comment for further improvements or to use it.

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Enable warnings to assist with detecting common errors.
SetMouseDelay, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

Sensitivity := 20   ; how far it takes before the scroll happens
HideCursor := True  ; decides if the mouse cursor is hidden on scrolling

DidScroll := False 
IsLongMousePress := False


$*MButton Up::
    MouseMove, X1, Y1, 0    ;Sest back the mouse possition
    if (HideCursor) SystemCursor("Toggle")
    Send {Mbutton up}       ;Saves the Middel Click function
    if (!DidScroll && IsLongMousePress) {
        MiddelMoudeCopyPaste()
    }
    SetTimer, MBScroll, off ;Ends the Scrolling (if started)
return

$*MButton::
    DidScroll := False 
    IsLongMousePress := False
    MouseGetPos, X1, Y1
    if (HideCursor) SystemCursor("Toggle")
    KeyWait, MButton, T0.250
    If ErrorLevel {
        IsLongMousePress := True
		SetTimer, MBScroll, 1
	}
    Else {
        GetKeyState, state, Mbutton
        if (state = "P")
            SendInput, {Mbutton down}
        Else
            SendInput {Mbutton}
        }
Return


MBScroll:
    MouseGetPos, X2, Y2
    MouseMove, X1, Y1, 0    ;Sest back the mouse possition
    MouseDifferenceY := Abs(Y1 - Y2)
    MouseDifferenceX := Abs(X1 - X2)
    Difference :=
    Direction :=
    if (MouseDifferenceY >= MouseDifferenceX){
        Direction := Y2 > Y1 ? "Down" : "Up"
        Difference := MouseDifferenceY
    } else {
        Direction := X2 > X1 ? "Right" : "Left"
        Difference := MouseDifferenceX
    }

    If Difference >= 4 * Sensitivity
    {
        GetKeyState, state, Mbutton
        if (state = "P")
            return
        SendInput, {Blind}{Wheel%Direction%}
        DidScroll = True
        
    }  Else If Difference >= 3 * Sensitivity
    {
        GetKeyState, state, Mbutton
        if (state = "P")
            return
        SendInput, {Blind}{Wheel%Direction%}
        DidScroll = True
        Sleep, 100
        
    }  Else If Difference >= 2 * Sensitivity
    {
        GetKeyState, state, Mbutton
        if (state = "P")
            return
        SendInput, {Blind}{Wheel%Direction%}
        DidScroll = True
        Sleep, 200
        
    } Else If Difference >= Sensitivity
    {
            GetKeyState, state, Mbutton
        if (state = "P")
            return
        SendInput, {Blind}{Wheel%Direction%}
        DidScroll = True
        Sleep, 300
        
    }
return

MiddelMoudeCopyPaste()
{
    ClipboardOld := ClipboardAll
    Clipboard =  ; Must start off blank for detection to work.
    Send ^c
    ClipWait 1, 1
    if ErrorLevel  ; ClipWait timed out.
    {
        return
    }
    KeyWait, mbutton
    Click
    Sleep 100
    Send ^v
    Sleep 100
    Clipboard =  ; Must start off blank for detection to work.
    
    Clipboard := ClipboardOld  ; Restore previous contents of clipboard.
    ClipWait 1, 1
    if ErrorLevel  ; ClipWait timed out.
    {
        return
    }
return
}
		

; This is the section that handles the hiding of the cursor
; ===================================
SystemCursor(OnOff=1)   ; INIT = "I","Init"; OFF = 0,"Off"; TOGGLE = -1,"T","Toggle"; ON = others
{
    static AndMask, XorMask, $, h_cursor
        ,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13 ; system cursors
        , b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13   ; blank cursors
        , h1,h2,h3,h4,h5,h6,h7,h8,h9,h10,h11,h12,h13   ; handles of default cursors
    if (OnOff = "Init" or OnOff = "I" or $ = "")       ; init when requested or at first call
    {
        $ = h                                          ; active default cursors
        VarSetCapacity( h_cursor,4444, 1 )
        VarSetCapacity( AndMask, 32*4, 0xFF )
        VarSetCapacity( XorMask, 32*4, 0 )
        system_cursors = 32512,32513,32514,32515,32516,32642,32643,32644,32645,32646,32648,32649,32650
        StringSplit c, system_cursors, `,
        Loop %c0%
        {
            h_cursor   := DllCall( "LoadCursor", "uint",0, "uint",c%A_Index% )
            h%A_Index% := DllCall( "CopyImage",  "uint",h_cursor, "uint",2, "int",0, "int",0, "uint",0 )
            b%A_Index% := DllCall("CreateCursor","uint",0, "int",0, "int",0
                , "int",32, "int",32, "uint",&AndMask, "uint",&XorMask )
        }
    }
    if (OnOff = 0 or OnOff = "Off" or $ = "h" and (OnOff < 0 or OnOff = "Toggle" or OnOff = "T"))
        $ = b  ; use blank cursors
    else
        $ = h  ; use the saved cursors

    Loop %c0%
    {
        h_cursor := DllCall( "CopyImage", "uint",%$%%A_Index%, "uint",2, "int",0, "int",0, "uint",0 )
        DllCall( "SetSystemCursor", "uint",h_cursor, "uint",c%A_Index% )
    }
}

TOTAL
Posts: 50
Joined: 11 Nov 2016, 13:47

Re: Use Middel mouse Button (Lenovo TrackPoint Button) to scroll like under Linux

Post by TOTAL » 11 May 2021, 08:22

Hi

By accident, I found out a simpler method:
mbutton:: click middle

For some reason, windows 7 and 10 does not read lenovo middle-click properly out of the box but ahk does identify the clicks.

The above line gives full scrolling functionality in browsers, with four directions and speed depending on pointer movement after clicking.

There is another line which sets the mouse to speed higher than windows allows

DllCall("SystemParametersInfo", UInt, 0x71, UInt, 0, UInt, 20, UInt, 0)

Thanks to these two mods, I have been able to drop the use of the dedicated software which was causing more problems than I would consider possible.


Post Reply

Return to “Scripts and Functions (v1)”