按下GetAsyncKeyState时如何检查VBA应用程序是否处于焦点

时间:2019-07-05 22:50:46

标签: vba

我有一个用VBA编写的长期运行的应用程序。因为它运行了很长时间,所以我每次迭代都会从主循环中调用一个子程序,以检查用户是否按下了转义键。子列表如下。该代码非常有用,除了它始终在监听之外,即使VBA应用程序没有重点。解决此问题的最佳方法是什么?是否有GetAsyncKeyState的替代方法,它仅在正确的应用程序处于焦点状态时进行侦听,或者是否可以使用系统调用来检查正确的窗口是否处于焦点状态。

Private Sub checkForUserEscKeyAbort()
    'Listen for escape key and exit gracefully if user aborts.
    Dim abortResult As VbMsgBoxResult
    If GetAsyncKeyState(vbKeyEscape) Then
        abortResult = MsgBox("Escape key pressed, do you want to abort?", vbYesNo)
        If abortResult = vbYes Then Call teardownSLICER
    End If
End Sub

1 个答案:

答案 0 :(得分:0)

问题是GetAsyncKeyState的操作方式。它所做的不只是检查当前是否已按下键,它还检查自上次调用GetAsyncKeyState以来是否按下了该键。因此,您的“总是收听”问题。

您可以使用GetKeyState,但是坦率地说,我也不喜欢该选项。您的代码必须经过精心设计,以免轮询窗口太小,以至于您实际上必须按下键以确保不会丢失它。

一种可行的替代方法是按键遮罩,其中您可以使用组合键,例如Shift-Escape。 Chip Pearson's网站上对此(以及许多其他主题)进行了不错的介绍。但是,这仍然不是我的首选方法。

我的偏好已在评论中提及。最好使用用户表单来改进您的应用程序。它还使您能够在用户面前获取信息。如果用户表单上的进度条显示95%完成,则他们可能不会尝试退出该应用程序。也许您可以添加一个暂停按钮,以释放预先需要的一些资源,然后在用户准备就绪时恢复。仅仅靠一点额外的功能就足以吸引我,但是使用用户表单还有一个更好的理由-它完全符合您的要求!

用户窗体以及许多用户窗体控件具有Keydown,Keyup和Keypress事件,这些事件仅在窗体(或控件)具有焦点时才触发。这正是您想要的。