2010-03-15 21 views
7

Oye, estoy intentando escribir un programa en C# que rastrea la presión de ciertas teclas (usando un gancho de teclado), y en su lugar envíe otras.Cambie la tecla que se está presionando con C#

Por ejemplo, cuando presiono la tecla A, en su lugar enviaré la tecla Q.

Utilicé http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx esto para mis ganchos y traté de usar la función SendKeys, pero recibo una excepción sobre el recolector de basura que destruye algún objeto dentro de la clase de ganchos.

+3

se preguntan lo que enviaría a las pulsaciones de teclas V I R U y S? o estoy siendo muy cínico? – Pharabus

+0

en realidad es solo para forzar la colocación de teclas rápidas para WC3 (porque no puede cambiarlas). Pero sí, entiendo que esto suena mal. – Benny

+0

así que esto es para una aplicación web? (W3C)? – Pharabus

Respuesta

0

Y cuando observas la clase de gancho, ¿cuál es la fuente del problema? Parece que un recurso no se maneja adecuadamente.

Date cuenta de que si estás planeando hacer esto como una especie de broma práctica, estas nunca van bien porque generalmente no se pueden apagar. También reconozca que este tipo de tema aparentemente no ético probablemente no obtendrá mucho apoyo.

+0

+1 para la advertencia sobre la dificultad de desactivación. – Val

+1

También pensé que podría suponer que este tipo de cosas tiene usos legítimos, como cambiar diseños de teclado. Por ejemplo: QWERTY a DVORAK – Val

+0

Definitivamente tiene usos legítimos ... También es posible que desee sobrescribir claves estúpidas en el teclado – pug

4

Primero debe conectar las llaves.

Con esta clase puede registrar un atajo global, me estoy saltando la explicación, pero puede 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); 
    } 
} 

A continuación, en el formulario hay que registrarse en el acceso directo

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

Y aquí la clase de gestionar Keyboard presionar y soltar eventos.

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

Lo he probado en esta área de texto, que le estoy escribiendo, cuando apreté A que estaba enviando Q.

No estoy seguro de cuál será el comportamiento de Warcraft III, tal vez se han bloqueado para evitar algún tipo de robot o algo ...

+0

https://brunolm.wordpress.com/2015/03/09/automating-keyboard-keypress-and-mouse-clicks-with- autoit3 / – BrunoLM

Cuestiones relacionadas