在C#事件发生后,我怎么能做某事〜

时间:2010-05-03 00:15:28

标签: c# keyboard-hook

我正在使用以下project来处理我的C#应用​​程序中的全局键盘和鼠标挂钩。

这个项目基本上是使用WH_MOUSE_LL或WH_KEYBOARD_LL常量调用Win API调用SetWindowsHookEx的包装器。它还管理某些状态,并且通常使这种挂钩非常无痛。

我正在使用它来制作我正在研究的鼠标手势识别软件。基本上,我设置它以便检测何时按下全局热键(比如CTRL),然后用户以预定义手势的形状移动鼠标,然后释放全局热键。

处理KeyDown的事件并告诉我的程序开始记录鼠标位置,直到它收到KeyUp事件。这工作正常,它允许用户轻松进入鼠标手势模式。一旦KeyUp事件触发并且它检测到适当的手势,则假设将某些击键发送到用户为他们刚绘制的特定手势定义的活动窗口。

我正在使用SendKeys.Send / SendWait方法将输出发送到当前窗口。

我的问题是:当用户释放他们的全局热键(比如CTRL)时,它会触发KeyUp事件。我的程序获取其记录的鼠标点并检测相关手势并尝试通过SendKeys发送正确的输入。

但是,由于所有这些都在KeyUp事件中,因此该全局热键尚未完成处理。因此,例如,如果我定义了一个手势,以便在检测到时发送密钥“A”,并且我的全局热键是CTRL,当检测到它时,SendKeys将发送“A”,但CTRL仍然是“向下”。所以,我没有发送A,而是获得了CTRL-A。因此,在此示例中,不是物理地发送单个字符“A”,而是通过CTRL-A快捷方式选择全部。即使用户已经发布了CTRL(全局热键),系统仍然会将其视为已关闭。

一旦我的KeyUp事件触发,如何让我的程序等待一段时间或某些事件,这样我就可以确定全局热键真的不再被系统注册,只有发送正确的输入通过SendKeys?

1 个答案:

答案 0 :(得分:3)

你可以简单地设置一个计时器并在稍后(例如,100ms)触发SendKeys,用户不会注意到轻微的延迟,但它足以在事件处理程序之外发生KeyUp。

另一个替代方法是发布您自己的窗口(使用PostMessage)自定义消息,以指示何时应该“触发”效果并实际执行该自定义消息处理程序中的SendKeys内容。这具有不使用一些任意“延迟”的优点。虽然设置稍微复杂一些(特别是在.NET中你需要P / Invoke更多的API调用才能使它工作,覆盖WndProc函数等等......