我正在创建一个程序,安装一个键盘挂钩来捕获所有的键,并显示一些与它们相关的文本。
但是,我遇到了一个问题,那就是在安装钩子时,一些键会改变行为。
我会考虑发布一个小而完整的测试程序,但现在我只描述这个问题。
这个问题出现在Windows764位的.NET 4.0中,这是一个C#程序.我想这一切都不重要。
我的钩子通过SetWindowsHookEx安装自己,然后处理系统中处理的所有密钥。
如果钩子方法简单地返回,或者对键进行最小的处理(我将在一秒钟内发布更改行为的内容),那么键盘功能就像程序中所期望的那样。
但是,如果我从User32.dll调用这个函数ToAscii,找出键盘上的OemTilde或类似的键实际上是哪个键,那么“覆盖下一个键”的任何键都会停止工作。我不知道这类键的正确名称,但是两个撇号-- 和‘, as well as~and´’--停止了功能。
例如,如果我按了~,然后按了N,它就会显示如下:
有人知道为什么会发生这种事吗?我怎样才能解决这个问题?
现在,我将满足于在其他程序中正确地处理密钥,即使这意味着我将无法正确地检测到我自己的程序中正确的密钥序列。
更多信息:
如果我调用ToAscii函数作为钩子方法的一部分,那么就会出现一个不同的问题。像¨这样的密钥被处理了两次。如果我点击¨一次,记事本就会收到两个¨¨字符,而点击N现在只会添加N。
但是,如果我使用BeginInvoke处理单独线程上的键,则在从键盘钩子方法返回后,会出现第一个问题。
我的节目可能有点特别,因为:
因此,我的代码最终看起来如下:
private bool IsDeadKey(uint key)
{
return ((Hook.Interop.MapVirtualKey(key, 2) & 2147483648) == 2147483648);
}
void _Hook_KeyDown_Async(KeyDownEventArgs e)
{
var inBuffer = new byte[2];
char key = '\0';
if (!IsDeadKey((uint)e.KeyCode))
{
int ascii = Hook.Interop.ToAscii((int) e.KeyCode,
e.ScanCode,
_KeyState,
inBuffer,
e.Flags);
if (ascii == 1)
{
key = Char.ToUpper((char) inBuffer[0]);
}
}
BeginInvoke(
new Action<Keys, Boolean, Boolean, Boolean, Char>(ProcessKeyboardEvent),
e.KeyCode, e.Control, e.Shift, e.Alt, key);
}发布于 2010-08-23 18:22:31
您的问题中缺少了一些关键信息,您使用的两个键盘挂钩中的哪一个?简单的是,WH_KEYBOARD_LL不能工作。最后,您将使用程序的键盘状态,而不是实际获得击键的程序。死钥匙确实起作用了。
困难的是,WH_KEYBOARD需要一个无法用托管代码编写的钩子。您将需要一个可以在每个进程中注入的非托管DLL。一旦你知道了,我就不用管键盘钩子了,不如用WH_CALLWNDPROC来记录WH_CALLWNDPROC消息。
示例DLL是可用的这里。
https://stackoverflow.com/questions/3548932
复制相似问题