I tried to make keyboard remapping using keyboard hook. It works fine with Shift, but it doesn't with Alt Gr - it's like it can't detect it pushed down while having multiple keys down or something. I was debbuging and it seems like clicked alone Alt Gr is being detected. Same with Alt and Ctrl combo.
The code I was using:
LRESULT CALLBACK KeyboardHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
KBDLLHOOKSTRUCT* kbStruct = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
WPARAM vkCode = kbStruct->vkCode;
// Check the AltGr key state using GetKeyState
bool altGrPressed = (GetKeyState(VK_RMENU) & 0x8000) != 0;
if (wParam == WM_KEYDOWN)
{
if (altGrPressed)
{
auto it = altGrRules.find(vkCode);
if (it != altGrRules.end())
{
// Get the remapped character
WCHAR character = it->second;
// Simulate the modified key press by sending a new key down message
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wVk = 0;
input.ki.wScan = character;
input.ki.dwFlags = kbStruct->flags | KEYEVENTF_UNICODE;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
SendInput(1, &input, sizeof(INPUT));
return 1; // Block the original key press
}
}
else
{
auto it = remappingRules.find(vkCode);
if (it != remappingRules.end())
{
// Get the remapped characters based on the Shift key status
bool shiftPressed = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
WCHAR character = shiftPressed ? it->second.second : it->second.first;
// Simulate the modified key press by sending a new key down message
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wVk = 0;
input.ki.wScan = character;
input.ki.dwFlags = kbStruct->flags | KEYEVENTF_UNICODE;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
SendInput(1, &input, sizeof(INPUT));
return 1; // Block the original key press
}
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
Can someone explain why and how to make it work?
update:
I tried the WM_SYSKEYDOWN
and WM_SYSKEYUP
solution:
if (wParam == WM_SYSKEYDOWN)
{
if (vkCode == VK_RMENU)
{
altGrPressed = true;
//return 1; // Block the original key press
}
}
if (wParam == WM_SYSKEYUP)
{
if (vkCode == VK_RMENU)
{
altGrPressed = false;
//return 2; // Block the original key press
}
}
and it's like it never catches keyup. Can someone explain why and how to fix it?