Drake
Drake

Reputation: 3891

C# hotkeys incorrect letters

I used SetWindowHook to set a low level keyboark hook for instant global hotkeys. But when I try to use hotkeys for letters such as ';'[],/', it returns incorrect/high value letters. Like when I press comma, it gives me a 1/4th sign.

Here is the callback

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    char letter;

    if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
    {
        int vkCode = Marshal.ReadInt32(lParam);

        letter = (char)vkCode;

        // converts letters to capitals
        if (char.IsLetter(letter) == true)
        {
            if ((((ushort)GetKeyState(0x14)) & 0xffff) != 0)
            {
                letter = char.ToUpper(letter);

                if (GetAsyncKeyState(((int)VirtualKeys.Shift)) != 0)
                letter = char.ToLower(letter);
            }
            else if (GetAsyncKeyState(((int)VirtualKeys.Shift)) != 0)
            {
                letter = char.ToUpper(letter);
            }
            else
            {
                letter = char.ToLower(letter);
            }
        }

        logs.Add(letter);
    }

    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

How can I get punctuation hotkeys without manually comparing every single wrong value?

Upvotes: 1

Views: 252

Answers (2)

CodesInChaos
CodesInChaos

Reputation: 108810

The first problem is that you're using a keyboard hook to get hotkeys when there is a perfectly fine RegisterHotkey function.

Then there is the misunderstanding that a key and a character are the same thing. Hotkeys are based on virtual keys, check the Keys enum for the virtual key values in C#. There is no 1 to 1 mapping between keys and characters. Many keyboard layouts don't have [ key. For example on a German keyboard [ is altgr+8

Upvotes: 2

SLaks
SLaks

Reputation: 887547

You need to read the scanCode rather than the vkCode from the KBDLLHOOKSTRUCT structure pointed to by lParam.

You need to create a managed struct equivalent to KBDLLHOOKSTRUCT, then change your callback to take a ref copy of the struct.

Upvotes: 1

Related Questions