fork download
  1. #ifndef UNICODE
  2. #define UNICODE
  3. #define _UNICODE
  4. #endif
  5. #include <windows.h>
  6. #include <stdio.h>
  7.  
  8. static HHOOK hHook;
  9.  
  10. static LRESULT CALLBACK LowLevelKeyboradProc(int code, WPARAM wParam, LPARAM lParam)
  11. {
  12. // Итак, у нас какое-то клавиатурное событие, и нам нужно БЫСТРО его
  13. // обработать.
  14.  
  15. // Во-первых, тупо передаем события с отрицательным кодом дальше, как того
  16. // требует MSDN. Не обрабатываем. Передали дальше и вернули, что вернулось.
  17. // Но так как нас интересует только HC_ACTION, то мы поступаем так же со
  18. // всеми остальными событиями.
  19. if (code != HC_ACTION) // if (code < 0 && code != HC_ACTION)
  20. {
  21. return CallNextHookEx(hHook, code, wParam, lParam);
  22. }
  23.  
  24. // Во-вторых, нам нужна инфа о событии. В wParam у нас тип события, а
  25. // lParam указывает на все остальное.
  26. UINT msg = (UINT) wParam;
  27. KBDLLHOOKSTRUCT *info = (KBDLLHOOKSTRUCT *) lParam;
  28.  
  29. // Для примера ломаем клавишу Q. Независимо от раскладки. Так как мы
  30. // возвращаем не 0 на сообщения о ее нажатии/отжатии, эти сообщения не
  31. // будут обрабатываться дальше.
  32. if (info->vkCode == VK_Q)
  33. {
  34. const char *action = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) ? "pressed" : "released";
  35. printf("Q key was %s!\n", action);
  36.  
  37. return 1;
  38. }
  39.  
  40. // Все остальное передаем дальше, другим хукам, и возвращаем то, что
  41. // вернулось от них.
  42. return CallNextHookEx(hHook, code, wParam, lParam);
  43. }
  44.  
  45. int main(void)
  46. {
  47. // Устанавливаем хук. При нажатии и отпускании клавиш в любом потоке будет
  48. // переключение контекста на наш поток и вызов LowLevelKeyboradProc.
  49. hHook = SetWindowsHookEx(WH_KEYBOARD_LL, &LowLevelKeyboradProc, GetModuleHandle(NULL), 0);
  50.  
  51. if (hHook)
  52. {
  53. // Обрабатываем сообщения своего потока. Это крайне желательно делать.
  54. MSG msg;
  55.  
  56. // Получаем очередное сообщения для потока. Если это WM_QUIT (= 0), то
  57. // завершаем работу, если это какое-то другое - отдаем на обработку
  58. // обратно системе, пусть сама разбирается.
  59. while (GetMessage(&msg, NULL, 0, 0))
  60. {
  61. DispatchMessage(&msg);
  62. }
  63.  
  64. // Убираем за собой хук и выходим.
  65. UnhookWindowsHookEx(hHook);
  66. return 0;
  67. }
  68. else
  69. {
  70. // SetWindowsHookEx вернула NULL.
  71. MessageBoxW(NULL, L"Unable to install hook.", L"Error", MB_ICONERROR);
  72. return 1;
  73. }
  74. }
  75.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c:5:21: fatal error: windows.h: No such file or directory
compilation terminated.
stdout
Standard output is empty