【问题标题】:Using GetKeyState to create 3 key hotkey without triggering another similar 2 key hotkey使用 GetKeyState 创建 3 键热键而不触发另一个类似的 2 键热键
【发布时间】:2018-04-01 04:11:52
【问题描述】:

问题

当按下 3 键热键 (LShift+CapsLock+LButton) 时,会触发类似的 2 键热键 (CapsLock+LButton)。

问题

  1. 为什么会这样?

  2. 如何为LShift+CapsLock+LButton 热键触发正确的消息框 (shift left click)?

代码

SetCapsLockState, AlwaysOff
CapsLock::
    MsgBox, "capslock"
return
CapsLock & LButton::
    MsgBox, "left click"
return

; 3 key hotkey
; problem here is when LShift+CapsLock+LButton are pressed, the CapsLock+LButton is 
; triggered instead
#If GetKeyState("LShift", "P") && GetKeyState("CapsLock", "P")
    LButton::
        MsgBox, "shift left click"
    return
#If

示例场景

  • CapsLock,出现正确消息框(capslock
  • CapsLock+LButton,出现正确的消息框(left click
  • LShift+CapsLock+LButton,出现错误消息框(left click)(应该出现消息框(shift left click))
  • CapsLock+LShift+LButton,出现错误消息框(left click)(应该出现消息框(shift left click))

我的尝试

  • 查看#If 指令文档,它提到了可能影响按钮组合的超时,但是,以不同的速度按下按钮仍然会导致CapsLock+LButton 热键触发
  • 使用嵌套的常规 ifelse ifelse 语句 而不是 #If 指令来改变 3 键的顺序 热键
  • 使用$修饰符防止三键热键触发CapsLock+LButton热键
  • 将 3 键热键分解为多个部分,例如,将 2 键热键放在 #If GetKeyState 中,即:

    #If GetKeyState("LShift", "P")
        CapsLock & LButton::
            MsgBox, "shift left click"
        return
    #If
    

    这通常会给出正确的消息 (shift left click) 框,但有时会触发 CapsLock 热键给出不正确的消息框 (capslock)

【问题讨论】:

  • if (GetKeyState("LShift", "P"))CapsLock & LButton 热键中怎么样?
  • @JoshBrobst 我试过 (pastebin) if (GetKeyState("LShift", "P"))CapsLock & LButton#If 和常规 if/else 都停止 CapsLock & LButton 和 3 键热键触发他们的 @ 987654372@
  • 哦,我的意思是使用 if 语句的真正部分来实现 3 键热键,like this
  • @JoshBrobst 好主意,比我以前的解决方案更有效且更稳定(当LShift 是触发热键后释放的最后一个键时,例如LShift down+CapsLock down then CapsLock up+LShift up 正确不会触发 CapsLock 热键,但如果 CapsLock 是触发热键后释放的最后一个键,则会触发 CapsLock 热键)
  • @JoshBrobst 你能把你的解决方案作为这个问题的答案,这样它就可以被接受,以便其他有类似问题的人可以更快地找到它?

标签: autohotkey


【解决方案1】:

您可以测试 2 键热键内的 shift 来实现 CapsLock + LButtonCapsLock + Shift + LButton,而不是单独的 3 键热键:

SetCapsLockState, AlwaysOff

CapsLock::
    MsgBox, "capslock"
return

CapsLock & LButton::
    if (GetKeyState("LShift", "P")) {
        MsgBox, "shift left click"
    }
    else {
        MsgBox, "left click"
    }
return

避免类似热键的代码重复:

  • 使用function

    CapsLock & RButton::CapsMouseHandler("right")
    CapsLock & LButton::CapsMouseHandler("left")
    
    CapsMouseHandler(btnString) {
        if (GetKeyState("LShift", "P")) {
            MsgBox % "shift " btnString " click"
        }
        else {
            MsgBox % btnString " click"
        }
    }
    
  • 使用A_ThisHotkey

    CapsLock & RButton::
    CapsLock & LButton::
        btnString := InStr(A_ThisHotkey, "LButton") ? "left" : "right"
        if (GetKeyState("LShift", "P")) {
            MsgBox % "shift " btnString " click"
        }
        else {
            MsgBox % btnString " click"
        }
    return
    

【讨论】:

  • 谢谢,这行得通。如果我有很多 2 键热键(例如,CapsLock+LButtonCapsLock+RButton 等),这会导致代码重复(pastebin)。有没有办法重构您的解决方案以避免代码重复?
  • 是的,因为热键实际上是labels,您只需将CapsLock & RButton:: 放在CapsLock & LButton:: 正上方的那一行,它们都会运行相同的代码。
  • 然后您可以针对A_ThisHotkey 进行测试以根据左键或右键进行分支以更改消息。或者,您可以将热键分开并将其移动到一个函数中。我将在答案中添加一个示例。
  • 好主意,function 和 A_ThisHotkey 方法都可以工作(function 方法看起来更简洁易读),+1 用于减少代码重复,非常感谢帮助:)
  • 乐于助人!我绝对同意使用函数更清晰。我尽量使用函数而不是子程序/命令。
猜你喜欢
  • 2013-10-21
  • 2016-02-28
  • 2017-06-18
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 2017-08-27
相关资源
最近更新 更多