2016-01-21 82 views
1

我正在製作一個C#表單應用程序在後臺運行,並檢查您是否按下CTRL + A + S.所以我正在檢查互聯網上的論壇和我已經設置該應用程序在後臺運行,現在我試圖設置鍵盤鉤子。我在互聯網上找到了一個全局鍵盤鉤子代碼。C#檢查是否有多個鍵被按下(全局鍵盤掛鉤)

下面是該代碼:

// GLOBAL HOOK 
    [DllImport("user32.dll")] 
    static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId); 

    [DllImport("user32.dll")] 
    static extern bool UnhookWindowsHookEx(IntPtr hInstance); 

    [DllImport("user32.dll")] 
    static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam); 

    [DllImport("kernel32.dll")] 
    static extern IntPtr LoadLibrary(string lpFileName); 

    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); 

    const int WH_KEYBOARD_LL = 13; // Number of global LowLevel- hook on the keyboard 
    const int WM_KEYDOWN = 0x100; // Messages pressing 

    private LowLevelKeyboardProc _proc = hookProc; 

    private static IntPtr hhook = IntPtr.Zero; 

    public void SetHook() 
    { 
     IntPtr hInstance = LoadLibrary("User32"); 
     hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0); 
    } 

    public static void UnHook() 
    { 
     UnhookWindowsHookEx(hhook); 
    } 

    public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam) 
    { 
     if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
     { 
      int vkCode = Marshal.ReadInt32(lParam); 

      if (vkCode.ToString() == "162") //162 is ASCI CTRL 
      { 
       MessageBox.Show("You pressed a CTRL");      
      } 
      return (IntPtr)1; 
     } 
     else 
      return CallNextHookEx(hhook, code, (int)wParam, lParam); 
    } 

    private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
    { 
     // Remove the hook 
     UnHook(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     // Set the hook 
     SetHook(); 
    } 

} 

我的問題是,這個鉤子是設置爲1個鍵,我無法弄清楚如何檢查是否被按下3個鍵(Ctrl + A + S) 。

我已經試過這個,但沒有工作。

if (vkCode.ToString() == "162" && vkCode.ToString() == "65" && vkCode.ToString() == "83") //162 is CTRL, 65 is A, 83 is S, ASCII CODE 
      { 
       MessageBox.Show("You pressed a CTRL + A + S");      
      } 

所以我的問題是什麼,我需要做的是,程序或該鉤子將讓我檢查3個按鍵(CTRL + A + S)。

+0

爲什麼你會認爲像'x == 1 && x == 2'這樣的表達式會評估爲真? – IInspectable

+0

我不知道。我剛開始學習C#,我想製作應用程序,我的意思是非常有用,但我的編程技巧不明,所以我非常感謝您的答案和幫助。 –

回答

2

我相信你不得不分別檢測CTRL,A和S,使用標誌來保持CTRL和A是否是最後的按鍵,像這樣的軌道:

static bool ctrlPressed = false; 
static bool ctrlAPressed = false; 

public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam) 
{ 
    if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
    { 
     int vkCode = Marshal.ReadInt32(lParam); 

     if (vkCode == 162 || vkCode == 163) //162 is Left Ctrl, 163 is Right Ctrl 
     { 
      ctrlPressed = true; 
     } 
     else if (vkCode == 65 && ctrlPressed == true) // "A" 
     { 
      ctrlPressed = false; 
      ctrlAPressed = true; 
     } 
     else if (vkCode == 83 && ctrlAPressed == true) // "S" 
     { 
      ctrlPressed = false; 
      ctrlAPressed = false; 
      MessageBox.Show("Bingo!"); 
     } 
     else 
     { 
      ctrlPressed = false; 
      ctrlAPressed = false; 
     } 

     // return (IntPtr)1; // note: this will interfere with keyboard processing for other apps 
    } 
// else // don't interfere , always return callnexthookex 
     return CallNextHookEx(hhook, code, (int)wParam, lParam); 
} 

如果你想牛逼omake確保所有按下的邏輯是相似的,你只需要添加檢查按鍵是否按下或向上。你也可以想出一個更聰明的方法來做到這一點,這使用某種列表或隊列或按鍵的東西。

+0

非常感謝...只是多一個問題 –

+0

它的工作(鉤),但我的問題是,當程序運行鍵盤佈局不工作,我無法輸入文本,所以問題在哪裏。 –

+0

取出'返回(IntPtr)1'部分和最後一個'else'條件,以便始終返回'CallNextHookEx'的結果。否則,你的程序會說它完全處理了該事件。 –