【问题标题】:How to grab the scrolling amount in one window?如何在一个窗口中抓取滚动量?
【发布时间】:2018-01-26 15:11:04
【问题描述】:

这是scroll two windows simulteneously 的第一步,第二步是找到一种方法将该金额应用于其他程序。但我真的不知道从哪里开始,我从谷歌看到的只是修改鼠标滚动的行为,而不是一个窗口中的滚动量 .使用它而不是听键的优点:

  • 滚动将是无缝的,因为其他程序在后台滚动
  • 点击滚动条有效
  • 不同的滚动速度不会影响比较
  • 文本编辑器中的移动行不会在 PDF 查看器中滚动页面

【问题讨论】:

  • 似乎是一个复杂的问题。对于一个简单的解决方案,我会尝试将相同的滚动事件发送到第二个窗口(只需要了解如何在不丢失当前焦点的情况下将事件发送到特定应用程序)。但是如果你想“同步”滚动位置,我认为这真的很难。阅读滚动位置和滚动范围本身太难了——我试过一次但很快就放弃了。
  • @MikhailV 你当时是怎么做到的?
  • 我在 AHK 的论坛上阅读过相关主题,例如这个:autohotkey.com/board/topic/97328-scrollbar-position 有一些其他相关主题的链接,但坦率地说,这对我来说太多了。所以我想读然后写滚动位置。

标签: scroll scrollview autohotkey


【解决方案1】:

我可以告诉你我会做什么,但这不会很有趣......

假设文本大致均匀分布(它可能不在这样的两种语言之间,以及具有不同文本大小和宽度的两个窗口,在你开始工作之前真的要仔细考虑这一点),那么目标是强制两者滚动条相对于它们的整体处于相同的百分比。所以你需要做的是编写一个函数来确定每个滚动条的百分比。我会截屏两个窗口并裁剪出滚动条的重要部分,如下所示:

特别是向上和向下按钮,滚动手柄的顶部,滚动手柄的底部。将它们保存在自己的文件中。对两个窗口都这样做,以防它们绘制滚动条的方式略有不同。

现在是棘手的部分。编写一个执行以下操作的函数:图像搜索最右边 25 像素或指定窗口的顶部按钮。底部按钮也一样。手柄顶部也是如此。手柄底部也一样。使用它来确定您的窗口在哪里。

SetTitleMatchMode, 2 ; so it matches the end of the title
WinGetPos , X, Y, Width, Height, LibreOffice Writer ;exact substring of window name required

使用类似的方法来查找滚动条部分。

CoordMode, Pixel , Screen ;so image search searches entire screen
barwidth = 25 ; make sure it's more than the bar is wide.
ImageSearch, TopButtonX, TopButtonY, X+Width-barwidth , Y, X+Width, Y+Height, TopButton.bmp ; no jpg, fuzzy edges make searches fail

然后做一些数学运算,比如:

TopButtonY := TopButtonY+TopButtonImageHeight ; because we only care about the position of the bottom of the button.
BottomHandleY := BottomHandleY+BottomHandleImageHeight   ; because we only care about where the bottom of the handle is.
HandleHeight := TopHandleY - BottomHandleY ; how tall the scroll handle is
TotalHeight := TopButtonY - BottomButtonY - HandleHeight ;how tall the scroll field is
HandleOffset := TopHandleY - TopButtonY ;how far it is from the top
HandlePercent := HandleOffset / TotalHeight ; the part we care about. return this value

通过这样的函数,您可以知道每个窗口的滚动程度。剩下的就是发送滚动命令。有几个选择。

; ControlSend , Control, Keys, LibreOffice Writer
ControlSend , Control, {Pgdown}, LibreOffice Writer ; or {Pgup}
ControlSend , Control, {WheelUp}, LibreOffice Writer ; or {wheeldown}
ControlSend , Control, {Up}, LibreOffice Writer ; or {down}

如果它允许您在窗口处于非活动状态时使用向上/向下箭头移动插入符号,这可能是最精确的选项,即使需要更长的时间。最快最精确的方法是也使用控制发送来模拟单击拖动。要使用 ControlSend,您需要弄清楚您正在处理哪个控件。 WindowSpy 可以帮助您。

所以首先:找到两个窗口的滚动位置。其次确定哪个窗口是活动的。第三,将非活动窗口推向正确的方向。重复直到它们在一定的公差范围内(否则它会无限地上下反弹)。

这一点我怎么强调都不为过,但在尝试此操作之前,请确保将滚动条置于大致相同的位置已经足够接近。如果不是,您将浪费大量时间来摆弄它。请记住,文本越长,它就越不准确。

如果可以选择,我肯定会考虑将两个窗口的内容复制到一个程序中,让您可以更多地访问控件(或者更好的专门用于此目的的程序)。如果您有更多的访问权限,您可以使用分节符来更精确地排列文本。

如果您真的只想并排查看两个文本(并且段落确实排成一行),您可以找到一个文本编辑器来告诉您如下信息:

如果 autohotkey 允许您阅读该信息的文本,您可以将 PDF 复制到 autohotkey 的内存中(以行分隔)并使用 autohotkey 在可编辑文档中移动时仅显示 PDF 的相应段落。

希望我说的对你有所帮助,祝你好运。

【讨论】:

  • 你认为图片中的手柄位置大致相同吗?我所能确定的是滚动量是相同的。看来要抓到这个不容易啊,要靠程序来提供这上面的API,是吗?
  • 它们看起来好像处于大致相同的位置,但您非常接近顶部,即 309 页投影到 520 像素上。每页大约 2 个像素,几乎没有出错的余地。如果页面数超过像素数,即使文本相同并且滚动条检测器写得很好,你也肯定会遇到问题。这不是理想的方法。
  • 如果保证段落在两种语言之间对齐,这会简化事情:我假设您只是将 PDF 程序用作文本查看器,并且编辑器 (libreoffice) 可以也改变。因此,您所需要做的就是找到一个编辑器,使行号(字面意思是在插入符号之前有多少个 '\n')可用于自动热键(或任何最终最方便的语言)。然后你可以把PDF的内容复制到剪贴板,用'\n'分割,然后用你自己的程序把焦点放在与编辑器当前拥有的段落相匹配的段落上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 2022-01-05
相关资源
最近更新 更多