目前,我正在编写一个程序来拦截来自特定键盘的击键(使用其 HID 进行过滤)。因此,为了了解特定设备发送了哪些击键,我使用了 RawInput 技术,灵感来自于这个很棒的教程:
http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
现在,它工作得很好:我可以得到一个击键并知道哪个键盘生成了它。
我的项目的困难部分是拦截和阻止来自该特定键盘的击键,以避免这些击键到达焦点应用程序(焦点是指操作系统带来的前台窗口)。
因此,自然的解决方案是在所有具有窗口句柄的当前线程上使用低级全局钩子。
我使用并调整了此页面中的代码来执行此操作:
http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
我在视觉工作室中创建了一个新项目,以避免给我的工作带来混乱。经过一些研究,我能够通过在回调函数中返回值(-1)来阻止所有应用程序上的击键:
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
//Check if we have a key to pass
if (
nCode >= 0 && (
(wParam == (IntPtr)WM_KEYDOWN) || (wParam == (IntPtr)WM_KEYUP) )
)
{
int vkCode = Marshal.ReadInt32(lParam);
if ((Keys)vkCode == Form1.KeysToIgnore)
{
return (IntPtr)(-1);
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
为了将所有内容放在一起(挂钩过程和击键检测),我在最终项目中创建了两个线程:
1st:使用 RawInput 识别每个击键并将其附加到设备
2nd:用于挂接所有窗口并阻止某些击键
线程 1 旨在将击键发送到线程 2,以阻止线程 2,线程 2 读取发送到所有窗口应用程序的所有消息,并从特定键盘中删除击键。我确切地说这两个线程是同步的。
问题是钩子似乎在执行Rawinput之前执行,所以我无法识别发送击键的键盘。我不知道该怎么做,也许改变钩子的类型(避免使用低级键盘钩子,但使用用户空间级键盘钩子)。
或者也许有人知道一种聪明的方法来做我想做的事?
我知道这个请求确实很复杂,请随时询问更多详细信息。