2010-03-15 20 views
7

Ehi, sto provando a scrivere un programma in C# che seguirà la pressione di determinati tasti (utilizzando un gancio della tastiera) e ne invierà di diversi.Cambiare il tasto premuto con C#

Ad esempio, quando premo il tasto A, verrà invece inviato il tasto Q.

Ho utilizzato http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx per i miei ami e ho provato a utilizzare la funzione SendKeys, ma ottengo un'eccezione sul garbage collector che distrugge alcuni oggetti all'interno della classe hook.

+3

chiedo che cosa avrebbe inviato per le sequenze di tasti V I R U e S? o sono molto cinico? – Pharabus

+0

in realtà è solo per forzare il posizionamento hotkey facile per WC3 (perché non è possibile cambiarli). Ma sì, capisco che questo suona male. – Benny

+0

quindi è per un'applicazione web? (W3C)? – Pharabus

risposta

0

E quando si guarda alla classe del gancio qual è la causa del problema? Sembra che una risorsa non sia gestita correttamente.

Realizza che se hai intenzione di fare questo come una sorta di scherzo pratico, questi non vanno mai troppo bene perché generalmente l'incapacità di disattivarli. Riconosce anche che questo tipo di argomento apparentemente non etico non otterrà probabilmente molto supporto.

+0

+1 per l'avviso relativo alla difficoltà di disattivazione. – Val

+1

Inoltre, ho pensato che avrei potuto sfruttare questo tipo di cose che hanno usi legittimi, come il cambio di layout della tastiera. Ad esempio: QWERTY a DVORAK – Val

+0

Sicuramente ha usi legittimi ... Potrei voler ignorare le chiavi stupide anche sulla tastiera – pug

4

Per prima cosa è necessario collegare le chiavi.

Con questa classe è possibile registrare una scelta rapida globale, sto saltando la spiegazione, ma è possibile 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); 
    } 
} 

Poi sul modulo è necessario registrare la scorciatoia

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

E qui la classe per gestire Keyboard premere e rilasciare gli eventi.

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

ho testato su questo textarea che sto scrivendo a, quando ho premuto A che stava mandando Q.

Non sono sicuro di quale sarà il comportamento in Warcraft III, forse hanno bloccato per evitare che un qualche tipo di bot o qualcosa ...

+0

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

Problemi correlati