Keyboard input hesitation when held down?

2019-08-02 12:04发布

问题:

Does anyone know why there is some hesitation when you hold down a keyboard key and try to process it? I'm calling a function right in my WinProc(...) that will move an image on the screen (OpenGL) when a key is held down. I press it and get a single response, then there is about .5 seconds of nothing, then it behaves as normal (moves 1 pixel every WinMain loop).

I'm wondering if the Windows messages are being delayed somehow because of some feature I need to disable???

Here's my code:

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int nshowcmd)
{
    bool quit = false;
    MSG msg;

    createWindow(hinstance, SCRW, SCRH, SCRD, WINDOWED);

    // Main loop
    while (!quit)
    {       
        if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                quit = true;

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        renderFrame();        // processes graphics
        SwapBuffers(hdc);
    }
    return msg.lParam;
}

and WinProc (there were more cases but same thing...):

    LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    {
        switch(msg)
        {
            case WM_KEYDOWN:
                switch ( wparam )
                {
                    case VK_RIGHT:
                        key_RIGHT();
                        return 0;
                }
                return 0;
}
}

and key_RIGHT:

void key_RIGHT()
{
    MoveObjectRight1Pixel();
}

回答1:

It's a rather standard keyboard setting to have a small delay between when the key was pressed and when repeat messages get generated.

Instead of processing keyboard input in your Windows message handler, you could instead keep an array of 256 bits indicating the current state of the keyboard. When you receive a WM_KEYDOWN or WM_KEYUP, you update the bit of the corresponding key. Then, in your main loop, you check the current state of the key and the previous state of the key (by keeping a second array of 256 bits that you make a copy to every frame).

If the key is currently down but was not down in the previous frame, then you move your object accordingly.

Another alternative is to use the GetAsyncKeyState() function.



回答2:

Well, I think you're dealing with a standard windows feature here. Windows usually has a delay before it fires the repititive keystrokes events when thekey is suppressed.

I don't know about other methods, but on the first key press you could activate a timer which would check whether the key is suppressed every few milliseconds and then process your code accordingly.

I think that would solve the problem you're having.