使用 AutoHotKey 的全新、更简单的解决方案

使用 AutoHotKey 的全新、更简单的解决方案

通常,当您将光标移动到带有滚动条的列表内时,鼠标滚轮会滚动该列表。然而,在 OneNote 中,当光标确实位于笔记列表内时(此图中的蓝色区域),我只能滚动笔记页面本身:

漂亮的动图,如果你没看到的话真是太遗憾了

页面是否可以滚动似乎并不重要,当鼠标滚轮位于蓝色区域内时,它不会滚动笔记列表。我只能通过使用鼠标左键与滚动条交互来滚动它。

这似乎是 Windows 7 的问题(可能是操作系统,也可能是 7 版 OneNote 有此错误)。Windows 10 似乎根本没有这个问题。

答案1

使用 AutoHotKey 的全新、更简单的解决方案

我一直在寻找一种方法来避免因不断检查活动窗口而导致的冻结,以及一个整体更简单的代码解决方案。这是我所做的:

#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

将 更改Loop 3Loop 5,或者任意多行,只需转动滚轮一次即可滚动。


使用 AutoIt 的旧解决方案

注意:此解决方案可能会导致旧 CPU 或 CPU 满负荷时出现卡顿和偶尔死机。

我编写了一个 AutoIt 脚本,它可以检测笔记列表区域内的光标,如果您向上或向下滚动,则会单击滚动条上的“向上”和“向下”按钮。这适用于多个 OneNote 窗口。您不必将焦点放在窗口上,只需将鼠标悬停在该列表上即可滚动:

#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

我还没想出如何防止滚动影响笔记页面本身。如果有人找到一种方法来阻止滚动事件从笔记列表区域到达主笔记区域,请分享您的解决方案,以便我们可以组合脚本以获得最佳效果。

相关内容