Изменить нажатую клавишу с помощью С#

Эй, я пытаюсь написать программу на C#, которая будет отслеживать нажатие определенных клавиш (используя клавиатурный хук) и вместо этого отправлять разные.

Например, когда я нажимаю клавишу A, вместо этого будет отправлена ​​клавиша Q.

Я использовал http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx это для моих хуков и пытался использовать функцию SendKeys, но я получаю исключение о том, что сборщик мусора уничтожает какой-то объект внутри класса хука.


person Benny    schedule 15.03.2010    source источник
comment
Интересно, что он будет посылать для нажатия клавиш V I R U и S? или я очень циничен?   -  person Pharabus    schedule 15.03.2010
comment
на самом деле это просто принудительное размещение горячих клавиш для WC3 (потому что вы не можете их изменить). Но да, я понимаю, что это звучит плохо.   -  person Benny    schedule 15.03.2010
comment
так это для веб-приложения? (W3C)?   -  person Pharabus    schedule 15.03.2010
comment
Нет, не W3C, WC3 warcraft3 это старая компьютерная игра =]   -  person Benny    schedule 15.03.2010


Ответы (2)


Сначала нужно подключить ключи.

С помощью этого класса вы можете зарегистрировать глобальный ярлык, я опускаю объяснение, но вы можете читать здесь.

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

Я проверил это на текстовой области, в которую я пишу, когда я нажимал A, он отправлял Q.

Я не уверен, как будет вести себя Warcraft III, может быть, они заблокировали, чтобы предотвратить появление какого-то бота или что-то в этом роде...

person BrunoLM    schedule 30.09.2010
comment
Связанный brunolm.wordpress. com/2015/03/09/ - person BrunoLM; 30.06.2015

И когда вы посмотрите на свой класс ловушек, в чем источник проблемы? Похоже, ресурс не управляется должным образом.

Поймите, что если вы планируете сделать это как своего рода розыгрыш, это никогда не пройдет хорошо из-за невозможности их отключить. Также признайте, что этот тип, казалось бы, неэтичной темы вряд ли получит большую поддержку.

person Driss Zouak    schedule 15.03.2010
comment
Также я подумал, что могу добавить, что такие вещи имеют законное применение, например, переключение раскладок клавиатуры. Например: QWERTY в ДВОРАК - person Val; 30.09.2010
comment
Определенно имеет законное использование ... Я также могу переопределить дурацкие клавиши на клавиатуре. - person Ali; 13.07.2012
comment
Любой, кто говорит более чем на одном языке (то есть на человеческом языке), должен увидеть очень полезное применение для такого рода кода. Быстрое двойное нажатие e может ввести è, три раза — é и т. д. - person Robert Kaucher; 23.10.2015