diff --git a/DDrawCompat/Common/BitSet.h b/DDrawCompat/Common/BitSet.h index fb268a2..b3afad4 100644 --- a/DDrawCompat/Common/BitSet.h +++ b/DDrawCompat/Common/BitSet.h @@ -29,6 +29,9 @@ public: } } + int getMax() const { return max; } + int getMin() const { return min; } + void reset() { m_bits.fill(0); diff --git a/DDrawCompat/Input/HotKey.cpp b/DDrawCompat/Input/HotKey.cpp index 4420c47..bec4df6 100644 --- a/DDrawCompat/Input/HotKey.cpp +++ b/DDrawCompat/Input/HotKey.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace { @@ -162,7 +163,7 @@ namespace return modifiers.find(either) == modifiers.end() && modifiers.find(left) == modifiers.end() && modifiers.find(right) == modifiers.end() && - (GetAsyncKeyState(either) & 0x8000); + Input::isKeyDown(either); } UINT getKeyCode(const std::string& name, const std::map& keyNames) @@ -223,7 +224,7 @@ namespace Input { for (auto modifier : modifiers) { - if (0 == (GetAsyncKeyState(modifier) & 0x8000)) + if (!isKeyDown(modifier)) { return false; } diff --git a/DDrawCompat/Input/Input.cpp b/DDrawCompat/Input/Input.cpp index d7c9105..f723afe 100644 --- a/DDrawCompat/Input/Input.cpp +++ b/DDrawCompat/Input/Input.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -46,6 +47,7 @@ namespace RECT g_monitorRect = {}; HHOOK g_keyboardHook = nullptr; HHOOK g_mouseHook = nullptr; + BitSet g_keyState; DInputMouseHookData g_dinputMouseHookData = {}; decltype(&PhysicalToLogicalPointForPerMonitorDPI) g_physicalToLogicalPointForPerMonitorDPI = nullptr; @@ -126,11 +128,24 @@ namespace if (HC_ACTION == nCode && (WM_KEYDOWN == wParam || WM_KEYUP == wParam || WM_SYSKEYDOWN == wParam || WM_SYSKEYUP == wParam)) { + auto llHook = reinterpret_cast(lParam); + if (static_cast(llHook->vkCode) >= g_keyState.getMin() && + static_cast(llHook->vkCode) <= g_keyState.getMax()) + { + if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN == wParam) + { + g_keyState.set(llHook->vkCode); + } + else + { + g_keyState.reset(llHook->vkCode); + } + } + DWORD pid = 0; GetWindowThreadProcessId(GetForegroundWindow(), &pid); if (GetCurrentProcessId() == pid) { - auto llHook = reinterpret_cast(lParam); for (auto& hotkey : g_hotKeys) { if (hotkey.first.vk == llHook->vkCode && Input::areModifierKeysDown(hotkey.first.modifiers)) @@ -235,7 +250,13 @@ namespace { UnhookWindowsHookEx(g_keyboardHook); } + + g_keyState.reset(); g_keyboardHook = CALL_ORIG_FUNC(SetWindowsHookExA)(WH_KEYBOARD_LL, &lowLevelKeyboardProc, nullptr, 0); + if (!g_keyboardHook) + { + LOG_ONCE("ERROR: Failed to install low level keyboard hook, error code: " << GetLastError()); + } }); } @@ -251,12 +272,19 @@ namespace g_origCursorPos = { MAXLONG, MAXLONG }; g_mouseHook = CALL_ORIG_FUNC(SetWindowsHookExA)(WH_MOUSE_LL, &lowLevelMouseProc, nullptr, 0); - INPUT inputs[2] = {}; - inputs[0].mi.dy = 1; - inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE; - inputs[1].mi.dx = 1; - inputs[1].mi.dwFlags = MOUSEEVENTF_MOVE; - SendInput(2, inputs, sizeof(INPUT)); + if (g_mouseHook) + { + INPUT inputs[2] = {}; + inputs[0].mi.dy = 1; + inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE; + inputs[1].mi.dx = 1; + inputs[1].mi.dwFlags = MOUSEEVENTF_MOVE; + SendInput(2, inputs, sizeof(INPUT)); + } + else + { + LOG_ONCE("ERROR: Failed to install low level mouse hook, error code: " << GetLastError()); + } }); } @@ -391,6 +419,25 @@ namespace Input registerHotKey(Config::terminateHotKey.get(), onTerminate, nullptr, false); } + bool isKeyDown(int vk) + { + switch (vk) + { + case VK_SHIFT: + return g_keyState.test(VK_LSHIFT) || g_keyState.test(VK_RSHIFT); + case VK_CONTROL: + return g_keyState.test(VK_LCONTROL) || g_keyState.test(VK_RCONTROL); + case VK_MENU: + return g_keyState.test(VK_LMENU) || g_keyState.test(VK_RMENU); + } + + if (vk >= g_keyState.getMin() && vk <= g_keyState.getMax()) + { + return g_keyState.test(vk); + } + return false; + } + void registerHotKey(const HotKey& hotKey, std::function action, void* context, bool onKeyDown) { if (0 != hotKey.vk) diff --git a/DDrawCompat/Input/Input.h b/DDrawCompat/Input/Input.h index 3ad3de7..2589b13 100644 --- a/DDrawCompat/Input/Input.h +++ b/DDrawCompat/Input/Input.h @@ -21,6 +21,7 @@ namespace Input HWND getCursorWindow(); POINT getRelativeCursorPos(); void installHooks(); + bool isKeyDown(int vk); void registerHotKey(const HotKey& hotKey, std::function action, void* context, bool onKeydown = true); void setCapture(Overlay::Control* control); void updateCursor();