【问题标题】:Why does shortcut don't have the same behavior when applied on multiple keys为什么快捷方式在多个键上应用时不具有相同的行为
【发布时间】:2013-09-04 03:13:13
【问题描述】:

这是我的问题。

我编写了一个小音量控制脚本来控制音量,就像 Windows 使用它的 Microsoft 键盘快捷键一样。

我有 3 个功能。两个控制音量,另一个控制按键的保持状态以继续提高或降低我的音量

这是代码。

    ;//**************************************************
    ;// Volume Mouse Control
    ;//**************************************************
    VolumeUp(p_numberToDecrease, p_holdToDecrease = true)
    {
        Send {Volume_Up %p_numberToDecrease%} 

        if(p_holdtoDecrease)
        {
            VolumeHoldTreatment("Up")
        }
    }

    VolumeDown(p_numberToDecrease, p_holdToDecrease = true)
    {
        Send {Volume_Down %p_numberToDecrease%} 

        if(p_holdtoDecrease)
        {
            VolumeHoldTreatment("Down")
        }
    }

    VolumeHoldTreatment(p_treatment)
    {
        Count := 0  

        Sleep 300
        While GetKeyState(A_ThisHotkey,"P")
        {
            ++Count
            if(p_treatment == "Up")
            {   
                Send {Volume_Up %Count%}
            }
            else
            {
                Send {Volume_Down %Count%}
            }
            Sleep 25
        }
    }

当我像这样↓调用快捷方式中的方法时,它们可以正常工作。

我可以提高和降低音量。

如果我按住按键超过 300 毫秒,音量将继续上升/下降。

    XButton1:: VolumeDown(1)
    XButton2:: VolumeUp(1)

但是当我添加我的静音快捷键↓

    XButton1 & XButton2:: Send {Volume_Mute}
    XButton2 & XButton1:: Send {Volume_Mute}

保持行为不正常。我需要按两次 Button1/2 才能调用保持行为。为什么?

感谢您的帮助

【问题讨论】:

    标签: autohotkey


    【解决方案1】:

    组合

    XButton1 & XButton2:: Send {Volume_Mute}
    XButton2 & XButton1:: Send {Volume_Mute}
    

    制作XButton1XButton2 prefix keys。前缀键的行为略有不同。它们只在释放时触发,这是无法避免的:例如,如果您按XButton1,则可能会按XButton2,从而触发组合。只有当你没有按下任何额外的按钮时,XButton1::才会被触发,另一方面在它被释放之前无法确定。
    对于您的 VolumeHoldTreatment() 函数:在这种情况下,不需要带有 GetKeyState() 的循环。当您按住它时,普通键将继续触发。这就是为什么有些人能够用太多的 O 字母生成单词LOL,而只需敲击三个键。
    忽略静音功能,这样的事情会完全一样:

    XButton1::Send, {Volume_Down}
    XButton2::Send, {Volume_Up}
    

    避免使用XButton1 & XButton2 之类的组合,从而防止出现前缀键将为您节省很多麻烦,例如像这样完成:

    XButton1::
        if( GetKeyState("XButton2") ) {
            Send, {Volume_Mute}
        } else {
            Send, {Volume_Down}
        }
    return
    
    XButton2::
        if( GetKeyState("XButton1") ) {
            Send, {Volume_Mute}
        } else {
            Send, {Volume_Up}
        }
    return
    

    这几乎可以完美运行:如果您只按住一个按钮,它将一次又一次地触发,不断发送Volume_UpVolume_Down。只要同时按下两个键,就会发生两件事:

    1. 您首先按下的键将停止触发
    2. 另一个密钥将发送{Volume_Mute}

    不幸的是,静音时有两个缺点:a) 在{Volume_Mute} 之前总会发送至少一个Volume_UpVolume_Down(当您花很长时间按下第二个按钮时甚至更多)已发送。 b) 如果您长时间按住两个键,{Volume_Mute} 将被一遍又一遍地发送;但这至少不会改变结果。

    更新:

    XButtons 确实表现出一种奇怪的行为,即当它们被按住时不会继续射击。看看这段代码:

    XButton1::
        if( GetKeyState("XButton2", "P") ) {
            SetTimer, FireVolumeUp, Off
            Send, {Volume_Mute}
        } else {
            SetTimer, FireVolumeDown, 100
        }
    return
    
    XButton1 Up::
         SetTimer, FireVolumeDown, Off
    return
    
    XButton2::
        if( GetKeyState("XButton1", "P") ) {
            SetTimer, FireVolumeDown, Off
            Send, {Volume_Mute}
        } else {
           SetTimer, FireVolumeUp, 100
        }
    return
    
    XButton2 Up::
         SetTimer, FireVolumeUp, Off
    return
    
    
    FireVolumeUp:
        Send, {Volume_Up}
    return
    
    FireVolumeDown:
        Send, {Volume_Down}
    return
    

    这变得更类似于您的代码,但它使用timers 而不是循环,使脚本能够在计时器运行之间执行其他代码。此外,我正在使用XButtonN Up:: 热键,从而在检测密钥释放方面更加精确。其余的应该是不言自明的。如果您不希望计时器在首次运行前等待 100 毫秒,请在每个 SetTimer 之前添加一个 GoSub, FireVolume...

    【讨论】:

    • 非常感谢您的解释。它帮助我了解 AutoHotkey 在后台做了什么。但是,当我运行你的脚本时,音量不会像你说的那样多次触发。可能是因为它们不是“普通键”?
    • @Tareck117 你说得对。回到我写代码的时候,我无法测试它。看看更新。希望它现在有效。
    • 感谢更新,现在可以正常使用了。另外,感谢您的解释。你知道 Autohotkey 中是否有办法在参数中传递热键,然后根据热键创建泛型方法?我想用你的方法来创建一个通用插件。
    • @Tareck117 为此使用Hotkey 命令(呃)!另外,如果解决方案适合您,请接受。
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    相关资源
    最近更新 更多