2010-03-15 66 views
7

嘿,我想在C#中編寫一個程序來跟蹤按下某些鍵(使用鍵盤鉤子),併發送不同的鍵。更改正在按下C鍵#

例如,當我按A鍵時,它會發送Q鍵。

我用http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx這個爲我的鉤子,並試圖使用SendKeys函數,但我得到了一個關於垃圾收集器銷燬鉤類中的某個對象的異常。

+3

不知道它會發送的擊鍵V I [R U和S'還是我非常憤世嫉俗? – Pharabus 2010-03-15 17:40:11

+0

實際上它只是爲了強制簡化WC3的熱鍵位置(因爲你不能改變它們)。但是,是的,我明白這聽起來很糟糕。 – Benny 2010-03-15 17:47:12

+0

所以這是一個Web應用程序? (W3C)? – Pharabus 2010-03-15 18:00:39

回答

0

而當你看看你的鉤類是什麼問題的根源?這聽起來像一個資源沒有得到妥善管理。

認識到,如果你打算把這當成某種實際的笑話,這些事情永遠都不會結束,因爲通常無法關閉這些笑話。也承認這種看似不道德的話題不可能得到很多支持。

+0

+1用於解除激活困難的警告。 – Val 2010-09-30 02:43:26

+1

另外我想我可能會認爲這種事情有合法用途,比如切換鍵盤佈局。例如:QWERTY到DVORAK – Val 2010-09-30 03:33:03

+0

肯定有合法用途...我可能想要覆蓋鍵盤上的愚蠢鍵鍵盤 – pug 2012-07-13 16:42:19

4

首先你需要掛鉤的鑰匙。

有了這門課,你可以註冊一個全局快捷方式,我可以跳過解釋,但你可以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); 
    } 
} 

那麼你的表格上,你必須註冊快捷

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的行爲,也許他們已經封鎖,以防止某些類型的殭屍或東西...的

+0

相關https://brunolm.wordpress.com/2015/03/09/automating-keyboard-keypress-and-mouse-clicks-with- autoit3 / – BrunoLM 2015-06-30 14:03:41