如何简化这个 AHK 脚本?GetKeyState 还是 KeyWait?

如何简化这个 AHK 脚本?GetKeyState 还是 KeyWait?

我有一个脚本,其中包含三种类似这样的变体,用于 50 多个键。我想知道,我该如何缩小它?

; Press "a" = Option 1 (with 500 ms sleep)
; Press "Ctrl + a" = Option 2 (with 500 ms sleep)
; Press "Ctrl + Alt + a" = Option 1 (with 1000 ms sleep)

a::
    Send, {Enter}
        Sleep, 100
    Send, 1
        Sleep, 500
    Send, {Enter}
Return

^a::
    Send, {Enter}
        Sleep, 100
    Send, 2
        Sleep, 500
    Send, {Enter}
Return

^!a::
    Send, {Enter}
        Sleep, 100
    Send, 1
        Sleep, 1000
    Send, {Enter}
Return

这正是我想要的效果。重要的是所选的选项(1 或 2)以及Sleep“选项 1”的两个不同值。我希望它能像这样工作。

我尝试使用GetKeyState(即使推荐使用此功能,而不是此功能)但没有成功。两个问题:

  1. 我无法像原始版本那样在“a”键之前按下 Ctrl 或 Alt。因此,我不得不将 a 放在Sleep开头,并在第一秒按下修饰键。
  2. 但它仍然不起作用,因为如果我不通过按下实际键(Ctrl 和/或 Alt)来填充这些变量,它就会出现错误消息。

我可以找到两种解决方法,但我觉得它终究还是行不通。代码如下:

a::
    Sleep, 1000
    GetKeyState, AltState, Alt
    GetKeyState, CtrlState, Ctrl
    Send, {Enter}
    if (CtrlState = D) {
        Send, Option 2
            Sleep, 500
    }
    else {
        Send, Option 1
        if (CtrlState = D and AltState = D) {
            Sleep, 1000
        }
        else {
            Sleep, 500
        }
    }
    Send, {Enter}
Return

这次失败后,我考虑过使用多个KeyWait命令,但我不再确定了。

TL;DR。如果有经验丰富的 AHK 用户能够帮助提供更短、更高效的替代方案或GetKeyState变体解决方案(或对其进行调试),我们将不胜感激!


编辑:使用通配符“*”并将 GetKeyState 作为函数,代码比原始代码运行得更好,并且包含的​​重复更少,如果需要,我可以更容易地在以后进行修改。

*a::
    Send, {Enter}
    Sleep, 100
    if GetKeyState("Control", "P") and not GetKeyState("Alt", "P") {
        Send, 2
        }
    else {
        Send, 1
        }
    if GetKeyState("Alt", "P") and GetKeyState("Control", "P") {
        Sleep, 1000
        }
    else {
        Sleep, 500
        }
    Send, {Enter}
Return

答案1

我不清楚您实际上想要解决什么问题。您只是想将第一个脚本合并为更高效的代码?还是第一个脚本无法以您希望的方式运行?

您可以在热键前使用星号修饰符(“*”),以允许它在已按下修饰符的情况下触发(然后,如果它们存在或不存在,则必须适当处理它们,您的示例代码部分做到了这一点)。我相信这解决了您列出的第一个问题。

IE,

*a::

这将触发a、、、、、、等。#a+a^a!a^!a

您还可以GetKeyState()在不分配中间状态变量的情况下进行调用并检查所按下的修饰键。

If GetKeyState("Control", "P") && GetKeyState("Alt", "P") {
}

相关内容