keyhook combinations with Alt Gr not working

89 Views Asked by At

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?

0

There are 0 best solutions below