2016-12-17 9 views
-1

Ребята из pls мне нужна помощь в исправлении того, что я сделал неправильно в своем коде. Я запускал код, и ошибок нет, но когда я пытаюсь выполнить комбинацию, он не делает то, что он должен делать (что «ключ А заблокирован»), поэтому мне нужна ваша помощь быстро, потому что мне нужно отправить это к понедельнику. Вот код:Как правильно использовать клавиатурные крючки, чтобы нажать комбинацию клавиш, чтобы заблокировать ключ, и снова нажать его, чтобы разблокировать его в C++.

#include "stdafx.h" 
#include <iostream> 
#include <conio.h> 
#include <Windows.h> 
#include <sstream> 
#define _WIN32_WINNT 0x050 

using namespace std; 

string intToHexString(int intValue) { 

    string hexStr; 

    /// integer value to hex-string 
    stringstream sstream; 
    sstream << "0x" << hex << (int)intValue; 

    hexStr = sstream.str(); 
    sstream.clear(); //clears out the stream-string 

    return hexStr; 
} 

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { 
    BOOL locked = FALSE; 
    PKBDLLHOOKSTRUCT hookStruct; 
    if (nCode == HC_ACTION) { 
     switch (wParam) 
     { 
     case WM_KEYDOWN: 
     case WM_SYSKEYDOWN: 
     case WM_KEYUP: 
     case WM_SYSKEYUP: 
      hookStruct = (PKBDLLHOOKSTRUCT)lParam; 
     /** 
     * this is where the problem is 
     */ 
      //ctrl+alt+n 
      if (hookStruct->vkCode == 0x11 && hookStruct->vkCode == 0x12 && hookStruct->vkCode == 0x4E 
       && !locked) { 
       locked = TRUE; 
       if (hookStruct->vkCode == 0x41) { 
        cout << "The key A is blocked" << endl; 
        return 1; 
       } 

      } 
      else if (hookStruct->vkCode == 0x11 && hookStruct->vkCode == 0x12 && hookStruct->vkCode == 0x4E) { 
       locked = FALSE; 
       BlockInput(locked); 
       cout << "The key is unblocked" << endl; 

      } 
      else { 
       return CallNextHookEx(NULL, nCode, wParam, lParam); 
      } 
     } 
    } 
    return CallNextHookEx(NULL, nCode, wParam, lParam); 
} 

int main() 
{ 
    char key_pressed; 
    int ascii_value; 
    string key_press_special; 
    HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0); 
    cout << "press any key to see it's Character, ASCII and Scan Code" << endl; 
    cout << "Press ESC key to Exit" << endl; 
    while(1) { 
     key_pressed = _getch(); 
     if (key_pressed == 13) { 
      key_press_special = "Enter"; 
      cout << "Character: " << key_press_special << endl; 
     } 
     else if (key_pressed == 9) { 
      key_press_special = "Tab"; 
      cout << "Character: " << key_press_special << endl; 
     } 
     else if (key_pressed == 27) { 
      key_press_special = "ESC"; 
      cout << "Character: " << key_press_special << endl; 
     } 

     else { 
      cout << "Character: " << key_pressed << endl; 
     } 
     ascii_value = key_pressed; 
     cout << "The ASCII Value is: " << ascii_value << endl; 
     int scan = MapVirtualKey(ascii_value, 0); 
     string scanCode = intToHexString(scan); 
     cout << "Scan Code is: " << scanCode << endl; 

     if (key_pressed == 27) { 
      break; 
     } 
     else { 
      continue; 
     } 
    } 

    UnhookWindowsHookEx(hhkLowLevelKybd); 

    return 0; 
} 

Pls не стесняется критиковать, когда вы видите ошибку, я все еще участвую.

+0

*** Я побежал код и нет никаких ошибок или ошибок, но когда я попробовать комбинацию, он не делает то, что это, предполагают, чтобы сделать ** * Разве это не определение ошибки? – drescherjm

+1

*** hookStruct-> vkCode == 0x11 && hookStruct-> vkCode == 0x12 && hookStruct-> vkCode == 0x4E *** Это никогда не может быть правдой. – drescherjm

+0

Извините, не знаю, было ли это определение –

ответ

1

Ваш крючок пытается обработать полную последовательность как один виртуальный ключ, и это просто не так, как он работает. Вы должны обрабатывать ключи отдельно.

Попробуйте что-то больше, как это вместо:

bool ctrlDown = false; 
bool altDown = false; 
bool nDown = false; 
bool locked = false; 

void UpdateLock() 
{ 
    if (ctrlDown && altDown && nDown) { 
     locked = !locked; 
     if (!locked) BlockInput(FALSE); 
     cout << (locked ? "" : "not ") << "locked" << endl; 
    } 
} 

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { 
    if (nCode == HC_ACTION) { 
     PKBDLLHOOKSTRUCT hookStruct = (PKBDLLHOOKSTRUCT) lParam; 
     switch (wParam) 
     { 
     case WM_KEYDOWN: 
     case WM_SYSKEYDOWN: 
      switch (hookStruct->vkCode) 
      { 
      case VK_CONTROL: 
       if (!ctrlDown) { 
        ctrlDown = true; 
        UpdateLock(); 
       } 
       break; 
      case VK_MENU: 
       if (!altDown) { 
        altDown = true; 
        UpdateLock(); 
       } 
       break; 
      case 'N': 
       if (!nDown) { 
        nDown = true; 
        UpdateLock(); 
       } 
       break; 
      } 
      break; 

     case WM_KEYUP: 
     case WM_SYSKEYUP: 
      switch (hookStruct->vkCode) 
      { 
      case VK_CONTROL: 
       ctrlDown = false; 
       break; 
      case VK_MENU: 
       altDown = false; 
       break; 
      case 'N': 
       nDown = false; 
       break; 
      } 
      break; 
     } 

     if ((hookStruct->vkCode == 'A') && locked) { 
      cout << "The key A is blocked" << endl; 
      return 1; 
     } 
    } 
    return CallNextHookEx(NULL, nCode, wParam, lParam); 
} 
+0

. Я реализовал ваш метод, но все еще не блокировал ключ A или вообще ничего не показывал из LowLevelKeyboardProc. –

+0

Вы проверили, что 'SetWindowsHookEx()' не терпит неудачу? Вы вызываете его с помощью 'dwThreadId = 0', чтобы установить глобальный крючок, который требует, чтобы код hook находился в DLL, поэтому его можно вводить в другие процессы, но вы устанавливаете' hMod = 0', поскольку код не находится в DLL. Если вы просто хотите подключить вызывающий поток, установите 'dwThreadId' в возвращаемое значение' GetCurrentThreadId() ' –