Search code examples
c#.netkey

Why does GetAsyncKeyState registers CTRL when pressing ALT


I am currently using GetAsyncKeyState to register key presses in a csharp program.

The issue I'm running into is that when pressing right Alt (RMenu / vKey 165), the program also registers a right Control press (RControlKey / vKey 162).

I'm running a for loop to check every vKey integer of the method like this :

for (int i = 0; i < 254; i++)
{
    short keyState = GetAsyncKeyState(i);
    if(keyState < 0)
    {
        Debug.WriteLine(i);
    }
}

I tried filtering the RControl key out, however I'd like to also detect this one.

Am I missing something and is there a way to work around it ?


Solution

  • I think the issue is how you are checking if the key is pressed.

    According to the documentation, you should compare the most significant bit. Try this instead:

    Import the function in this manner:

    [DllImport("User32.dll")]
    public static extern short GetAsyncKeyState(Keys ArrowKeys);
    

    Then you use a binary AND operator to check if the most significant digit is set on the value returned by the imported function:

    for (int i = 0; i < 254; i++)
    {
        var key = (Keys)i;
        bool isKeyDown = (GetAsyncKeyState(key) & 0x8000) > 0; 
        if (isKeyDown)
        {
            Console.WriteLine($"{i} => {key}");
        }
    }
    

    The output, when the right alt key is pressed:

    18 => Menu 
    165 => RMenu 
    

    You see both because from the list of keys, 18 indicates "The ALT key" and 165 is a more specific value that indicates "The right ALT key."

    Similarly, pressing the right control key produces this output:

    17 => ControlKey
    163 => RControlKey