[英]Change the key being pressed with 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会有什么行为,也许他们已经封锁了以防止某种机器人或什么......
当你看看你的钩子类时,问题的根源是什么? 这听起来像是一个没有正确管理的资源。
要意识到如果你打算把它当成某种恶作剧,那么这些笑话永远不会好转,因为通常无法解决这些问题。 同时也认识到这种看似不道德的话题不太可能得到很多支持。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.