目前,我正在制作一个程序来拦截来自特定键盘的击键(使用其 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
我在 Visual Studio 中创建了一个新项目,以避免把我的工作弄得一团糟。经过一番研究,我能够通过在回调函数中返回值 (-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);
}
为了将所有内容放在一起(挂钩过程和击键检测),我在最终项目中创建了两个线程:
第一种:使用 RawInput 识别每次击键并将其附加到设备
2nd : 用于钩住所有窗口并阻止某些击键
线程 1 旨在将击键发送到线程 2,线程 2 读取发送到所有窗口应用程序的所有消息,并从特定键盘删除击键。我确切地说这两个线程是同步的。
问题是钩子似乎是在执行 Rawinput 之前执行的,所以我无法识别发送击键的键盘。我不知道该怎么做,也许要改变钩子的类型(避免使用低级键盘钩子,但使用用户空间级键盘钩子)。
或者也许有人知道一个聪明的方法来做我想做的事?
我知道这个请求真的很复杂,不要犹豫,询问更多细节。