用C#更改按下的键

嘿,我正在尝试用C#编写一个程序来跟踪某些键的按下(使用键盘钩子),然后发送不同的键。

例如,当我按下A键时,它将发送Q键。

我使用http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx这个用于我的钩子并尝试使用SendKeys函数,但是我得到一个关于垃圾收集器的例外,它破坏了钩子类中的一些对象。

首先,您需要连接键。

使用此类,您可以注册一个全局快捷方式,我正在跳过解释,但您可以在此处阅读 。

public class KeyboardHook { [DllImport("user32.dll")] private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk); [DllImport("user32.dll")] private static extern bool UnregisterHotKey(IntPtr hWnd, int id); public enum Modifiers { None = 0x0000, Alt = 0x0001, Control = 0x0002, Shift = 0x0004, Win = 0x0008 } int modifier; int key; IntPtr hWnd; int id; public KeyboardHook(int modifiers, Keys key, Form f) { this.modifier = modifiers; this.key = (int)key; this.hWnd = f.Handle; id = this.GetHashCode(); } public override int GetHashCode() { return modifier ^ key ^ hWnd.ToInt32(); } public bool Register() { return RegisterHotKey(hWnd, id, modifier, key); } public bool Unregister() { return UnregisterHotKey(hWnd, id); } } 

然后在您的表单上,您必须注册快捷方式

 public partial class Form1 : Form { public Form1() { InitializeComponent(); KeyboardHook hook = new KeyboardHook((int)KeyboardHook.Modifiers.None, Keys.A, this); hook.Register(); // registering globally that A will call a method } protected override void WndProc(ref Message m) { if (m.Msg == 0x0312) HandleHotkey(); // A, which was registered before, was pressed base.WndProc(ref m); } private void HandleHotkey() { // instead of A send Q KeyboardManager.PressKey(Keys.Q); } } 

这里是管理Keyboard按下和释放事件的类。

 public class KeyboardManager { public const int INPUT_KEYBOARD = 1; public const int KEYEVENTF_KEYUP = 0x0002; public struct KEYDBINPUT { public Int16 wVk; public Int16 wScan; public Int32 dwFlags; public Int32 time; public Int32 dwExtraInfo; public Int32 __filler1; public Int32 __filler2; } public struct INPUT { public Int32 type; public KEYDBINPUT ki; } [DllImport("user32")] public static extern int SendInput(int cInputs, ref INPUT pInputs, int cbSize); public static void HoldKey(Keys vk) { INPUT input = new INPUT(); input.type = INPUT_KEYBOARD; input.ki.dwFlags = 0; input.ki.wVk = (Int16)vk; SendInput(1, ref input, Marshal.SizeOf(input)); } public static void ReleaseKey(Keys vk) { INPUT input = new INPUT(); input.type = INPUT_KEYBOARD; input.ki.dwFlags = KEYEVENTF_KEYUP; input.ki.wVk = (Int16)vk; SendInput(1, ref input, Marshal.SizeOf(input)); } public static void PressKey(Keys vk) { HoldKey(vk); ReleaseKey(vk); } } 

我已经在我正在写的这个textarea上测试了它,当我按下A它发送Q

我不确定魔兽争霸III会有什么行为,也许他们已经阻止了某些机器人或其他东西……

当你看看你的钩子类时,问题的根源是什么? 这听起来像是没有正确管理的资源。

要意识到如果你打算把它当成某种恶作剧,那么这些笑话永远不会好转,因为通常都无法解决这些问题。 同时也认识到这种看似不道德的话题不太可能得到很多支持。