多次使用循环

Using Loop multiple times

1。简要

我不明白,如何在不结束脚本的情况下多次使用 Loop 中的循环。


2。设置

我有一个文件 SashaAutoScrolling.ahk,它的内容是:

; First loop, Speed 1
#+1::
Loop
{
    Send {WheelDown}
    Sleep 3000
}

; Second loop, Speed 2
#+2::
Loop
{
    Send {WheelDown}
    Sleep 600
}

; Third loop, Speed 3
#+3::
Loop
{
    Send {WheelDown}
    Sleep 100
}

; Fourth loop, Speed Up
#+0::
Loop
{
    Send {WheelUp}
    Sleep 600
}

; Loop pause
; http://autohotkey.com/board/topic/95308-endless-loop-with-hotkey-pause/?p=600526
#p::Pause

; Exit script
#esc::ExitApp

3。重现步骤

我在任何 PDF 查看器中打开任何 pdf 文件。我在“速度”之间切换:


4。实际行为

If I 运行 Shift+Super+3Shift+Super+0第一次

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍【=19=】

If I 运行 Shift+Super+3Shift+Super+0第二次和下一次,

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‌‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍


5。预期行为

成功切换 «速度» 次数不限。


6。没有帮助

  1. 谷歌搜索,在 Stack Overflow 和 AutoHotkey 论坛中搜索。

7。不提供

  1. 请不要提供使用第三方程序。 Adobe Reader 免费版 works as expected,但我看不懂,请使用此程序,例如 djvudoc 书籍。
  2. 请不要提供使用 built-in mouse auto scrolling。它不舒服,因为有问题快速选择准确舒适的 «speed» 阅读。

通过在Shift+Win+1Shift+Win+2[时模拟鼠标滚轮滚动来滚动当前window =17=],等等按下。 esc 退出循环

#+1:: scrollit(3000)
#+2:: scrollit(600)
#+3:: scrollit(300)
Esc:: abort()

scrollit(delay)
{
  global abort := false
  while (!abort)
  {
    Send {WheelDown}
    Sleep delay
  }
}


abort()
{
  global abort := true
}

此代码使用模拟鼠标滚轮滚动当前 window

Shift+Win+1, Shift+Win+2, 等等...开始滚动。如果已经滚动,只需更新睡眠间隔。 esc 退出

; globals:
;   g_running : true while loop is active
;   g_sleep   : milliseconds to sleep between sending input event
;   g_key     : key to simulate


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; HOTKEY DEFINITIONS

#MaxThreadsPerHotkey 2

#+1:: scrollit(3000)
#+2:: scrollit(600)
#+3:: scrollit(300)
#+0:: scrollit(600,"WheelUp")

#MaxThreadsPerHotkey 1

Esc:: abort()


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; HELPER FUNCTIONS

; send wheeldown every _delay_ microseconds
; if called while loop is already active, just update delay and exit
;
scrollit(sleep, key="WheelDown")
{
  global g_running
  global g_sleep := sleep
  global g_key   := key

  if g_running
    return

  g_running := true

  while (g_running)
  {
    Send {%g_key%}
    Sleep g_sleep
  }
}



abort()
{
  global g_running := false
}

您的代码不起作用,因为默认情况下每个热键只有一个线程。当你这样做时:

Loop
{
    Send {WheelDown}
    Sleep 100
}

你永远不会从这个线程中 return 所以当你第二次调用它时,热键不会触发,你的程序将继续在当前线程中循环。

通过调用 #MaxThreadsPerHotkey 2 解决了它,但这不会让你的代码工作,因为你根本没有 return 来自你的热键线程,Jim U 没有't return 仅来自第一个线程,因此 2 个线程足以让他的解决方案工作。

另一种解决方案是使用计时器,下面将立即更改滚动速度,不需要任何特殊指令,也不依赖于 Autohotkeys 独特的线程模型。

#+1::callSetTimer(3000)
#+2::callSetTimer(600)
#+3::callSetTimer(100)
#+0::callSetTimer(600, "WheelUp")
Esc::SetTimer, scrollTimer, Off

callSetTimer(interval, key := "WheelDown") {
    global currKey := key
    SetTimer, scrollTimer, %interval%

    scrollTimer:
        send, {%currKey%}
    return
}