【问题标题】:AHK Click event while Toggled切换时的 AHK 点击事件
【发布时间】:2020-05-17 20:44:26
【问题描述】:

我发现单独工作的 AHK 代码“正常”,但我需要一个在另一个内部。所以,我有:

1.当您按住鼠标左键时,第一个会快速触发点击:

~$LButton::
    While GetKeyState("LButton", "P"){
    Click
    Sleep .1  ;  milliseconds
    }
return

2。第二个是一个切换脚本,它发送相同的鼠标左键触发事件,但可以通过按下按钮(在本例中为 F8)来打开和关闭

toggle = 0
#MaxThreadsPerHotkey 2

F8::
    Toggle := !Toggle
    While Toggle{
        Click
        sleep 1
    }
return

我需要的是:当我按下 F8 一次时,我希望我的鼠标左键在按住它的同时快速触发点击事件。当我再次按下 F8 时,它应该什么都不做。如果它很重要,我需要在游戏中按住 Ctrl 的同时点击这些点击。 我已经阅读了一些关于 AHK 的信息并尝试了此代码,但它与我想要的没有任何关系:

toggle = 0
#MaxThreadsPerHotkey 2

F8::
    Toggle := !Toggle
    If Toggle{
~$LButton::
    While GetKeyState("LButton", "P"){
    Click
    Sleep .5  ;  milliseconds
    }
    }
return

这给了我关于缺少“返回”的错误,但我尝试了很多合并变体。

另外,我已经阅读了很多关于 MaxThreads 的内容,但仍然不知道为什么应该有 2 个以及它是做什么用的。

【问题讨论】:

    标签: autohotkey


    【解决方案1】:

    首先,不确定您尝试发出Sleep 命令的时间,但十进制数字不起作用。只是整数,它们以毫秒为单位。 .1.5 可能被解释为 0,但不确定。此外,睡眠命令并不像您想象的那么准确。阅读文档中的备注部分了解更多信息。

    其次,您不应该在热键标签内循环。由于 AHK 不提供真正的多线程,这是不好的做法。
    不过,归根结底,如果这就是您的全部脚本,它不会有任何区别。
    如果您想开始编写更好更大的脚本以供将来参考,我将向您展示timers 的用法。它们应该用于此目的。

    LButton::SetTimer, MyCoolFunction, 0 ;when LButton is clicked down start a timer with the shortest possible period
    LButton Up::SetTimer, MyCoolFunction, Off ;when LButton is released, stop the timer
    
    MyCoolFunction()
    {
        Click
    }
    

    对于您的切换版本,您不想在热键标签内循环:

    F8::
        toggle := !toggle
        if(toggle) ;if true
            SetTimer, MyCoolFunction, 0
        else
            SetTimer, MyCoolFunction, Off
    return
    
    MyCoolFunction()
    {
        Click
    }
    

    如果您不知道 toggle := !toggle 究竟是什么,并且想知道,您可以阅读我之前的回答 here。它还展示了如何将代码压缩为一行代码。并且还解释了为什么不需要在脚本顶部定义变量 toggle(就像您所做的那样)。

    关于#MaxThreadsPerHotkey2:
    这是因为 AHK 不提供真正的多线程。当您循环播放热键定义时,该热键被完全锁定。您不能再次运行热键来停止循环。除非,您将热键设置为使用多个线程(最好将它们称为实例)。
    这样您就可以再次启动热键,并且可以更改 toggle 变量的值,以便停止循环。
    但同样,您不应该在热键中循环。如果您使用计时器,就像我在上面展示的那样,您无需担心这种肮脏的解决方法。


    然后到您要创建的新代码。
    首先是关于你的尝试出了什么问题。我想这是一个好主意,但它甚至还没有接近。很难说它到底有什么问题,因为它甚至还没有接近工作。我想我能说的是热键标签(hotkey::)在脚本启动时被评估一次,然后再也不会。所以你不能把它们放在一些运行时逻辑中。 Hotkey 命令将用于此目的。

    幸运的是,您的问题实际上比这简单得多。您无需乱用Hotkey 命令。
    您要做的就是打开/关闭热键。 Suspend 就是这样使用的:
    F8::Suspend
    现在,每次按 F8 时,脚本的热键(和热字串)都会打开/关闭。

    这是你的最终脚本:

    LButton::SetTimer, MyCoolFunction, 0 ;when LButton is clicked down start a timer with the shortest possible period
    LButton Up::SetTimer, MyCoolFunction, Off ;when LButton is released, stop the timer
    
    MyCoolFunction()
    {
        Click
    }
    
    F8::
        Suspend
        SetTimer, MyCoolFunction, Off ;set the timer off just incase we hadn't released LButton before we hit F8
    return
    

    【讨论】:

    • 非常感谢,但这并不能解决问题。从头开始 - 我需要一个可以打开/关闭的脚本,所以在打开之前它不会影响任何东西。打开时,它应该在我按下鼠标左键时不断快速地发送点击事件。它实际上应该为我解决什么:我正在玩流放之路,有一个 5x12 网格的库存。当您进行交易时,您可以按住 Ctrl 键单击项目以将其发送。因此,对于完整的库存,您需要 60 次点击。我想切换脚本,按住 Ctrl,按下鼠标按钮,然后将鼠标悬停在整个网格上。
    • 这正是答案中的代码所做的。也许Ctrl 部分是您认为没有的原因。对热键使用* 修饰符,这样即使按下额外的修饰符,它们也会触发。 (例如:*LButton::
    • 有了“*”,它就可以正常工作了!我还添加了“Suspend SetTimer, MyCoolFunction, Off”以在开始时禁用 - 是草率还是好的?
    • 如果您希望它开始暂停,请确保您可以将Suspend 设置为脚本的第一行。不需要额外的检查来关闭计时器。
    猜你喜欢
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2023-02-06
    相关资源
    最近更新 更多