mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
[Keyboard Manager] Added in Shortcut to Key and Key to Shortcut remapping (#5070)
* Added union class * Added key to shortcut backend implementation * Added tests * Added tests for CapsLock/modifier workaround for key to shortcut * Added correct JSON loading step * Cleaned shortcut remap code to use helper function for modifier keys * Removed RemapKey class * Enable Key to Shortcut in UI along with Type Shortcut in Remap key window * Fixed orphaning and unsuccessful remap dialog * Fixed column width * Renamed second type key button * Fixed Type Shortcut issues * Fixed shortcut to key backend logic and manually tested most scenarios * Added s2k in UI, manually verified its working * Added one more k2s test * Added tests for s2k * Added tests for Caps Lock workaround in shortcut remaps * Fixed formatting * Fixed formatting * Removed safety code since it can cause issues with code generated key up events * Added test for key up scenario * Tweaked warning text * Tweaked text * Tweaked text to fit in two lines * telemetry additions
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
|
||||
namespace RemappingLogicTests
|
||||
{
|
||||
TEST_CLASS (AppSpecificShortcutRemappingTests)
|
||||
@@ -40,7 +39,7 @@ namespace RemappingLogicTests
|
||||
dest.SetKey(VK_MENU);
|
||||
dest.SetKey(0x56);
|
||||
testState.AddAppSpecificShortcut(testApp1, src, dest);
|
||||
|
||||
|
||||
// Set the testApp as the foreground process
|
||||
mockedInputHandler.SetForegroundProcess(testApp1);
|
||||
|
||||
@@ -86,7 +85,7 @@ namespace RemappingLogicTests
|
||||
// Send Ctrl+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl and A key states should be unchanged, Alt and V key states should be true
|
||||
// Ctrl and A key states should be true, Alt and V key states should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
@@ -172,12 +171,146 @@ namespace RemappingLogicTests
|
||||
// Release A then Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
|
||||
// Ctrl, A, Alt and Tab should all be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_TAB), false);
|
||||
}
|
||||
|
||||
// Test if the app specific shortcut to key remap takes place when the target app is in foreground
|
||||
TEST_METHOD (AppSpecificShortcutToSingleKey_ShouldGetRemapped_WhenAppIsInForeground)
|
||||
{
|
||||
// Remap Ctrl+A to V
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddAppSpecificShortcut(testApp1, src, 0x56);
|
||||
|
||||
// Set the testApp as the foreground process
|
||||
mockedInputHandler.SetForegroundProcess(testApp1);
|
||||
|
||||
const int nInputs = 2;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
|
||||
// Send Ctrl+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl and A key states should be unchanged, V key states should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
|
||||
}
|
||||
|
||||
// Test if the app specific shortcut to key remap takes place when the target app is not in foreground
|
||||
TEST_METHOD (AppSpecificShortcutToSingleKey_ShouldNotGetRemapped_WhenAppIsNotInForeground)
|
||||
{
|
||||
// Remap Ctrl+A to V
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddAppSpecificShortcut(testApp1, src, 0x56);
|
||||
|
||||
// Set the testApp as the foreground process
|
||||
mockedInputHandler.SetForegroundProcess(testApp2);
|
||||
|
||||
const int nInputs = 2;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
|
||||
// Send Ctrl+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl and A key states should be true, V key state should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
}
|
||||
|
||||
// Test if the the keyboard manager state's activated app is correctly set after an app specific shortcut to key remap takes place
|
||||
TEST_METHOD (AppSpecificShortcutToSingleKey_ShouldSetCorrectActivatedApp_WhenRemapOccurs)
|
||||
{
|
||||
// Remap Ctrl+A to V
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddAppSpecificShortcut(testApp1, src, 0x56);
|
||||
|
||||
// Set the testApp as the foreground process
|
||||
mockedInputHandler.SetForegroundProcess(testApp1);
|
||||
|
||||
const int nInputs = 2;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
|
||||
// Send Ctrl+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Activated app should be testApp1
|
||||
Assert::AreEqual(testApp1, testState.GetActivatedApp());
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release A then Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Activated app should be empty string
|
||||
Assert::AreEqual(std::wstring(KeyboardManagerConstants::NoActivatedApp), testState.GetActivatedApp());
|
||||
}
|
||||
// Test if the key states get cleared if foreground app changes after app-specific shortcut to key shortcut is invoked and then released
|
||||
TEST_METHOD (AppSpecificShortcutToSingleKey_ShouldClearKeyStates_WhenForegroundAppChangesAfterShortcutIsPressedOnRelease)
|
||||
{
|
||||
// Remap Ctrl+A to V
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddAppSpecificShortcut(testApp1, src, 0x56);
|
||||
|
||||
// Set the testApp as the foreground process
|
||||
mockedInputHandler.SetForegroundProcess(testApp1);
|
||||
|
||||
const int nInputs = 2;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
|
||||
// Send Ctrl+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Set the testApp as the foreground process
|
||||
mockedInputHandler.SetForegroundProcess(testApp2);
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release A then Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, A, V should all be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -156,6 +156,6 @@ void MockedInput::SetForegroundProcess(std::wstring process)
|
||||
|
||||
// Function to get the foreground process name
|
||||
void MockedInput::GetForegroundProcess(_Out_ std::wstring& foregroundProcess)
|
||||
{
|
||||
{
|
||||
foregroundProcess = currentProcess;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,16 @@ namespace RemappingLogicTests
|
||||
|
||||
// Set HandleOSLevelShortcutRemapEvent as the hook procedure
|
||||
std::function<intptr_t(LowlevelKeyboardEvent*)> currentHookProc = std::bind(&KeyboardEventHandlers::HandleOSLevelShortcutRemapEvent, std::ref(mockedInputHandler), std::placeholders::_1, std::ref(testState));
|
||||
mockedInputHandler.SetHookProc(currentHookProc);
|
||||
mockedInputHandler.SetHookProc([currentHookProc](LowlevelKeyboardEvent* data) {
|
||||
if (data->lParam->dwExtraInfo != KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
|
||||
{
|
||||
return currentHookProc(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (intptr_t)1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set for a 2 key shortcut remap wih different modifiers key down
|
||||
@@ -1105,5 +1114,895 @@ namespace RemappingLogicTests
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set for a 2 key shortcut to a single key remap not containing that key on key down followed by key up
|
||||
TEST_METHOD (RemappedTwoKeyShortcutToSingleKeyNotContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents)
|
||||
{
|
||||
// Remap Ctrl+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
|
||||
const int nInputs = 2;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
|
||||
// Send Ctrl+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, A should be false, Alt should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release Ctrl+A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, A, Alt should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set for a 3 key shortcut to a single key remap not containing that key on key down followed by key up
|
||||
TEST_METHOD (RemappedThreeKeyShortcutToSingleKeyNotContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents)
|
||||
{
|
||||
// Remap Ctrl+Shift+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(VK_SHIFT);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_SHIFT;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
|
||||
// Send Ctrl+Shift+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, Shift, A should be false, Alt should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_SHIFT;
|
||||
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = VK_CONTROL;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release Ctrl+Shift+A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, Shift, A, Alt should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set for a 2 key shortcut to a single key remap containing that key on key down followed by key up
|
||||
TEST_METHOD (RemappedTwoKeyShortcutToSingleKeyContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents)
|
||||
{
|
||||
// Remap Ctrl+A to Ctrl
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_CONTROL);
|
||||
|
||||
const int nInputs = 2;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
|
||||
// Send Ctrl+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A should be false, Ctrl should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release Ctrl+A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, A should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set for a 3 key shortcut to a single key remap containing that key on key down followed by key up
|
||||
TEST_METHOD (RemappedThreeKeyShortcutToSingleKeyContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents)
|
||||
{
|
||||
// Remap Ctrl+Shift+A to Ctrl
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(VK_SHIFT);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_CONTROL);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_SHIFT;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
|
||||
// Send Ctrl+Shift+A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Shift, A should be false, Ctrl should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_SHIFT;
|
||||
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = VK_CONTROL;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release Ctrl+Shift+A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, Shift, A should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
}
|
||||
|
||||
// Test if keyboard state is reverted for a shortcut to a single key remap (target key is not a part of the shortcut) on key down followed by releasing the action key
|
||||
TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsNotInShortcut_ShouldSetOriginalModifier_OnReleasingActionKey)
|
||||
{
|
||||
// Remap Ctrl+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Press Ctrl+A, release A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, Alt should be false, Ctrl should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
}
|
||||
|
||||
// Test if keyboard state is reverted for a shortcut to a single key remap (target key is a modifier in the shortcut) on key down followed by releasing the action key
|
||||
TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsAModifierInShortcut_ShouldSetOriginalModifier_OnReleasingActionKey)
|
||||
{
|
||||
// Remap Ctrl+A to Ctrl
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_CONTROL);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Press Ctrl+A, release A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A should be false, Ctrl should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
}
|
||||
|
||||
// Test if keyboard state is reverted for a shortcut to a single key remap (target key is the action key in the shortcut) on key down followed by releasing the action key
|
||||
TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsActionKeyInShortcut_ShouldSetOriginalModifier_OnReleasingActionKey)
|
||||
{
|
||||
// Remap Ctrl+A to A
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, 0x41);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Press Ctrl+A, release A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A should be false, Ctrl should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
}
|
||||
|
||||
// Test if keyboard state is reverted for a shortcut to a single key remap (target key is not a part of the shortcut) on key down followed by releasing the modifier key
|
||||
TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsNotInShortcut_ShouldSetOriginalModifier_OnReleasingModifierKey)
|
||||
{
|
||||
// Remap Ctrl+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = VK_CONTROL;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Press Ctrl+A, release Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, Alt, Ctrl should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
}
|
||||
|
||||
// Test if keyboard state is reverted for a shortcut to a single key remap (target key is a modifier in the shortcut) on key down followed by releasing the modifier key
|
||||
TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsAModifierInShortcut_ShouldSetOriginalModifier_OnReleasingModifierKey)
|
||||
{
|
||||
// Remap Ctrl+A to Ctrl
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_CONTROL);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = VK_CONTROL;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Press Ctrl+A, release Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, Ctrl should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
}
|
||||
|
||||
// Test if keyboard state is reverted for a shortcut to a single key remap (target key is the action key in the shortcut) on key down followed by releasing the modifier key
|
||||
TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsActionKeyInShortcut_ShouldSetOriginalModifier_ModifierKey)
|
||||
{
|
||||
// Remap Ctrl+A to A
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, 0x41);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = VK_CONTROL;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Press Ctrl+A, release Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, Ctrl should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
}
|
||||
|
||||
// Test if remap is invoked for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed before it
|
||||
TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvoked_IfOtherKeysArePressedAlongWithIt)
|
||||
{
|
||||
// Remap Ctrl+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x42;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
|
||||
// Press B+Ctrl+A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, Ctrl should be false, B, Alt should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
|
||||
}
|
||||
|
||||
// Test that remap is not invoked for a shortcut to a single key remap when a larger remapped shortcut to shortcut containing those shortcut keys is invoked
|
||||
TEST_METHOD (RemappedShortcutToSingleKey_ShouldNotBeInvoked_IfALargerRemappedShortcutToShortcutContainingThoseShortcutKeysIsInvoked)
|
||||
{
|
||||
// Remap Ctrl+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
// Remap Shift+Ctrl+A to Ctrl+V
|
||||
src.SetKey(VK_SHIFT);
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_CONTROL);
|
||||
dest.SetKey(0x56);
|
||||
testState.AddOSLevelShortcut(src, dest);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_SHIFT;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
|
||||
// Press Shift+Ctrl+A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Alt, A, Shift should be false, Ctrl, V should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
|
||||
}
|
||||
|
||||
// Test that remap is not invoked for a shortcut to a single key remap when a larger remapped shortcut to key containing those shortcut keys is invoked
|
||||
TEST_METHOD (RemappedShortcutToSingleKey_ShouldNotBeInvoked_IfALargerRemappedShortcutToKeyContainingThoseShortcutKeysIsInvoked)
|
||||
{
|
||||
// Remap Ctrl+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
// Remap Shift+Ctrl+A to B
|
||||
src.SetKey(VK_SHIFT);
|
||||
testState.AddOSLevelShortcut(src, 0x42);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_SHIFT;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
|
||||
// Press Shift+Ctrl+A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Alt, Ctrl, A, Shift should be false, B should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
|
||||
}
|
||||
|
||||
// Test if remap is invoked for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed after it and then action key is released
|
||||
TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvoked_IfOtherKeysArePressedAfterItAndActionKeyIsReleased)
|
||||
{
|
||||
// Remap Ctrl+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x42;
|
||||
|
||||
// Press Ctrl+A+B
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, Ctrl should be false, B, Alt should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release A
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
|
||||
// A, Alt should be false, Ctrl, B should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
|
||||
}
|
||||
|
||||
// Test if remap is invoked for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed after it and modifier key is released
|
||||
TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvoked_IfOtherKeysArePressedAfterItAndModifierKeyIsReleased)
|
||||
{
|
||||
// Remap Ctrl+A to Alt
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, VK_MENU);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x42;
|
||||
|
||||
// Press Ctrl+A+B
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, Ctrl should be false, B, Alt should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release Ctrl
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, Alt, A should be false, B should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
|
||||
}
|
||||
|
||||
// Test if Windows left key state is set when a shortcut remap to Win both is invoked
|
||||
TEST_METHOD (RemappedShortcutToWinBoth_ShouldSetLWinKeyState_OnKeyEvent)
|
||||
{
|
||||
// Remap Ctrl+A to Win both
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, CommonSharedConstants::VK_WIN_BOTH);
|
||||
|
||||
const int nInputs = 2;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
|
||||
// Press Ctrl+A
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, Ctrl should be false, LWin should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), true);
|
||||
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CONTROL;
|
||||
input[1].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Release A, Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Ctrl, A, LWin should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
}
|
||||
|
||||
// Test if invoking two remapped shortcuts that share modifiers, where the first one remaps to a key and the second one remaps to a shortcut, in succession sets the correct keyboard states
|
||||
TEST_METHOD (TwoRemappedShortcutsThatShareModifiersWhereFirstOneRemapsToAKeyAndSecondOneRemapsToAShortcut_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap)
|
||||
{
|
||||
// Remap Alt+A to D
|
||||
Shortcut src;
|
||||
src.SetKey(VK_MENU);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, 0x44);
|
||||
|
||||
// Remap Alt+V to Ctrl+X
|
||||
Shortcut src1;
|
||||
src1.SetKey(VK_MENU);
|
||||
src1.SetKey(0x56);
|
||||
Shortcut dest1;
|
||||
dest1.SetKey(VK_CONTROL);
|
||||
dest1.SetKey(0x58);
|
||||
testState.AddOSLevelShortcut(src1, dest1);
|
||||
|
||||
const int nInputs = 4;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_MENU;
|
||||
input[0].ki.dwFlags = 0;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[1].ki.dwFlags = 0;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[3].type = INPUT_KEYBOARD;
|
||||
input[3].ki.wVk = 0x56;
|
||||
input[3].ki.dwFlags = 0;
|
||||
|
||||
// Send Alt+A, release A, press V
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Alt, A, D, V key states should be unchanged, Ctrl, X should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x44), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
|
||||
}
|
||||
|
||||
// Test if invoking two remapped shortcuts that share modifiers, where the first one remaps to a key and the second one remaps to a key, in succession sets the correct keyboard states
|
||||
TEST_METHOD (TwoRemappedShortcutsThatShareModifiersWhereFirstOneRemapsToAKeyAndSecondOneRemapsToAKey_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap)
|
||||
{
|
||||
// Remap Alt+A to D
|
||||
Shortcut src;
|
||||
src.SetKey(VK_MENU);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, 0x44);
|
||||
|
||||
// Remap Alt+V to X
|
||||
Shortcut src1;
|
||||
src1.SetKey(VK_MENU);
|
||||
src1.SetKey(0x56);
|
||||
testState.AddOSLevelShortcut(src1, 0x58);
|
||||
|
||||
const int nInputs = 4;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_MENU;
|
||||
input[0].ki.dwFlags = 0;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[1].ki.dwFlags = 0;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[3].type = INPUT_KEYBOARD;
|
||||
input[3].ki.wVk = 0x56;
|
||||
input[3].ki.dwFlags = 0;
|
||||
|
||||
// Send Alt+A, release A, press V
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Alt, A, D, V key states should be unchanged, X should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x44), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
|
||||
}
|
||||
|
||||
// Test if invoking two remapped shortcuts that share modifiers, where the first one remaps to a shortcut and the second one remaps to a key, in succession sets the correct keyboard states
|
||||
TEST_METHOD (TwoRemappedShortcutsThatShareModifiersWhereFirstOneRemapsToAShortcutAndSecondOneRemapsToAKey_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap)
|
||||
{
|
||||
// Remap Alt+A to Ctrl+C
|
||||
Shortcut src;
|
||||
src.SetKey(VK_MENU);
|
||||
src.SetKey(0x41);
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_CONTROL);
|
||||
dest.SetKey(0x43);
|
||||
testState.AddOSLevelShortcut(src, dest);
|
||||
|
||||
// Remap Alt+V to X
|
||||
Shortcut src1;
|
||||
src1.SetKey(VK_MENU);
|
||||
src1.SetKey(0x56);
|
||||
testState.AddOSLevelShortcut(src1, 0x58);
|
||||
|
||||
const int nInputs = 4;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_MENU;
|
||||
input[0].ki.dwFlags = 0;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[1].ki.dwFlags = 0;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[3].type = INPUT_KEYBOARD;
|
||||
input[3].ki.wVk = 0x56;
|
||||
input[3].ki.dwFlags = 0;
|
||||
|
||||
// Send Alt+A, release A, press V
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// Alt, A, C, V, Ctrl key states should be unchanged, X should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x44), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set if a shortcut to single key remap is pressed and then an unremapped shortcut with the same modifier is pressed - Ex: Ctrl+A is remapped. User invokes Ctrl+A then releases A and presses C (while Ctrl is held), should invoke Ctrl+C
|
||||
TEST_METHOD (InvokingUnremappedShortcutAfterRemappedShortcutToSingleKeyWithSameModifier_ShouldSetUnremappedShortcut_OnKeyDown)
|
||||
{
|
||||
// Remap Ctrl+A to V
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, 0x56);
|
||||
|
||||
const int nInputs = 4;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x41;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
input[3].type = INPUT_KEYBOARD;
|
||||
input[3].ki.wVk = 0x43;
|
||||
|
||||
// Send Ctrl+A keydown, A key up, then C key down
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A, V key states should be unchanged, Ctrl, C should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x43), true);
|
||||
}
|
||||
|
||||
// Test if SendVirtualInput is sent exactly once with the suppress flag when Win+CapsLock is remapped to shortcut containing Ctrl
|
||||
TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenWinCapsLockIsMappedToShortcutContainingCtrl)
|
||||
{
|
||||
// Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
|
||||
mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
|
||||
if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
// Remap Win+CapsLock to Ctrl+A
|
||||
Shortcut src;
|
||||
src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
|
||||
src.SetKey(VK_CAPITAL);
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_CONTROL);
|
||||
dest.SetKey(0x41);
|
||||
testState.AddOSLevelShortcut(src, dest);
|
||||
|
||||
const int nInputs = 2;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_LWIN;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CAPITAL;
|
||||
|
||||
// Send LWin+CapsLock keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// SendVirtualInput should be called exactly once with the above condition
|
||||
Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
|
||||
}
|
||||
|
||||
// Test if SendVirtualInput is sent exactly once with the suppress flag when Win+CapsLock is remapped to Ctrl
|
||||
TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenWinCapsLockIsMappedToCtrl)
|
||||
{
|
||||
// Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
|
||||
mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
|
||||
if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
// Remap Win+CapsLock to Ctrl+A
|
||||
Shortcut src;
|
||||
src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
|
||||
src.SetKey(VK_CAPITAL);
|
||||
testState.AddOSLevelShortcut(src, VK_CONTROL);
|
||||
|
||||
const int nInputs = 2;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_LWIN;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = VK_CAPITAL;
|
||||
|
||||
// Send LWin+CapsLock keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// SendVirtualInput should be called exactly once with the above condition
|
||||
Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
|
||||
}
|
||||
|
||||
// Test if SendVirtualInput is sent exactly once with the suppress flag when shortcut containing Ctrl is remapped to shortcut Win+CapsLock and Ctrl is pressed again while shortcut remap is invoked
|
||||
TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenShortcutContainingCtrlIsMappedToWinCapsLockAndCtrlIsPressedWhileInvoked)
|
||||
{
|
||||
// Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
|
||||
mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
|
||||
if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
// Remap Ctrl+A to Win+CapsLock
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
Shortcut dest;
|
||||
dest.SetKey(CommonSharedConstants::VK_WIN_BOTH);
|
||||
dest.SetKey(VK_CAPITAL);
|
||||
testState.AddOSLevelShortcut(src, dest);
|
||||
|
||||
const int nInputs = 3;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = VK_CONTROL;
|
||||
|
||||
// Send LWin+CapsLock keydown followed by Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// SendVirtualInput should be called exactly once with the above condition
|
||||
Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
|
||||
}
|
||||
|
||||
// Test if SendVirtualInput is sent exactly once with the suppress flag when shortcut containing Ctrl is remapped to shortcut Win+CapsLock and Shift is pressed again while shortcut remap is invoked
|
||||
TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenShortcutContainingCtrlIsMappedToWinCapsLockAndShiftIsPressedWhileInvoked)
|
||||
{
|
||||
// Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
|
||||
mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
|
||||
if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
// Remap Ctrl+A to Win+CapsLock
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
Shortcut dest;
|
||||
dest.SetKey(CommonSharedConstants::VK_WIN_BOTH);
|
||||
dest.SetKey(VK_CAPITAL);
|
||||
testState.AddOSLevelShortcut(src, dest);
|
||||
|
||||
const int nInputs = 3;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = VK_SHIFT;
|
||||
|
||||
// Send LWin+CapsLock keydown followed by Ctrl
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// SendVirtualInput should be called exactly once with the above condition
|
||||
Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
|
||||
}
|
||||
|
||||
// Test that the shortcut remap state is not reset when an unrelated key up message is sent - required to handle programs sending dummy key up messages
|
||||
TEST_METHOD (ShortcutRemap_ShouldNotGetReset_OnSendingKeyUpForAKeyNotPresentInTheShortcutAfterInvokingTheShortcut)
|
||||
{
|
||||
// Remap Ctrl+A to Ctrl+V
|
||||
Shortcut src;
|
||||
src.SetKey(VK_CONTROL);
|
||||
src.SetKey(0x41);
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_CONTROL);
|
||||
dest.SetKey(0x56);
|
||||
testState.AddOSLevelShortcut(src, dest);
|
||||
|
||||
const int nInputs = 3;
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
input[1].type = INPUT_KEYBOARD;
|
||||
input[1].ki.wVk = 0x41;
|
||||
input[2].type = INPUT_KEYBOARD;
|
||||
input[2].ki.wVk = 0x42;
|
||||
input[2].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Send Ctrl+A keydown, then B key up
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, Ctrl, V should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
|
||||
|
||||
// Shortcut invoked state should be true
|
||||
Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "MockedInput.h"
|
||||
#include <keyboardmanager/common/KeyboardManagerState.h>
|
||||
#include <keyboardmanager/dll/KeyboardEventHandlers.h>
|
||||
#include <keyboardmanager/common/Helpers.h>
|
||||
#include "TestHelpers.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace RemappingLogicTests
|
||||
input[0].ki.wVk = 0x41;
|
||||
|
||||
// Send A keydown
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, and B key state should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
@@ -48,7 +48,7 @@ namespace RemappingLogicTests
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Send A keyup
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, and B key state should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
@@ -67,14 +67,14 @@ namespace RemappingLogicTests
|
||||
input[0].ki.wVk = 0x41;
|
||||
|
||||
// Send A keydown
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Send A keyup
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
@@ -92,7 +92,7 @@ namespace RemappingLogicTests
|
||||
input[0].ki.wVk = 0x41;
|
||||
|
||||
// Send A keydown
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, and common Win key state should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
@@ -100,7 +100,7 @@ namespace RemappingLogicTests
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Send A keyup
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, and common Win key state should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
@@ -108,7 +108,7 @@ namespace RemappingLogicTests
|
||||
}
|
||||
|
||||
// Test if SendVirtualInput is sent exactly once with the suppress flag when Caps Lock is remapped to Ctrl
|
||||
TEST_METHOD (HandleSingleKeyRemapEvent_ShouldSendVirutalInputWithSuppressFlagExactlyOnce_WhenCapsLockIsMappedToCtrlAltShift)
|
||||
TEST_METHOD (HandleSingleKeyRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenCapsLockIsMappedToCtrlAltShift)
|
||||
{
|
||||
// Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
|
||||
mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
|
||||
@@ -127,14 +127,14 @@ namespace RemappingLogicTests
|
||||
input[0].ki.wVk = VK_CAPITAL;
|
||||
|
||||
// Send Caps Lock keydown
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// SendVirtualInput should be called exactly once with the above condition
|
||||
Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
|
||||
}
|
||||
|
||||
// Test if SendVirtualInput is sent exactly once with the suppress flag when Ctrl is remapped to Caps Lock
|
||||
TEST_METHOD (HandleSingleKeyRemapEvent_ShouldSendVirutalInputWithSuppressFlagExactlyOnce_WhenCtrlAltShiftIsMappedToCapsLock)
|
||||
TEST_METHOD (HandleSingleKeyRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenCtrlAltShiftIsMappedToCapsLock)
|
||||
{
|
||||
// Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
|
||||
mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
|
||||
@@ -153,10 +153,166 @@ namespace RemappingLogicTests
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
|
||||
// Send Ctrl keydown
|
||||
mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT));
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// SendVirtualInput should be called exactly once with the above condition
|
||||
Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
|
||||
}
|
||||
|
||||
// Test if SendVirtualInput is sent exactly twice with the suppress flag when Caps Lock is remapped to shortcut with Ctrl and Shift
|
||||
TEST_METHOD (HandleSingleKeyRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyTwice_WhenCapsLockIsMappedToShortcutWithCtrlAltShift)
|
||||
{
|
||||
// Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
|
||||
mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
|
||||
if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
// Remap Caps Lock to Ctrl+Shift+V
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_CONTROL);
|
||||
dest.SetKey(VK_SHIFT);
|
||||
dest.SetKey(0x56);
|
||||
testState.AddSingleKeyRemap(VK_CAPITAL, dest);
|
||||
const int nInputs = 1;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CAPITAL;
|
||||
|
||||
// Send Caps Lock keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// SendVirtualInput should be called exactly twice with the above condition
|
||||
Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount());
|
||||
}
|
||||
|
||||
// Test if SendVirtualInput is sent exactly once with the suppress flag when Ctrl is remapped to a shortcut with Caps Lock
|
||||
TEST_METHOD (HandleSingleKeyRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenCtrlAltShiftIsMappedToShortcutWithCapsLock)
|
||||
{
|
||||
// Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
|
||||
mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
|
||||
if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
});
|
||||
|
||||
// Remap Ctrl to Ctrl+Caps Lock
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_CONTROL);
|
||||
dest.SetKey(VK_CAPITAL);
|
||||
testState.AddSingleKeyRemap(VK_CONTROL, dest);
|
||||
const int nInputs = 1;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_CONTROL;
|
||||
|
||||
// Send Ctrl keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// SendVirtualInput should be called exactly once with the above condition
|
||||
Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set for a single key to two key shortcut remap
|
||||
TEST_METHOD (RemappedKeyToTwoKeyShortcut_ShouldSetTargetKeyState_OnKeyEvent)
|
||||
{
|
||||
// Remap A to Ctrl+V
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_CONTROL);
|
||||
dest.SetKey(0x56);
|
||||
testState.AddSingleKeyRemap(0x41, dest);
|
||||
const int nInputs = 1;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
|
||||
// Send A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, and Ctrl, V key state should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Send A keyup
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, and Ctrl, V key state should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set for a single key to three key shortcut remap
|
||||
TEST_METHOD (RemappedKeyToThreeKeyShortcut_ShouldSetTargetKeyState_OnKeyEvent)
|
||||
{
|
||||
// Remap A to Ctrl+Shift+V
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_CONTROL);
|
||||
dest.SetKey(VK_SHIFT);
|
||||
dest.SetKey(0x56);
|
||||
testState.AddSingleKeyRemap(0x41, dest);
|
||||
const int nInputs = 1;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = 0x41;
|
||||
|
||||
// Send A keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, and Ctrl, Shift, V key state should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Send A keyup
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// A key state should be unchanged, and Ctrl, Shift, V key state should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
}
|
||||
|
||||
// Test if correct keyboard states are set for a remap from a single key to a shortcut containing the source key
|
||||
TEST_METHOD (RemappedKeyToShortcutContainingSourceKey_ShouldSetTargetKeyState_OnKeyEvent)
|
||||
{
|
||||
// Remap LCtrl to LCtrl+V
|
||||
Shortcut dest;
|
||||
dest.SetKey(VK_LCONTROL);
|
||||
dest.SetKey(0x56);
|
||||
testState.AddSingleKeyRemap(VK_LCONTROL, dest);
|
||||
const int nInputs = 1;
|
||||
|
||||
INPUT input[nInputs] = {};
|
||||
input[0].type = INPUT_KEYBOARD;
|
||||
input[0].ki.wVk = VK_LCONTROL;
|
||||
|
||||
// Send LCtrl keydown
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// LCtrl, V key state should be true
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LCONTROL), true);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
|
||||
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
|
||||
// Send LCtrl keyup
|
||||
mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT));
|
||||
|
||||
// LCtrl, V key state should be false
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LCONTROL), false);
|
||||
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user