mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-01-18 14:41:21 +08:00
[KBM] Distinguish numpad keys (#28097)
This commit is contained in:
parent
c2bb2a8c3a
commit
efee03eb99
@ -5,6 +5,8 @@
|
||||
#include "keyboard_layout_impl.h"
|
||||
#include "shared_constants.h"
|
||||
|
||||
constexpr DWORD numpadOriginBit = 1ull << 31;
|
||||
|
||||
LayoutMap::LayoutMap() :
|
||||
impl(new LayoutMap::LayoutMapImpl())
|
||||
{
|
||||
@ -110,7 +112,6 @@ void LayoutMap::LayoutMapImpl::UpdateLayout()
|
||||
keyboardLayoutMap[VK_BACK] = L"Backspace";
|
||||
keyboardLayoutMap[VK_TAB] = L"Tab";
|
||||
keyboardLayoutMap[VK_CLEAR] = L"Clear";
|
||||
keyboardLayoutMap[VK_RETURN] = L"Enter";
|
||||
keyboardLayoutMap[VK_SHIFT] = L"Shift";
|
||||
keyboardLayoutMap[VK_CONTROL] = L"Ctrl";
|
||||
keyboardLayoutMap[VK_MENU] = L"Alt";
|
||||
@ -118,20 +119,36 @@ void LayoutMap::LayoutMapImpl::UpdateLayout()
|
||||
keyboardLayoutMap[VK_CAPITAL] = L"Caps Lock";
|
||||
keyboardLayoutMap[VK_ESCAPE] = L"Esc";
|
||||
keyboardLayoutMap[VK_SPACE] = L"Space";
|
||||
|
||||
keyboardLayoutMap[VK_LEFT] = L"Left";
|
||||
keyboardLayoutMap[VK_RIGHT] = L"Right";
|
||||
keyboardLayoutMap[VK_UP] = L"Up";
|
||||
keyboardLayoutMap[VK_DOWN] = L"Down";
|
||||
keyboardLayoutMap[VK_INSERT] = L"Insert";
|
||||
keyboardLayoutMap[VK_DELETE] = L"Delete";
|
||||
keyboardLayoutMap[VK_PRIOR] = L"PgUp";
|
||||
keyboardLayoutMap[VK_NEXT] = L"PgDn";
|
||||
keyboardLayoutMap[VK_END] = L"End";
|
||||
keyboardLayoutMap[VK_HOME] = L"Home";
|
||||
keyboardLayoutMap[VK_LEFT] = L"Left";
|
||||
keyboardLayoutMap[VK_UP] = L"Up";
|
||||
keyboardLayoutMap[VK_RIGHT] = L"Right";
|
||||
keyboardLayoutMap[VK_DOWN] = L"Down";
|
||||
keyboardLayoutMap[VK_END] = L"End";
|
||||
keyboardLayoutMap[VK_RETURN] = L"Enter";
|
||||
|
||||
keyboardLayoutMap[VK_LEFT | numpadOriginBit] = L"Left (Numpad)";
|
||||
keyboardLayoutMap[VK_RIGHT | numpadOriginBit] = L"Right (Numpad)";
|
||||
keyboardLayoutMap[VK_UP | numpadOriginBit] = L"Up (Numpad)";
|
||||
keyboardLayoutMap[VK_DOWN | numpadOriginBit] = L"Down (Numpad)";
|
||||
keyboardLayoutMap[VK_INSERT | numpadOriginBit] = L"Insert (Numpad)";
|
||||
keyboardLayoutMap[VK_DELETE | numpadOriginBit] = L"Delete (Numpad)";
|
||||
keyboardLayoutMap[VK_PRIOR | numpadOriginBit] = L"PgUp (Numpad)";
|
||||
keyboardLayoutMap[VK_NEXT | numpadOriginBit] = L"PgDn (Numpad)";
|
||||
keyboardLayoutMap[VK_HOME | numpadOriginBit] = L"Home (Numpad)";
|
||||
keyboardLayoutMap[VK_END | numpadOriginBit] = L"End (Numpad)";
|
||||
keyboardLayoutMap[VK_RETURN | numpadOriginBit] = L"Enter (Numpad)";
|
||||
keyboardLayoutMap[VK_DIVIDE | numpadOriginBit] = L"/ (Numpad)";
|
||||
|
||||
keyboardLayoutMap[VK_SELECT] = L"Select";
|
||||
keyboardLayoutMap[VK_PRINT] = L"Print";
|
||||
keyboardLayoutMap[VK_EXECUTE] = L"Execute";
|
||||
keyboardLayoutMap[VK_SNAPSHOT] = L"Print Screen";
|
||||
keyboardLayoutMap[VK_INSERT] = L"Insert";
|
||||
keyboardLayoutMap[VK_DELETE] = L"Delete";
|
||||
keyboardLayoutMap[VK_HELP] = L"Help";
|
||||
keyboardLayoutMap[VK_LWIN] = L"Win (Left)";
|
||||
keyboardLayoutMap[VK_RWIN] = L"Win (Right)";
|
||||
@ -275,6 +292,12 @@ std::vector<DWORD> LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcu
|
||||
}
|
||||
}
|
||||
|
||||
// Add numpad keys
|
||||
for (auto it = keyboardLayoutMap.rbegin(); it->first & numpadOriginBit; ++it)
|
||||
{
|
||||
keyCodes.push_back(it->first);
|
||||
}
|
||||
|
||||
// Sort the special keys in alphabetical order
|
||||
std::sort(specialKeys.begin(), specialKeys.end(), [&](const DWORD& lhs, const DWORD& rhs) {
|
||||
return keyboardLayoutMap[lhs] < keyboardLayoutMap[rhs];
|
||||
|
@ -207,6 +207,8 @@ LRESULT KeyboardManagerEditor::KeyHookProc(int nCode, WPARAM wParam, LPARAM lPar
|
||||
{
|
||||
event.lParam = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
|
||||
event.wParam = wParam;
|
||||
event.lParam->vkCode = Helpers::EncodeKeyNumpadOrigin(event.lParam->vkCode, event.lParam->flags & LLKHF_EXTENDED);
|
||||
|
||||
if (editor->HandleKeyboardHookEvent(&event) == 1)
|
||||
{
|
||||
// Reset Num Lock whenever a NumLock key down event is suppressed since Num Lock key state change occurs before it is intercepted by low level hooks
|
||||
|
@ -27,7 +27,7 @@ DWORD KeyDropDownControl::GetSelectedValue(ComboBox comboBox)
|
||||
}
|
||||
|
||||
auto value = winrt::unbox_value<hstring>(dataContext);
|
||||
return stoi(std::wstring(value));
|
||||
return stoul(std::wstring(value));
|
||||
}
|
||||
|
||||
void KeyDropDownControl::SetSelectedValue(std::wstring value)
|
||||
|
@ -42,8 +42,7 @@ namespace KeyboardEventHandlers
|
||||
key_count = std::get<Shortcut>(it->second).Size();
|
||||
}
|
||||
|
||||
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
LPINPUT keyEventList = new INPUT[size_t(key_count)]{};
|
||||
|
||||
// Handle remaps to VK_WIN_BOTH
|
||||
DWORD target;
|
||||
@ -148,7 +147,6 @@ namespace KeyboardEventHandlers
|
||||
}
|
||||
int key_count = 2;
|
||||
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
|
||||
Helpers::SetKeyEvent(keyEventList, 1, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
|
||||
|
||||
@ -232,8 +230,7 @@ namespace KeyboardEventHandlers
|
||||
{
|
||||
// key down for all new shortcut keys except the common modifiers
|
||||
key_count = dest_size - commonKeys;
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
int i = 0;
|
||||
Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
|
||||
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
@ -243,8 +240,7 @@ namespace KeyboardEventHandlers
|
||||
{
|
||||
// Dummy key, key up for all the original shortcut modifier keys and key down for all the new shortcut keys but common keys in each are not repeated
|
||||
key_count = KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE + (src_size - 1) + (dest_size) - (2 * static_cast<size_t>(commonKeys));
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
|
||||
// Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->Ctrl+V, press Win+A, since Win will be released here we need to send a dummy event before it
|
||||
int i = 0;
|
||||
@ -282,8 +278,7 @@ namespace KeyboardEventHandlers
|
||||
it->second.isOriginalActionKeyPressed = true;
|
||||
}
|
||||
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
|
||||
// Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->V, press Win+A, since Win will be released here we need to send a dummy event before it
|
||||
int i = 0;
|
||||
@ -302,7 +297,7 @@ namespace KeyboardEventHandlers
|
||||
// Modifier state reset might be required for this key depending on the shortcut's action and target modifier - ex: Win+Caps -> Ctrl
|
||||
if (it->first.GetCtrlKey() == NULL && it->first.GetAltKey() == NULL && it->first.GetShiftKey() == NULL)
|
||||
{
|
||||
ResetIfModifierKeyForLowerLevelKeyHandlers(ii,static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), data->lParam->vkCode);
|
||||
ResetIfModifierKeyForLowerLevelKeyHandlers(ii, static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), data->lParam->vkCode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,8 +356,7 @@ namespace KeyboardEventHandlers
|
||||
key_count += 1;
|
||||
}
|
||||
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
|
||||
// Release new shortcut state (release in reverse order of shortcut to be accurate)
|
||||
int i = 0;
|
||||
@ -400,8 +394,7 @@ namespace KeyboardEventHandlers
|
||||
key_count--;
|
||||
}
|
||||
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
|
||||
// Release new key state
|
||||
int i = 0;
|
||||
@ -453,8 +446,7 @@ namespace KeyboardEventHandlers
|
||||
}
|
||||
|
||||
size_t key_count = 1;
|
||||
LPINPUT keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
LPINPUT keyEventList = new INPUT[key_count]{};
|
||||
if (remapToShortcut)
|
||||
{
|
||||
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
@ -476,13 +468,12 @@ namespace KeyboardEventHandlers
|
||||
LPINPUT keyEventList;
|
||||
if (remapToShortcut)
|
||||
{
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
}
|
||||
else if (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)
|
||||
{
|
||||
// If remapped to disable, do nothing and suppress the key event
|
||||
// If remapped to disable, do nothing and suppress the key event
|
||||
// Since the original shortcut's action key is released, set it to false
|
||||
it->second.isOriginalActionKeyPressed = false;
|
||||
return 1;
|
||||
@ -491,13 +482,12 @@ namespace KeyboardEventHandlers
|
||||
{
|
||||
// Check if the keyboard state is clear apart from the target remap key (by creating a temp Shortcut object with the target key)
|
||||
bool isKeyboardStateClear = Shortcut(std::vector<int32_t>({ Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)) })).IsKeyboardStateClearExceptShortcut(ii);
|
||||
|
||||
|
||||
// If the keyboard state is clear, we release the target key but do not reset the remap state
|
||||
if (isKeyboardStateClear)
|
||||
{
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD,static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -507,8 +497,7 @@ namespace KeyboardEventHandlers
|
||||
// 1 for releasing new key and original shortcut modifiers, and dummy key
|
||||
key_count = dest_size + (src_size - 1) + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE;
|
||||
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
|
||||
// Release new key state
|
||||
int i = 0;
|
||||
@ -574,7 +563,7 @@ namespace KeyboardEventHandlers
|
||||
|
||||
size_t key_count;
|
||||
LPINPUT keyEventList = nullptr;
|
||||
|
||||
|
||||
// Check if a new remapping should be applied
|
||||
Shortcut currentlyPressed = it->first;
|
||||
currentlyPressed.actionKey = data->lParam->vkCode;
|
||||
@ -588,8 +577,7 @@ namespace KeyboardEventHandlers
|
||||
DWORD to = std::get<0>(newRemapping.targetShortcut);
|
||||
bool isLastKeyStillPressed = ii.GetVirtualKeyState(static_cast<WORD>(from.actionKey));
|
||||
key_count = static_cast<size_t>(from.Size()) - 1 + 1 + (isLastKeyStillPressed ? 1 : 0);
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
int i = 0;
|
||||
Helpers::SetModifierKeyEvents(from, it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
if (ii.GetVirtualKeyState(static_cast<WORD>(from.actionKey)))
|
||||
@ -599,7 +587,8 @@ namespace KeyboardEventHandlers
|
||||
i++;
|
||||
}
|
||||
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, static_cast<WORD>(to), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
Shortcut to = std::get<Shortcut>(newRemapping.targetShortcut);
|
||||
bool isLastKeyStillPressed = ii.GetVirtualKeyState(static_cast<WORD>(from.actionKey));
|
||||
@ -608,7 +597,7 @@ namespace KeyboardEventHandlers
|
||||
temp_key_count_calculation += static_cast<size_t>(to.Size()) - 1;
|
||||
temp_key_count_calculation -= static_cast<size_t>(2) * from.GetCommonModifiersCount(to);
|
||||
key_count = temp_key_count_calculation + 1 + (isLastKeyStillPressed ? 1 : 0);
|
||||
keyEventList = new INPUT[key_count]();
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
|
||||
int i = 0;
|
||||
Helpers::SetModifierKeyEvents(from, it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, to);
|
||||
@ -635,7 +624,7 @@ namespace KeyboardEventHandlers
|
||||
}
|
||||
else
|
||||
{
|
||||
// Key up for all new shortcut keys, key down for original shortcut modifiers and current key press but common keys aren't repeated
|
||||
// Key up for all new shortcut keys, key down for original shortcut modifiers and current key press but common keys aren't repeated
|
||||
key_count = (dest_size) + (src_size - 1) - (2 * static_cast<size_t>(commonKeys));
|
||||
|
||||
// If the target shortcut's action key is pressed, then it should be released and original shortcut's action key should be set
|
||||
@ -646,8 +635,7 @@ namespace KeyboardEventHandlers
|
||||
key_count += 2;
|
||||
}
|
||||
|
||||
keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
keyEventList = new INPUT[key_count]{};
|
||||
|
||||
// Release new shortcut state (release in reverse order of shortcut to be accurate)
|
||||
int i = 0;
|
||||
@ -719,8 +707,7 @@ namespace KeyboardEventHandlers
|
||||
// Key down for original shortcut modifiers and action key, and current key press
|
||||
size_t key_count = src_size + 1;
|
||||
|
||||
LPINPUT keyEventList = new INPUT[key_count]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
LPINPUT keyEventList = new INPUT[key_count]{};
|
||||
|
||||
// Set original shortcut key down state
|
||||
int i = 0;
|
||||
@ -730,7 +717,7 @@ namespace KeyboardEventHandlers
|
||||
if (isRemapToDisable && isOriginalActionKeyPressed)
|
||||
{
|
||||
// Set original action key
|
||||
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD,static_cast<WORD>(it->first.GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, static_cast<WORD>(it->first.GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
@ -812,7 +799,7 @@ namespace KeyboardEventHandlers
|
||||
std::wstring query_string;
|
||||
|
||||
AppSpecificShortcutRemapTable::iterator it;
|
||||
|
||||
|
||||
// Check if an app-specific shortcut is already activated
|
||||
if (state.GetActivatedApp() == KeyboardManagerConstants::NoActivatedApp)
|
||||
{
|
||||
@ -854,8 +841,7 @@ namespace KeyboardEventHandlers
|
||||
if (Helpers::IsModifierKey(key) && !(key == VK_LWIN || key == VK_RWIN || key == CommonSharedConstants::VK_WIN_BOTH))
|
||||
{
|
||||
int key_count = 1;
|
||||
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
|
||||
memset(keyEventList, 0, sizeof(keyEventList));
|
||||
LPINPUT keyEventList = new INPUT[size_t(key_count)]{};
|
||||
|
||||
// Use the suppress flag to ensure these are not intercepted by any remapped keys or shortcuts
|
||||
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, static_cast<WORD>(key), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG);
|
||||
|
@ -66,13 +66,14 @@ void KeyboardManager::LoadSettings()
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK KeyboardManager::HookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
LRESULT CALLBACK KeyboardManager::HookProc(int nCode, const WPARAM wParam, const LPARAM lParam)
|
||||
{
|
||||
LowlevelKeyboardEvent event;
|
||||
if (nCode == HC_ACTION)
|
||||
{
|
||||
event.lParam = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
|
||||
event.wParam = wParam;
|
||||
event.lParam->vkCode = Helpers::EncodeKeyNumpadOrigin(event.lParam->vkCode, event.lParam->flags & LLKHF_EXTENDED);
|
||||
if (keyboardManagerObjectPtr->HandleKeyboardHookEvent(&event) == 1)
|
||||
{
|
||||
// Reset Num Lock whenever a NumLock key down event is suppressed since Num Lock key state change occurs before it is intercepted by low level hooks
|
||||
@ -83,7 +84,7 @@ LRESULT CALLBACK KeyboardManager::HookProc(int nCode, WPARAM wParam, LPARAM lPar
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return CallNextHookEx(hookHandleCopy, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,50 @@
|
||||
|
||||
namespace Helpers
|
||||
{
|
||||
DWORD EncodeKeyNumpadOrigin(const DWORD key, const bool extended)
|
||||
{
|
||||
bool numpad_originated = false;
|
||||
switch (key)
|
||||
{
|
||||
case VK_LEFT:
|
||||
case VK_RIGHT:
|
||||
case VK_UP:
|
||||
case VK_DOWN:
|
||||
case VK_INSERT:
|
||||
case VK_DELETE:
|
||||
case VK_PRIOR:
|
||||
case VK_NEXT:
|
||||
case VK_HOME:
|
||||
case VK_END:
|
||||
numpad_originated = !extended;
|
||||
break;
|
||||
case VK_RETURN:
|
||||
case VK_DIVIDE:
|
||||
numpad_originated = extended;
|
||||
break;
|
||||
}
|
||||
|
||||
if (numpad_originated)
|
||||
return key | GetNumpadOriginEncodingBit();
|
||||
else
|
||||
return key;
|
||||
}
|
||||
|
||||
DWORD ClearKeyNumpadOrigin(const DWORD key)
|
||||
{
|
||||
return (key & ~GetNumpadOriginEncodingBit());
|
||||
}
|
||||
|
||||
bool IsNumpadOriginated(const DWORD key)
|
||||
{
|
||||
return !!(key & GetNumpadOriginEncodingBit());
|
||||
}
|
||||
DWORD GetNumpadOriginEncodingBit()
|
||||
{
|
||||
// Intentionally do not mimic KF_EXTENDED to avoid confusion, because it's not the same thing
|
||||
// See EncodeKeyNumpadOrigin.
|
||||
return 1ull << 31;
|
||||
}
|
||||
// Function to check if the key is a modifier key
|
||||
bool IsModifierKey(DWORD key)
|
||||
{
|
||||
@ -18,7 +62,8 @@ namespace Helpers
|
||||
// Function to get the combined key for modifier keys
|
||||
DWORD GetCombinedKey(DWORD key)
|
||||
{
|
||||
switch (key) {
|
||||
switch (key)
|
||||
{
|
||||
case VK_LWIN:
|
||||
case VK_RWIN:
|
||||
return CommonSharedConstants::VK_WIN_BOTH;
|
||||
|
@ -14,6 +14,12 @@ namespace Helpers
|
||||
Shift,
|
||||
Action
|
||||
};
|
||||
|
||||
// Functions to encode that a key is originated from numpad
|
||||
DWORD EncodeKeyNumpadOrigin(const DWORD key, const bool extended);
|
||||
DWORD ClearKeyNumpadOrigin(const DWORD key);
|
||||
bool IsNumpadOriginated(const DWORD key);
|
||||
DWORD GetNumpadOriginEncodingBit();
|
||||
|
||||
// Function to check if the key is a modifier key
|
||||
bool IsModifierKey(DWORD key);
|
||||
|
@ -194,7 +194,7 @@ DWORD Shortcut::GetShiftKey() const
|
||||
}
|
||||
|
||||
// Function to check if the input key matches the win key expected in the shortcut
|
||||
bool Shortcut::CheckWinKey(const DWORD& input) const
|
||||
bool Shortcut::CheckWinKey(const DWORD input) const
|
||||
{
|
||||
if (winKey == ModifierKey::Disabled)
|
||||
{
|
||||
@ -216,7 +216,7 @@ bool Shortcut::CheckWinKey(const DWORD& input) const
|
||||
}
|
||||
|
||||
// Function to check if the input key matches the ctrl key expected in the shortcut
|
||||
bool Shortcut::CheckCtrlKey(const DWORD& input) const
|
||||
bool Shortcut::CheckCtrlKey(const DWORD input) const
|
||||
{
|
||||
if (ctrlKey == ModifierKey::Disabled)
|
||||
{
|
||||
@ -238,7 +238,7 @@ bool Shortcut::CheckCtrlKey(const DWORD& input) const
|
||||
}
|
||||
|
||||
// Function to check if the input key matches the alt key expected in the shortcut
|
||||
bool Shortcut::CheckAltKey(const DWORD& input) const
|
||||
bool Shortcut::CheckAltKey(const DWORD input) const
|
||||
{
|
||||
if (altKey == ModifierKey::Disabled)
|
||||
{
|
||||
@ -260,7 +260,7 @@ bool Shortcut::CheckAltKey(const DWORD& input) const
|
||||
}
|
||||
|
||||
// Function to check if the input key matches the shift key expected in the shortcut
|
||||
bool Shortcut::CheckShiftKey(const DWORD& input) const
|
||||
bool Shortcut::CheckShiftKey(const DWORD input) const
|
||||
{
|
||||
if (shiftKey == ModifierKey::Disabled)
|
||||
{
|
||||
@ -282,7 +282,7 @@ bool Shortcut::CheckShiftKey(const DWORD& input) const
|
||||
}
|
||||
|
||||
// Function to set a key in the shortcut based on the passed key code argument. Returns false if it is already set to the same value. This can be used to avoid UI refreshing
|
||||
bool Shortcut::SetKey(const DWORD& input)
|
||||
bool Shortcut::SetKey(const DWORD input)
|
||||
{
|
||||
// Since there isn't a key for a common Win key we use the key code defined by us
|
||||
if (input == CommonSharedConstants::VK_WIN_BOTH)
|
||||
@ -394,7 +394,7 @@ bool Shortcut::SetKey(const DWORD& input)
|
||||
}
|
||||
|
||||
// Function to reset the state of a shortcut key based on the passed key code argument. Since there is no VK_WIN code, use the second argument for setting common win key.
|
||||
void Shortcut::ResetKey(const DWORD& input)
|
||||
void Shortcut::ResetKey(const DWORD input)
|
||||
{
|
||||
// Since there isn't a key for a common Win key this is handled with a separate argument.
|
||||
if (input == CommonSharedConstants::VK_WIN_BOTH || input == VK_LWIN || input == VK_RWIN)
|
||||
@ -415,7 +415,7 @@ void Shortcut::ResetKey(const DWORD& input)
|
||||
}
|
||||
else
|
||||
{
|
||||
actionKey = NULL;
|
||||
actionKey = {};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
#include "ModifierKey.h"
|
||||
|
||||
#include <compare>
|
||||
#include <tuple>
|
||||
#include <variant>
|
||||
|
||||
namespace KeyboardManagerInput
|
||||
@ -14,91 +17,34 @@ private:
|
||||
// Function to split a wstring based on a delimiter and return a vector of split strings
|
||||
std::vector<std::wstring> splitwstring(const std::wstring& input, wchar_t delimiter);
|
||||
|
||||
public:
|
||||
ModifierKey winKey;
|
||||
ModifierKey ctrlKey;
|
||||
ModifierKey altKey;
|
||||
ModifierKey shiftKey;
|
||||
DWORD actionKey;
|
||||
|
||||
// By default create an empty shortcut
|
||||
Shortcut() :
|
||||
winKey(ModifierKey::Disabled), ctrlKey(ModifierKey::Disabled), altKey(ModifierKey::Disabled), shiftKey(ModifierKey::Disabled), actionKey(NULL)
|
||||
inline auto comparator() const
|
||||
{
|
||||
return std::make_tuple(winKey, ctrlKey, altKey, shiftKey, actionKey);
|
||||
}
|
||||
|
||||
public:
|
||||
ModifierKey winKey = ModifierKey::Disabled;
|
||||
ModifierKey ctrlKey = ModifierKey::Disabled;
|
||||
ModifierKey altKey = ModifierKey::Disabled;
|
||||
ModifierKey shiftKey = ModifierKey::Disabled;
|
||||
DWORD actionKey = {};
|
||||
|
||||
Shortcut() = default;
|
||||
|
||||
// Constructor to initialize Shortcut from it's virtual key code string representation.
|
||||
Shortcut(const std::wstring& shortcutVK);
|
||||
|
||||
// Constructor to initialize shortcut from a list of keys
|
||||
Shortcut(const std::vector<int32_t>& keys);
|
||||
|
||||
// == operator
|
||||
inline bool operator==(const Shortcut& sc) const
|
||||
inline friend auto operator<=>(const Shortcut& lhs, const Shortcut& rhs) noexcept
|
||||
{
|
||||
return (winKey == sc.winKey && ctrlKey == sc.ctrlKey && altKey == sc.altKey && shiftKey == sc.shiftKey && actionKey == sc.actionKey);
|
||||
return lhs.comparator() <=> rhs.comparator();
|
||||
}
|
||||
|
||||
// Less than operator must be defined to use with std::map.
|
||||
inline bool operator<(const Shortcut& sc) const
|
||||
inline friend bool operator==(const Shortcut& lhs, const Shortcut& rhs) noexcept
|
||||
{
|
||||
// Compare win key first
|
||||
if (winKey < sc.winKey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (winKey > sc.winKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If win key is equal, then compare ctrl key
|
||||
if (ctrlKey < sc.ctrlKey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (ctrlKey > sc.ctrlKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If ctrl key is equal, then compare alt key
|
||||
if (altKey < sc.altKey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (altKey > sc.altKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If alt key is equal, then compare shift key
|
||||
if (shiftKey < sc.shiftKey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (shiftKey > sc.shiftKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If shift key is equal, then compare action key
|
||||
if (actionKey < sc.actionKey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lhs.comparator() == rhs.comparator();
|
||||
}
|
||||
|
||||
// Function to return the number of keys in the shortcut
|
||||
@ -126,22 +72,22 @@ public:
|
||||
DWORD GetShiftKey() const;
|
||||
|
||||
// Function to check if the input key matches the win key expected in the shortcut
|
||||
bool CheckWinKey(const DWORD& input) const;
|
||||
bool CheckWinKey(const DWORD input) const;
|
||||
|
||||
// Function to check if the input key matches the ctrl key expected in the shortcut
|
||||
bool CheckCtrlKey(const DWORD& input) const;
|
||||
bool CheckCtrlKey(const DWORD input) const;
|
||||
|
||||
// Function to check if the input key matches the alt key expected in the shortcut
|
||||
bool CheckAltKey(const DWORD& input) const;
|
||||
bool CheckAltKey(const DWORD input) const;
|
||||
|
||||
// Function to check if the input key matches the shift key expected in the shortcut
|
||||
bool CheckShiftKey(const DWORD& input) const;
|
||||
bool CheckShiftKey(const DWORD input) const;
|
||||
|
||||
// Function to set a key in the shortcut based on the passed key code argument. Returns false if it is already set to the same value. This can be used to avoid UI refreshing
|
||||
bool SetKey(const DWORD& input);
|
||||
bool SetKey(const DWORD input);
|
||||
|
||||
// Function to reset the state of a shortcut key based on the passed key code argument
|
||||
void ResetKey(const DWORD& input);
|
||||
void ResetKey(const DWORD input);
|
||||
|
||||
// Function to return the string representation of the shortcut in virtual key codes appended in a string by ";" separator.
|
||||
winrt::hstring ToHstringVK() const;
|
||||
|
Loading…
Reference in New Issue
Block a user