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% )
}
}