我可以更改用户的键盘输入吗?
我发现这个键盘钩子代码,我想稍微修改一下我的目的:http://blogs.msdn.com/toub/archive/2006/05/03/589423.aspx我可以更改用户的键盘输入吗?
作为一个概述,我想有用户按一个键,说“E”,并有键盘回报一个不同的角色,'Z',任何应用程序的焦点。
我改变了相关的方法现在看起来像:
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
//The truely typed character:
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
KBDLLHOOKSTRUCT replacementKey = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
replacementKey.vkCode = 90; // char 'Z'
Marshal.StructureToPtr(replacementKey, lParam, false);
//Now changed to my set character
vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
控制台正确输出该为:
E
Z
T
Z
G
Z
etc.
然而,在重点应用仍然类型“E”而不是“Z” 。为什么?我改变了钩住的键盘输入以包含'Z'而不是'E',并且控制台线显示它被正确地改变了!
据我所知,调用return CallNextHookEx(_hookID, nCode, wParam, lParam);
是将“print this now”命令发送到打开的应用程序。这不是它的工作原理吗?有什么能够阻止我输入我想要的字符吗?我知道像AutoHotkey这样的应用程序需要输入密钥,检查它并返回一个不同的字符。我如何在这里做同样的事情?
谢谢!
我已经完成了这之前,但有点不同。
而不是尝试更改发送到CallNextHookEx
的参数,我'吞咽'按键(您可以通过从挂钩过程中返回一个非零值来阻止后续过程被调用)。
然后我用SendInput发送我想'注入'的新密钥。
所以基本上它的工作原理是这样的:
- 钩子程序标识目标键被按下
- 电话SendInput,用新密钥
- 返回1从钩子程序忽略原始密钥
小心环状重定向,即“一个”重定向到重定向到“A”,它可以很容易炸毁“b”)
很酷,我已经成功地用return((IntPtr)1)忽略了原始键;'现在,我该如何'SendInput'?是否需要在标题中包含特定的“使用XXX”,或者需要添加其他代码才能使用该命令? – cksubs 2010-01-14 23:02:56
pinvoke.net拥有调用'SendInput'所需的所有代码 - http://www.pinvoke.net/default.aspx/user32/SendInput.html – 2010-01-14 23:20:42
好吧,使用'[DllImport(“coredll.dll”, SetLastError = true)] static extern uint SendInput(uint cInputs,/ * [MarshalAs(UnmanagedType.LPArray)] */KEYBOARDINPUT [] inputs,int cbSize);'和一个KEYBOARDINPUT结构。现在我正在努力传递SendInput()正确的参数。 – cksubs 2010-01-14 23:20:43
您很有可能已经安装了“线程宽度”而非“系统宽度”的挂钩,这意味着密钥转换只会发生在安装挂钩的线程中。
为了安装它“系统范围”,你将需要两件:一个DLL具有“钩子提供者”和一个EXE管理它。 这里是一个很好的教程 http://www.codeproject.com/KB/system/hooksys.aspx 这里一个例子: http://www.codeguru.com/cpp/com-tech/shell/article.php/c4509/
但是: 1.安装系统范围内挂钩可能会严重搞砸了你的系统(请确保您转发的钥匙,你不翻译) 。 2.请...不要创建另一个键盘记录器
他使用低级别的键盘钩子,而不是普通的键盘钩子。低级别的钩子不需要一个单独的dll被加载到每个进程中。从http://msdn.microsoft.com/en-us/library/ms644985.aspx - 但是,WH_KEYBOARD_LL挂钩不被注入到另一个进程中。相反,上下文切换回安装钩子的进程,并在其原始上下文中调用它。然后上下文切换回生成事件的应用程序。 – 2010-01-14 21:43:34
所以......这是否意味着我正确地使用它? :) – cksubs 2010-01-14 22:47:54
关于实现/使用WH_KEYBOARD_LL的许多信息(以及关于检测控制修饰符,将关键信息传递给下一个应用程序或阻塞等问题的大量讨论)。 codeproject.com/KB/system/CSLLKeyboard.aspx“C#中的低级别Windows API挂钩可阻止不必要的击键”作者:Emma Burrows。 2007文章。 – BillW 2010-01-15 06:08:09
出于好奇,这有什么用? – 2010-01-14 20:59:39
这不是一个键盘记录! :)应用程序是辅助技术。想想iPhone键盘;在幕后,它修改了关键区域,纠正了明显的错误,并运行了其他智能代码,以帮助您更快,更准确地打字。这是一个类似的应用程序,但对于全键盘。 – cksubs 2010-01-14 22:46:37