简体   繁体   English

用C#更改按下的键

[英]Change the key being pressed with C#

Hey, I'm trying to write a program in C# that will track the pressing of certain keys (using a keyboard hook), and send different ones instead. 嘿,我正在尝试用C#编写一个程序来跟踪某些键的按下(使用键盘钩子),然后发送不同的键。

For instance, when I press the A key it will instead send the Q key. 例如,当我按下A键时,它将发送Q键。

I used http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx this for my hooks and tried to use the SendKeys function, but I get an exception about the garbage collector destroying some object inside the hook class. 我使用http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx这个用于我的钩子并试图使用SendKeys函数,但是我得到一个关于垃圾收集器的例外,它破坏了钩子类中的一些对象。

First you need to hook up the keys. 首先,您需要连接键。

With this class you can register a global shortcut, I'm skipping the explanation, but you can read it here . 使用此类,您可以注册一个全局快捷方式,我正在跳过解释,但您可以在此处阅读

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);
    }
}

Then on your form you have to register the shortcut 然后在您的表单上,您必须注册快捷方式

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);
    }
}

And here the class to manage Keyboard press and release events. 这里是管理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);
    }
}

I've tested it on this textarea which I'm writing to, when I pressed A it was sending Q . 我已经在我正在写的这个textarea上测试了它,当我按下A它正在发送Q

I'm not sure what will be the behavior on Warcraft III, maybe they have blocked to prevent some kind of bot or something... 我不确定魔兽争霸III会有什么行为,也许他们已经封锁了以防止某种机器人或什么......

And when you look at your hook class what is the source of the problem? 当你看看你的钩子类时,问题的根源是什么? It sounds like a resource not being managed properly. 这听起来像是一个没有正确管理的资源。

Realize that if you are planning on doing this as some sort of practical joke these never go over well because generally of the inability to turn these off. 要意识到如果你打算把它当成某种恶作剧,那么这些笑话永远不会好转,因为通常无法解决这些问题。 Also recognize that this type of seemingly unethical topic will not likely get much support. 同时也认识到这种看似不道德的话题不太可能得到很多支持。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM