diff --git a/DDrawCompat/Config/Config.cpp b/DDrawCompat/Config/Config.cpp index c310ea5..6615246 100644 --- a/DDrawCompat/Config/Config.cpp +++ b/DDrawCompat/Config/Config.cpp @@ -30,6 +30,7 @@ namespace Config Settings::SpriteTexCoord spriteTexCoord; Settings::StatsHotKey statsHotKey; Settings::SupportedResolutions supportedResolutions; + Settings::TerminateHotKey terminateHotKey; Settings::TextureFilter textureFilter; Settings::ThreadPriorityBoost threadPriorityBoost; Settings::VSync vSync; diff --git a/DDrawCompat/Config/Config.h b/DDrawCompat/Config/Config.h index 7b2771c..d571c23 100644 --- a/DDrawCompat/Config/Config.h +++ b/DDrawCompat/Config/Config.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ namespace Config extern Settings::SpriteTexCoord spriteTexCoord; extern Settings::StatsHotKey statsHotKey; extern Settings::SupportedResolutions supportedResolutions; + extern Settings::TerminateHotKey terminateHotKey; extern Settings::TextureFilter textureFilter; extern Settings::ThreadPriorityBoost threadPriorityBoost; extern Settings::VSync vSync; diff --git a/DDrawCompat/Config/Settings/TerminateHotKey.h b/DDrawCompat/Config/Settings/TerminateHotKey.h new file mode 100644 index 0000000..23350fe --- /dev/null +++ b/DDrawCompat/Config/Settings/TerminateHotKey.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace Config +{ + namespace Settings + { + class TerminateHotKey : public HotKeySetting + { + public: + TerminateHotKey() : HotKeySetting("TerminateHotKey", "ctrl+alt+end") {} + }; + } +} diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index 7f27339..ab2693c 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -187,6 +187,7 @@ + diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index 4a94e93..9b080e1 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -630,6 +630,9 @@ Header Files\Config\Settings + + Header Files\Config\Settings + diff --git a/DDrawCompat/Input/HotKey.cpp b/DDrawCompat/Input/HotKey.cpp index fc09d27..4420c47 100644 --- a/DDrawCompat/Input/HotKey.cpp +++ b/DDrawCompat/Input/HotKey.cpp @@ -148,6 +148,15 @@ namespace return names; }(); + const std::map g_altKeyNames = { + { "alt", VK_MENU }, + { "lalt", VK_LMENU }, + { "ralt", VK_RMENU }, + { "ctrl", VK_CONTROL }, + { "lctrl", VK_LCONTROL }, + { "rctrl", VK_RCONTROL } + }; + bool areExcludedModifierKeysDown(const std::set& modifiers, UINT either, UINT left, UINT right) { return modifiers.find(either) == modifiers.end() && @@ -156,6 +165,12 @@ namespace (GetAsyncKeyState(either) & 0x8000); } + UINT getKeyCode(const std::string& name, const std::map& keyNames) + { + auto it = keyNames.find(name); + return it != keyNames.end() ? it->second : 0; + } + UINT getKeyCode(const std::string& name) { if (1 == name.length()) @@ -167,12 +182,22 @@ namespace } } - auto it = g_keyNames.find(name); - if (it == g_keyNames.end()) + auto code = getKeyCode(name, g_altKeyNames); + if (0 == code) { - throw Config::ParsingError("Invalid hotkey: '" + name + "'"); + code = getKeyCode(name, g_keyNames); + if (0 == code) + { + throw Config::ParsingError("Invalid hotkey: '" + name + "'"); + } } - return it->second; + return code; + } + + std::string getKeyName(UINT key, const std::map& keyNames) + { + auto it = std::find_if(keyNames.begin(), keyNames.end(), [&](const auto& pair) { return pair.second == key; }); + return it != keyNames.end() ? it->first : std::string(); } std::string getKeyName(UINT key) @@ -183,8 +208,12 @@ namespace return std::string(1, static_cast(std::tolower(key, std::locale()))); } - auto it = std::find_if(g_keyNames.begin(), g_keyNames.end(), [&](const auto& pair) { return pair.second == key; }); - return it != g_keyNames.end() ? it->first : "none"; + auto name(getKeyName(key, g_altKeyNames)); + if (name.empty()) + { + name = getKeyName(key, g_keyNames); + } + return name.empty() ? "none" : name; } } diff --git a/DDrawCompat/Input/Input.cpp b/DDrawCompat/Input/Input.cpp index a646887..d73685e 100644 --- a/DDrawCompat/Input/Input.cpp +++ b/DDrawCompat/Input/Input.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -21,6 +22,7 @@ namespace { std::function action; void* context; + bool onKeyDown; }; HANDLE g_bmpArrow = nullptr; @@ -93,7 +95,7 @@ namespace { if (hotkey.first.vk == llHook->vkCode && Input::areModifierKeysDown(hotkey.first.modifiers)) { - if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN == wParam) + if (hotkey.second.onKeyDown == (WM_KEYDOWN == wParam || WM_SYSKEYDOWN == wParam)) { hotkey.second.action(hotkey.second.context); } @@ -146,6 +148,12 @@ namespace return CallNextHookEx(nullptr, nCode, wParam, lParam); } + void onTerminate(void* /*context*/) + { + LOG_INFO << "Terminating application via TerminateHotKey"; + TerminateProcess(GetCurrentProcess(), 0); + } + void resetKeyboardHook() { Gdi::GuiThread::execute([]() @@ -251,13 +259,15 @@ namespace Input HOOK_FUNCTION(user32, SetWindowsHookExA, setWindowsHookExA); HOOK_FUNCTION(user32, SetWindowsHookExW, setWindowsHookExW); + + registerHotKey(Config::terminateHotKey.get(), onTerminate, nullptr, false); } - void registerHotKey(const HotKey& hotKey, std::function action, void* context) + void registerHotKey(const HotKey& hotKey, std::function action, void* context, bool onKeyDown) { if (0 != hotKey.vk) { - g_hotKeys[hotKey] = { action, context }; + g_hotKeys[hotKey] = { action, context, onKeyDown }; if (!g_keyboardHook) { resetKeyboardHook(); diff --git a/DDrawCompat/Input/Input.h b/DDrawCompat/Input/Input.h index 601fd6c..8462002 100644 --- a/DDrawCompat/Input/Input.h +++ b/DDrawCompat/Input/Input.h @@ -21,7 +21,7 @@ namespace Input POINT getCursorPos(); HWND getCursorWindow(); void installHooks(); - void registerHotKey(const HotKey& hotKey, std::function action, void* context); + void registerHotKey(const HotKey& hotKey, std::function action, void* context, bool onKeydown = true); void setCapture(Overlay::Control* control); void updateCursor(); }