PowerPoint中的VBA GetAsyncKeyState多次捕获相同的密钥

时间:2018-10-02 15:48:20

标签: vba powerpoint powerpoint-vba

我正在尝试使用GetAsyncKeyState捕获PowerPoint中任意的两次笔触键字母序列,例如“ AA”,“ AB”,“ DZ”。但是,我发现第一个按键同时被捕获为第一个和第二个。

为简单起见,下面的代码尝试仅捕获序列“ AA”。我希望两次按下“ A”后代码才能完成。但是,一旦按下“ A”,它就会完成。

Option Explicit

Private Declare PtrSafe Function GetAsyncKeyState Lib "user32" _
    (ByVal vKey As Long) As Integer

Private Const VK_A = &H41 'A key


Sub CaptureAA()

    ' Capture first 'A' keystroke
    Do While True
        If GetAsyncKeyState(VK_A) Then
            Debug.Print "First A captured"
            Exit Do
        End If
        DoEvents
    Loop

    ' Capture second 'A' keystroke
    Do While True
        If GetAsyncKeyState(VK_A) Then
            Debug.Print "Second A captured"
            Exit Do
        End If
        DoEvents
    Loop

End Sub

我猜我需要在第一个GetAsyncKeyState之后以某种方式放弃按键,但是我不确定这是正确的还是如何做到的。

1 个答案:

答案 0 :(得分:2)

您将在测试返回值时将其转换为Boolean,因此除了键状态外,您还将选择“最近按下”位。从the documentation获得API:

  

尽管返回值的最低有效位指示自上一次查询以来是否已按下键,但是由于Windows的抢先式多任务处理性质,另一个应用程序可以调用GetAsyncKeyState并接收“最近按下”位,而不是你的申请。严格保留返回值的最低有效位的行为是为了与16位Windows应用程序(非抢占式)兼容,因此不应依赖。

也就是说,这可能永远无法可靠地工作。如果要可靠地执行此操作,则可能需要对宿主窗口进行子类化。每次您在循环中调用DoEvents时,都有可能会丢失按键。

您还需要考虑用户键入 A {Any} A 的情况。试图监视“真实”消息泵的外部循环唯一可以做的就是确定它们是否连续快速下降两次。为了排除在过渡期间按下任何其他键,您需要监视所有键盘事件。