#1 - 2022-7-17 11:44
冈崎羽未鹰原汐 (二阶堂芽爱 小河坂青空)
发送鼠标滚轮 WheelDown ,调用一次相当于滚轮滚动一格。通常用循环次数来调整滚动速度。显然,这样滚动长页面时断断续续,很不平滑。
有没有更平滑、精度更高的模拟滚动方式,或者让每次滚轮格数小于1行?

已知AHK是可以接收<1格的输入

但当我尝试<1格的输出,如  Send, {WheelDown 0.8} ,它不起作用。


或者,AHK能不能模拟笔记本触控板双指滑动?这样是非常平滑的。
#2 - 2022-7-17 17:32
(miaow~~~)
没用过ahk  也不知道具体要平滑滚动来干什么 ...

先想到的是 在这些实现有问题的情况下 能不能
先捕捉滚动条的位置 然后模拟鼠标抓住滑块以多少刷新帧一像素的速度往下拖动

然后翻了下 你看看这里面有没有什么可参考的地方
https://www.autoahk.com/help/aut ... dex.htm#NumpadMouse
看起来有移速加速的实现 看能不能弄出来平滑效果 不知道有没有帮助
#2-1 - 2022-7-17 19:07
冈崎羽未鹰原汐
感谢回复(bgm105)
具体要平滑滚动来干什么
比如说摇杆模拟滚轮,摇杆幅度越小滚动速度越慢,最慢时每次循环滚动<=1行。
(同类脚本最慢都是每次滚3行,直接映射滚轮键受限于win系统的设置)
捕捉滚动条的位置
可惜不泛用,没有滚动条的窗口用不了(bgm38)
这里面有没有什么可参考的地方
可惜了,这个脚本也是通过循环次数调用WheelDown来实现所谓的变速,最慢还是每次循环滚3行。
These options are affected by the mouse wheel speed  adjusted on Control Panel. If you don't have a mouse with wheel, the default is 3 +/- lines per option button press

意思是修改win设置 就可以改变脚本调用WheelDown的滚动行数。

但这样使用普通鼠标时又不爽了(bgm38)所以我想还是不要从“映射滚轮”这个方向入手,找找有没有不用滚轮的滚动方式,比如映射笔记本触摸板
#2-2 - 2022-7-19 18:29
MousHu
看到#3想起来 好久没用中键拖动了 ...
但再次感受了下 适用范围是有点小窄 ...

#4看一眼大概就是直接解决方案了 ... 不知道LZ试出来没 ~

#5 好吧 ......
#3 - 2022-7-17 19:24
网页滚动的话可以直接映射方向键,或按住鼠标中键移动鼠标。

刚好有个用键盘映射鼠标移动的脚本,试了一下可以用于中键滚动:

(注:在不知名地方抄的改了点,没有检查代码也不完全清楚实现,还有很多额外的东西,键位是 QERF)


#NoEnv
#SingleInstance Force
SetBatchLines -1

SetTimer, DebugView, 75

initSpeed := speed := 50
initDelay := delay := 1 ; caution with delay = 0

Loop
{
        xDir := yDir := 0
        (up := GetKeyState("r", "P")) ? --yDir
        (down := GetKeyState("f", "P")) ? ++yDir
        (left := GetKeyState("e", "P")) ? ++xDir
        (right := GetKeyState("q", "P")) ? --xDir

        if (xDir && yDir)
        {
                x := Round(xDir * speed * 0.707)
                y := Round(yDir * speed * 0.707)
        }
        else
        {
                x := xDir * speed
                y := yDir * speed
        }

        mouseMove(x, y, delay)
}
Return

^Esc::ExitApp
*Numpad5::speed := initSpeed, delay := initDelay ; reset all

; inc/dec pixel movement step size
*Numpad7::++speed
*Numpad1::(--speed < initSpeed) ? speed := initSpeed

; inc/dec sleep delay
*Numpad9::++delay
*Numpad3::(--delay < initDelay) ? delay := initDelay

; suppress native function
*f::
*e::
*q::
*r::
Return

DebugView:
{
       
        ToolTip, % Format(dbg
                , speed
                , delay
                , (invertAxis ? "Inverted" : "Normal")
                , x
                , xDir
                , y
                , yDir
                , up
                , left
                , down
                , right), 100, 200, 20
Return
}

mouseMove(x, y, delay) {
        DllCall("mouse_event", "UInt", 0x0001, "UInt", x, "UInt", y, "UInt", 0, "UInt64P", 0)
        DllCall("Sleep", "UInt", delay)
}

1::MouseMove, -10000, 0, 0, R
2::MouseMove, 10000, 0, 0, R
#4 - 2022-7-17 20:51
(情更怯)
使用 DllCall   调用 Windows的 API
文档ScrollWindowEx

SW_SMOOTHSCROLL   查了一下是 0x10
#define SW_SMOOTHSCROLL             0x0010
hwnd 这个句柄应该需要使用 AHK 的  WinGet 拿到

DllCall("User32.dll\ScrollWindowEx", "ptr", hwnd, "int", x, "int", y, "ptr", 0, "ptr", &rect, "ptr", 0, "ptr", 0, "Uint", 16)
#5 - 2022-7-19 22:17
(二阶堂芽爱 小河坂青空)
很遗憾,折腾了大半天#4的代码,虽然调用dll成功且返回值正常,但是似乎没有反应(bgm38)



我目前找到最接近成功的解决方案是:

; 高精度滚轮,以像素为单位滚动鼠标所在窗口
; http://msdn.microsoft.com/en-us/library/windows/desktop/ms645617(v=vs.85).aspx
PostMW(deltay, deltax := 0)
{
    MouseGetPos,x,y, id, control ; 获取鼠标所在窗口id
    Modifiers := 0x8*GetKeyState("ctrl") | 0x1*GetKeyState("lbutton") | 0x10*GetKeyState("mbutton")
    |0x2*GetKeyState("rbutton") | 0x4*GetKeyState("shift") | 0x20*GetKeyState("xbutton1")
    |0x40*GetKeyState("xbutton2")

    if (deltay != 0)
        PostMessage, 0x20A, deltay << 16 | Modifiers, y << 16 | x ,, ahk_id %id%
    if (deltax != 0)
        PostMessage, 0x20E, deltax << 16 | Modifiers, y << 16 | x ,, ahk_id %id%
}

f3:: ;向上
    PostMW(1)
return
f4:: ;向下
    PostMW(-1)
return
f5:: ;向左
    PostMW(0,-1)
return
f6:: ;向右
    PostMW(0,1)
return

它很完美的在大部分软件窗口中以像素为单位顺滑地滚动。但有些窗口不支持这个接口,比如win的资源管理器,此时这代码不生效。
我试图再找个方法判断它是否生效,否 则转回用传统方式(bgm38)

@MousHu
@拿月亮自刎
#5-1 - 2022-7-20 10:14
拿月亮自刎
ScrollWindowEx 设置 SW_SMOOTHSCROLL 我也没成功。


-::
dx := 0
dy := 50
ControlGet, OutputVar, Hwnd,, Edit1, ahk_exe NOTEPAD.EXE
Result := DllCall("User32.dll\ScrollWindowEx", "Ptr", OutputVar, "Int", dx, "Int", dy, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Ptr", 0, "Uint", 0)
return


用记事本测试了滚动功能。滚动起来有残影,滚动不依赖滚动条。
这个API不好用
#6 - 2022-7-19 22:44
(象牙门的梦,午夜前的景。)
快速滚动倒有,“平滑滚动”还真第一次见。
如果是滑滚时的残影让你感到焦虑的话,或许换个高质量的4k屏能有效缓解。