VBA PowerPoint 中的 GetAsyncKeyState 多次捕获相同的键

VBA GetAsyncKeyState in PowerPoint captures same key multiple times

我正在尝试使用 GetAsyncKeyState 在 PowerPoint 中捕获任意两个笔画键 alpha 序列,例如 "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 之后放弃按键,但我不确定这是否正确或如何去做。

您在测试时将 return 值转换为 Boolean,因此除了键状态之外,您还将选择 "recently pressed" 位。从 the documentation 到 API:

Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.

也就是说,这可能永远无法可靠地工作。如果你想可靠地做到这一点,你可能需要子类化主机 window。每次您在循环中调用 DoEvents 时,您都有可能丢失击键。

您还需要考虑用户键入 A {Any}A[=24= 的情况].使用尝试监视 "real" 消息泵的外部循环,您真正可以做的唯一一件事就是确定它们是否连续两次关闭。为了排除在此期间按下任何其他键,您需要监视所有键盘事件。