2010-03-15 3 views
7

안녕하세요, 키보드 훅을 사용하여 특정 키를 누르는 대신 C#으로 프로그램을 작성하고 대신 다른 프로그램을 보내려고합니다.C#으로 누른 키 바꾸기

예를 들어 내가 A 키를 누르면 대신 Q 키가 전송됩니다.

내 후크에 대해 http://www.codeproject.com/KB/cs/CSLLKeyboardHook.aspx을 사용하고 SendKeys 함수를 사용하려고했지만 후크 클래스 내부의 일부 개체를 파괴하는 가비지 수집기에 대한 예외가 발생합니다.

+3

가 키 입력 내가 U와 S를 R V 형을 위해 전송 될지 궁금 봇이나 뭐 ... 일종의을 방지하기 위해 차단 한? 아니면 내가 매우 냉소적입니까? – Pharabus

+0

실제로 WC3에 대한 단축키 배치를 강제하기 만하면됩니다 (변경할 수 없기 때문에). 그러나 참으로, 나는 이것이 나쁘게 들리는 것을 이해합니다. – Benny

+0

이것은 웹 앱을위한 것입니까? (W3C)? – Pharabus

답변

0

그리고 훅 클래스를 보면 문제의 원인은 무엇입니까? 리소스가 제대로 관리되지 않는 것 같습니다.

실용적인 농담으로 이런 일을 할 계획이라면, 이것들을 작동시키지 못하는 것이 일반적이기 때문에 절대로 넘어 가지 않을 것임을 깨달으십시오. 또한이 유형의 겉으로는 비 윤리적 인 주제가 많은 지원을 얻지 못할 것이라는 점을 인식하십시오.

+0

+1은 비활성화 문제에 대한 경고입니다. – Val

+1

또한 이런 종류의 키보드 레이아웃을 바꾸는 것과 같은 합법적 인 용도가 있다는 점을 지적했습니다. 예 : QWERTY to DVORAK – Val

+0

확실히 합법적 인 용도가 있습니다 ... 키보드의 바보 같은 키를 무시하고 싶을 수도 있습니다 – pug

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

그런 다음 양식에 당신은 Keyboard 눌러을 관리하고 이벤트를 해제 여기에 바로 가기

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

그리고에게 클래스를 등록해야합니다.

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

나는 그것이 Q를 전송했다 A을 누르면 I가 쓰고 있어요이 텍스트 영역에 그것을 테스트했습니다. 내가 뭘 워크래프트 III에서 동작 될 것입니다 확실하지 않다

는, 어쩌면 그들은

+0

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

관련 문제