简体   繁体   中英

Key input lags when using Windows API and WM_KEYDOWN C++

So I'm trying to make a program using Windows API (and DirectX9, if it matters) and am trying to use WM_KEYDOWN and WM_KEYUP to get input from the keyboard. This is the related part of my code right now. The idea is that the "keyTimes" array should store the number of frames that a key has been held down.

    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);


    Game* Game::s_instance = NULL;

    LPDIRECT3D9 d3dObject;
    LPDIRECT3DDEVICE9 d3dDevice;

    Game::Game(){
        for(int i=0; i<256; i++){
            keyTimes[i]=0;
        }

    }

    //....

    Game* Game::Instance(){
        if(Game::s_instance==NULL){
            s_instance = new Game();
        }
        return s_instance;
    }

    //Checks to see if key was pressed, and adds to value
    void Game::keyCheck(int keyNum, bool pressed){
        if(pressed){
            keyTimes[keyNum]++;
        }
        else{
            keyTimes[keyNum]=0;
        }

    }

    //Returns time that key has been pressed
    int Game::keyPressed(int keyNum){
            return keyTimes[keyNum];
    }

    //Returns true if key was hit once, and doesn't return true again until the key is let go and hit again.
    bool Game::keyHit(int keyNum){
        return keyTimes[keyNum]==1;
    }

    //Returns true only if the key has been held for delay
    bool Game::keyHeld(int keyNum, int delay){
        if(delay==0)
            delay=1;

        return keyTimes[keyNum]==delay;

    }

    //Returns true everyXFrame frames.
    bool Game::keyPressedDelay(int keyNum, int everyXFrame){
        if(everyXFrame<2){
            return false;
        }
        return keyTimes[keyNum]%everyXFrame==1;
    }


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){

    switch (message)
    {
            case WM_DESTROY:
                 PostQuitMessage(0);
            break;
            case WM_KEYDOWN:
                {
                    Game::Instance()->keyCheck(wParam,true);

                    return 0;   

                }
            break;
            case WM_KEYUP:
                {

                    Game::Instance()->keyCheck(wParam,false);
                    return 0;
                }
            break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;

}


    //........
    //Inside the main function while loop....


    if(Game::Instance()->keyHit(VK_LEFT)){
        thing->move(-3,0);
    }
    if(Game::Instance()->keyHit(VK_RIGHT)){
        thing->move(3,0);
    }
    if(Game::Instance()->keyHit(VK_UP)){
        thing->move(0,-3);
    }
    if(Game::Instance()->keyHit(VK_DOWN)){
        thing->move(0,3);
    }

    //.......

So when I try using the "KeyPressed" function as the boolean to move "thing" in the main function, it moves three pixels, stops for about half a second, and then starts moving again. It will also stop again if I try to hit another key while holding the first down. When I use "KeyHit" to move it, it goes about 9-12 pixels, then stops (rather than going only 3).

How would I change my code so that the functions work as commented, without any lag?

EDIT 3/26/12: I have managed to fix the code. It turns out that the problem was simply that I was using the GetMessage function in my main loop, which waits for input before moving, where I should have been using PeekMessage.

keyHit works only for the first 500 milliseconds because autorepeat kicks in and causes the hit count to go above 1.

Add some debug tracing to observe what messages you're receiving and what the value of keyTimes is each time you check it in your main game loop. That will probably identify the problem.

So when I try using the "KeyPressed" function as the boolean to move "thing" in the main function, it moves three pixels, stops for about half a second, and then starts moving again.

This is standard windows behaviour.

For example if you go to the Windows Control Panel and in the Keyboard properties set the Repeat Delay to short you will find that your delay times are now reduced.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM