Universal middle button scrolling with laptop with mouse pointer in keyboard

autohotkeylaptopmouse

I have a new HP ZBook G6. It has two mouse button rows, the top one for the mouse pointer in the middle of the keyboard, the lower one for the trackpad. I have completely disabled the trackpad (and the bottom row of mouse buttons); I only use the mouse pointer and the top row of mouse buttons. So, my post here refers only to the mouse pointer and the upper middle mouse button, circled in red in this photo here:

HP ZBook 17 G6 keyboard and touchpad

I use the middle button primarily to scroll windows in conjunction with the pointer: I press and hold the middle button (with my thumb) and simultaneously move the pointer to scroll in the direction and speed that I want. This works well in many programs, but not in others. It works well with web browsers like Firefox and Chrome and many applications like Word and Excel, but it does not work at all with others, most notably Windows Explorer, Windows configuration windows, Microsoft OneNote, etc.

I also have a Lenovo ThinkPad T510 which can scroll well with pointer and middle button in all of these applications, so, as far as I can tell, the applications I've named all support middle-button mouse scrolling.

I have done a lot of searching on this topic but have not been able to find a suitable solution. (Among other things, I have updated to the latest drivers from the HP website.) I have also tried an AutoHotKey script (AutoHotkey scrolling & middle click & mouse acceleration), but it made my mouse go out of whack, and the script is too complex for me to debug, so I didn't pursue that further.

I would appreciate any guidance to get middle-button scrolling working on these applications (Windows Explorer, Microsoft OneNote, etc.) on my laptop. This is only a minor occurrence, but it is one I encounter many times every day, so I would like to get it working.

Best Answer

I did some more searching on AutoHotKey solutions and I found a script by ahp that, after a minor bug fix, works for me:

; Description: Scroll Explorer on middle mouse button drag
; Permalink: https://autohotkey.com/boards/viewtopic.php?t=43715
; Author: aph
; Version: 0.2
$*MButton::
    MouseGetPos, CursorX, CursorY, Window, ClassNN
    WinGetTitle, Title, ahk_id %Window%
    WinGetClass, ahk_class, ahk_id %Window%
    WinGet ahk_exe, ProcessName, ahk_id %Window%
    WinGet ahk_PID, PID, ahk_id %Window%
    WinGetText, VisibleText, ahk_id %Window%
    MouseGetPos, CursorX_ended, CursorY_ended, Window_ended, ClassNN_ended
    WinGetClass, ahk_class_ended, ahk_id %Window_ended%
    WinGet ahk_exe_ended, ProcessName, ahk_id %Window_ended%
    AllowedApp := ahk_exe = "explorer.exe" or ahk_exe = "mmc.exe" or ahk_exe = "systempropertiesadvanced.exe" or ahk_exe = "filezilla.exe" or ahk_exe = "7zFM.exe"
    AllowedText := InStr(VisibleText, "Tree View") or InStr(VisibleText, "FolderView")
    LimitedApp := ahk_exe = "cmd.exe"
    DisabledApp := ahk_class_ended = "Shell_TrayWnd" or ahk_class_ended = "WorkerW"
    if (AllowedText >= 1)
        AllowedText = 1
    If (DisabledApp) {
        SendInput, {MButton Down}
        Return
    }
    Else If (!AllowedApp and !LimitedApp and !AllowedText) {
        SendInput, {MButton Down}
        Return
    }
    Else {
        If (AllowedApp) {
            SendInput, {MButton}
        }
        MiddleScroll := 1
        SetSystemCursor("SIZEALL")
        Sensitivity = 10 ; How far the middle mouse wheel has to be dragged before scrolling is triggered
        MouseGetPos, X1, Y1, , c, 2
        OrigTimer := 50 ; How quickly the file list scrolls
        SetTimer, MBScroll, %OrigTimer%
        MBScroll:
            MouseGetPos, X2, Y2
            Distance := Abs(Y2-Y1)
            If (Distance >= Sensitivity) {
                Rounded := % Round((Distance / 200)**1.25+1)
                DllCall("SystemParametersInfo", UInt, 0x69, UInt, Round(Ln(Rounded)+1), UInt, 0, UInt, 0) ; Vary lines scrolled by distance of drag 
                Percent := (A_ScreenHeight - (Max(Y1, Abs(Y1-A_ScreenHeight)) - Distance)) / A_ScreenHeight * 100
                Timer := Round(OrigTimer - (OrigTimer/2*Percent/100))
                SetTimer, MBScroll, %Timer%
                SendInput, % "{Blind}{Wheel" (Y2 > Y1 ? "Down" : "Up") " " Rounded "}"
            }
        Return
        $*MButton Up::
            DllCall("SystemParametersInfo", UInt, 0x69, UInt, 3, UInt, 0, UInt, 0) ; Set back to 3 lines scrolled
            SetTimer, MBScroll, off
            SetSystemCursor()
            MiddleScroll := 0
            SendInput {MButton Up}
            SetSystemCursor(Cursor="") {
                SystemCursors := "32512IDC_ARROW|32513IDC_IBEAM|32514IDC_WAIT|32515IDC_CROSS|32516IDC_UPARROW|32642IDC_SIZENWSE|32643IDC_SIZENESW|32644IDC_SIZEWE|32645IDC_SIZENS|32646IDC_SIZEALL|32648IDC_NO|32649IDC_HAND|32650IDC_APPSTARTING|32651IDC_HELP"
                If (Cursor = "")
                    Return DllCall("SystemParametersInfo", "UInt", 0x57, "UInt", 0, "UInt", 0, "UInt", 0) 
                If (StrLen(SystemCursors) = 221)
                    Loop, Parse, SystemCursors, |
                        StringReplace, SystemCursors, SystemCursors, %A_LoopField%, % DllCall("LoadCursor", "UInt", 0, "Int", SubStr(A_LoopField, 1, 5)) A_LoopField
                If !(Cursor := SubStr(SystemCursors, InStr(SystemCursors "|", "IDC_" Cursor "|") - 5 - p := (StrLen(SystemCursors) - 221) / 14, 5))
                    MsgBox, 262160, %A_ScriptName% - %A_ThisFunc%(): Error, Invalid cursor name!
                Else
                    Loop, Parse, SystemCursors, |
                        DllCall("SetSystemCursor", "UInt", DllCall("CopyIcon", "UInt", Cursor), "Int", SubStr(A_LoopField, 6, p))
                }
        Return
    }
Return