2016-01-21 2 views
1

Я делаю приложение формы C#, которое работает в фоновом режиме и проверяет, нажали ли вы CTRL + A + S. Поэтому я проверял форумы в Интернете и Я уже установил, что приложение работает в фоновом режиме, и теперь я пытаюсь настроить клавиатурный крючок. Я нашел глобальный код крючка клавиатуры в Интернете.C# Проверка нажатия нескольких клавиш (Global Keyboard Hook)

Вот этот код:

// 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', когда-либо оценивалось бы true? – IInspectable

+0

Не знаю. Я только начал изучать C#, и я хочу сделать приложение, которое я имею в виду, действительно полезно, но мои навыки программирования неясны, поэтому я ценю все ваши ответы и помощь. –

ответ

2

Я считаю, что вы должны были бы обнаружить CTRL, A и S отдельно, используя флаги, чтобы следить за того, были ли последние нажатия клавиш, как CTRL так и А:

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

Если вы хотите т Бонус-байка убедитесь, что все нажаты одновременно с логикой, вам просто нужно добавить проверки на то, нажата ли клавиша нажата или вверх. Вы также можете придумать более умный способ сделать это, используя какой-то список или очередь или что-то для нажатия клавиш.

+0

Большое спасибо ... еще один вопрос –

+0

Это работает (крючок), но моя проблема в том, что когда программа работает, раскладка клавиатуры не работает, и я не могу ввести текст так, где проблема , –

+0

Извлеките часть 'return (IntPtr) 1' и ваше последнее условие' else', чтобы вы всегда возвращали результат 'CallNextHookEx'. В противном случае ваша программа заявляет, что полностью обработала это событие. –

Смежные вопросы