#include "Global.h" #include "KeyboardHook.h" #include "InputManager.h" #include "WindowsKeyboard.h" #include "Config.h" #include "VKey.h" #include "WndProcEater.h" #include "DeviceEnumerator.h" extern HINSTANCE hInst; LRESULT CALLBACK IgnoreKeyboardHook(int code, WPARAM wParam, LPARAM lParam); ExtraWndProcResult StartHooksWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output); class IgnoreKeyboardHookDevice; static IgnoreKeyboardHookDevice *ikhd = 0; class IgnoreKeyboardHookDevice : public WindowsKeyboard { public: HHOOK hHook; // When binding, eat all keys int binding; IgnoreKeyboardHookDevice() : WindowsKeyboard(IGNORE_KEYBOARD, L"Ignore Keyboard") { // Don't want to send keypress/keyrelease messages. for (int i=0; iDeactivate(); InitInfo *info = (InitInfo*) d; binding = info->bindingIgnore; if (info->hWndButton) EatWndProc(info->hWndButton, StartHooksWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); else EatWndProc(info->hWnd, StartHooksWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); InitState(); ikhd = this; active = 1; return 1; } void Deactivate() { FreeState(); if (active) { if (hHook) { UnhookWindowsHookEx(hHook); hHook = 0; } if (ikhd == this) ikhd = 0; active = 0; } } }; void EnumHookDevices() { dm->AddDevice(new IgnoreKeyboardHookDevice()); } // Makes sure hooks are started in correct thread. ExtraWndProcResult StartHooksWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) { // Don't remove too quickly - could be other things happening in other threads. // Attempted fix for keyboard input occasionally not working. static int counter = 0; if (ikhd && !ikhd->hHook && ikhd->active) { counter = 0; ikhd->hHook = SetWindowsHookEx(WH_KEYBOARD_LL, IgnoreKeyboardHook, hInst, 0); if (ikhd->hHook == 0) ikhd->Deactivate(); } counter ++; if (counter % 1000 == 0) return CONTINUE_BLISSFULLY_AND_RELEASE_PROC; else return CONTINUE_BLISSFULLY; } LRESULT CALLBACK IgnoreKeyboardHook(int code, WPARAM wParam, LPARAM lParam) { HHOOK hHook = 0; if (ikhd) { hHook = ikhd->hHook; if (hHook) { if (code == HC_ACTION) { if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) { KBDLLHOOKSTRUCT* key = (KBDLLHOOKSTRUCT*) lParam; if (key->vkCode < 256) { for (int i=0; ipads[0][0].numBindings; i++) { if (ikhd->pads[0][0].bindings[i].controlIndex == key->vkCode) { return 1; } } if (ikhd->binding){ ikhd->UpdateKey(key->vkCode, 1); return 1; } } if (config.vistaVolume) { if (key->vkCode == VK_VOLUME_DOWN) { SetVolume(config.volume-3); return 1; } if (key->vkCode == VK_VOLUME_UP) { SetVolume(config.volume+3); return 1; } } } else if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) { KBDLLHOOKSTRUCT* key = (KBDLLHOOKSTRUCT*) lParam; if (ikhd->binding && key->vkCode < 256) ikhd->UpdateKey(key->vkCode, 0); } } return CallNextHookEx(hHook, code, wParam, lParam); } } return CallNextHookEx(hHook, code, wParam, lParam); }