New, much simpler solution using AutoHotKey
I've been looking for a way to avoid freezes caused by constant checks for the active window and also an overall simpler code solution. Here's what I made:
#ifWinActive ahk_class Framework::CFrame
WheelUp::
ControlGetFocus, control, A
Loop 3
SendMessage, 0x115, 0, 0, %control%, A
Return
#ifWinActive ahk_class Framework::CFrame
WheelDown::
ControlGetFocus, control, A
Loop 3
SendMessage, 0x115, 1, 0, %control%, A
Return
Change the Loop 3
to Loop 5
or however many lines you wish for one movement of the wheel to scroll.
old solution using AutoIt
Note: this solution may cause stuttering and occasional freezes on older CPUs or at full CPU load.
I whipped up an AutoIt script which detects the cursor within the notes list area and if you scroll up or down, makes a click on the "up" and "down" buttons on the scrollbar. This works with multiple OneNote windows. You don't have to have focus on the window for the scroll to work, just hover over that list:
#include <AutoItConstants.au3>
#include <MsgBoxConstants.au3>
#include <MouseOnEvent.au3> ; get it from https://www.autoitscript.com/forum/topic/64738-mouseonevent-udf/
#include <WinAPI.au3>
#include <Misc.au3>
_MouseSetOnEvent($MOUSE_WHEELSCROLLUP_EVENT, 'MouseWUp')
_MouseSetOnEvent($MOUSE_WHEELSCROLLDOWN_EVENT, 'MouseWDown')
Opt("WinTitleMatchMode", 2) ; 2 - substring mode
Global $clicks = 3 ; how many items to scroll per scroll, change this to 5, 8, 13, 42 or however fast you wanna scroll
Func MouseWUp($iEvent)
If StringInStr(WinGetTitle($hWin), " - OneNote") Then
; check if cursor is within the notes list and not anywhere else
Local $cur = MouseGetPos()
Local $handle = $hWin ;WinGetHandle("[ACTIVE]")
Local $wpos = WinGetPos($handle) ; returna array of x,y,w,h
Local $cpos = ControlGetPos ($handle, "", "[CLASS:NetUIHWND; INSTANCE:5]")
;MsgBox($MB_SYSTEMMODAL, "title", "win2:" & $wpos[2] & "; win3:" & $wpos[3] & "; cp2:" & $cpos[2] & "; cp3:" & $cpos[3])
If ($cur[0] > $wpos[0] + $wpos[2] - $cpos[2]) And ($cur[0] < $wpos[0] + $wpos[2]) Then
Local $x = $cpos[2] - 2
Local $y = 58
ControlClick($handle, "", "[CLASS:NetUIHWND; INSTANCE:5]", "left", $clicks, $x, $y)
EndIf
EndIf
EndFunc
Func MouseWDown($iEvent)
If StringInStr(WinGetTitle($hWin), " - OneNote") Then
Local $cur = MouseGetPos()
Local $handle = $hWin ;WinGetHandle("[ACTIVE]")
Local $wpos = WinGetPos($handle)
Local $cpos = ControlGetPos ($handle, "", "[CLASS:NetUIHWND; INSTANCE:5]")
If ($cur[0] > $wpos[0] + $wpos[2] - $cpos[2]) And ($cur[0] < $wpos[0] + $wpos[2]) Then
Local $x = $cpos[2] - 2
Local $y = $cpos[3] - 8
ControlClick($handle, "", "[CLASS:NetUIHWND; INSTANCE:5]", "left", $clicks, $x, $y)
EndIf
EndIf
EndFunc
; https://stackoverflow.com/a/11270659
Func _WindowFromPoint($iX,$iY)
Local $stInt64,$aRet,$stPoint=DllStructCreate("long;long")
DllStructSetData($stPoint,1,$iX)
DllStructSetData($stPoint,2,$iY)
$stInt64=DllStructCreate("int64",DllStructGetPtr($stPoint))
$aRet=DllCall("user32.dll","hwnd","WindowFromPoint","int64",DllStructGetData($stInt64,1))
If @error Then Return SetError(2,@error,0)
If $aRet[0]=0 Then Return SetError(3,0,0)
Return $aRet[0]
EndFunc
Local $hControl, $hWin, $hOldWin, $aMousePos
$hOldWin = ""
While True ;Not _IsPressed("1B")
$aMousePos = MouseGetPos()
$hControl=_WindowFromPoint($aMousePos[0],$aMousePos[1])
; Since _WindowFromPoint() can return 'sub' windows, or control handles, we should seek the owner window
$hWin=_WinAPI_GetAncestor($hControl,2)
If $hWin <> $hOldWin Then
;TrayTip("Window Info","Window under mouse = " & WinGetTitle($hWin), 1)
$hOldWin = $hWin
EndIf
Sleep(10)
WEnd
I haven't figured out how to prevent the scrolls from affecting the note page itself. If someone finds a way to block the scroll event from reaching the main note area from within the notes list area, please share your solution so we could combine the scripts for best results.