为什么快捷方式在应用于多个键时不具有相同的行为

时间:2013-08-29 16:03:27

标签: autohotkey

这是我的问题。

我写了一个小小的音量控制脚本来控制我的音量,就像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来调用保持行为。为什么?

感谢您的帮助

1 个答案:

答案 0 :(得分:2)

组合

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}
  3. 不幸的是,这在静音时有两个缺点:a)在发送之前总是会有至少一个Volume_UpVolume_Down(甚至更长时间按下第二个按钮) {Volume_Mute}已发送。 b)如果您长按两个键,{Volume_Mute}将一遍又一遍地发送;但这至少不会改变结果。

    <强>更新

    XButton确实表现出一种奇怪的行为,即当他们被压下时他们不会继续射击。看看这段代码:

    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毫秒,请在每个GoSub, FireVolume...之前添加SetTimer