Search code examples
c++macroshotkeys

why does the "If GetAsyncKeyState" sends Button infinitely?


I wanted to make a macro that sends space infinitely only if I press it, the problem is that it's sending it even after I left my finger of the button.

DWORD WINAPI BhopThread(LPVOID lp)
{
    while (true)
    {
        if (bhop)
        {
            if (GetAsyncKeyState(VK_SPACE))
                {
                Sleep(10);
                keybd_event(0x20, 0, 0, 0);
                Sleep(1);
                keybd_event(0x20, 0, KEYEVENTF_KEYUP, 0);
                Sleep(10);
                }
        }
    }
}

what did I wrong?


Solution

  • You have to check the most signifcant bit of the return value of the GetAsyncKeyState() function to determine if they key is currently pressed or not.

    GetAsyncKeyState() function

    If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior;

    Simply, it means that GetAsyncKeyState() returns not just true or false, but a wide range of values. To determine if the key really is currently held down, aka pressed, you need to use a bit-wise operator with the value 0x8000.

    Example to check if the Space key is currently held down:

    if(GetAsyncKeyState(VK_SPACE) & 0x8000)
    {
        // high bit is set.  Space is currently held down.
    } 
    

    What is a bit-wise operator?

    This is too broad to explain in this answer. I recommend you to have some basic C++ books/docs/tutorials to read.

    https://en.wikipedia.org/wiki/Bitwise_operation#AND