Задержка ввода с клавиатуры при удерживании?

Кто-нибудь знает, почему есть некоторые колебания, когда вы удерживаете клавишу клавиатуры и пытаетесь ее обработать? Я вызываю функцию прямо в WinProc(...), которая будет перемещать изображение на экране (OpenGL) при удерживании клавиши. Я нажимаю ее и получаю один ответ, затем около 0,5 секунд ничего, затем она ведет себя как обычно (перемещается на 1 пиксель в каждом цикле WinMain).

Мне интересно, задерживаются ли сообщения Windows как-то из-за какой-то функции, которую мне нужно отключить???

Вот мой код:

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;
}

и WinProc (было больше случаев, но то же самое...):

    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;
}
}

и key_RIGHT:

void key_RIGHT()
{
    MoveObjectRight1Pixel();
}

person Tony R    schedule 07.04.2009    source источник


Ответы (2)


Это довольно стандартная настройка клавиатуры, заключающаяся в небольшой задержке между нажатием клавиши и созданием повторных сообщений.

Вместо обработки ввода с клавиатуры в обработчике сообщений Windows вы можете сохранить массив из 256 бит, указывающий текущее состояние клавиатуры. Когда вы получаете WM_KEYDOWN или WM_KEYUP, вы обновляете бит соответствующего ключа. Затем в основном цикле вы проверяете текущее состояние ключа и предыдущее состояние ключа (сохраняя второй массив из 256 бит, который вы копируете в каждый кадр).

Если клавиша в настоящее время нажата, но не была нажата в предыдущем кадре, вы соответственно перемещаете свой объект.

Другой альтернативой является использование функции GetAsyncKeyState().

person Adam Rosenfield    schedule 07.04.2009
comment
Я боялся, что мне придется придумывать какой-нибудь глупый обходной путь... Нет никакого способа заставить Windows отправлять мне сообщения с цивилизованной скоростью? - person Tony R; 07.04.2009
comment
Это огромная клавиатура. :) Большинство стандартных клавиатур ПК имеют около 105 клавиш, так что 128 бит звучит для меня достаточно. - person unwind; 07.04.2009
comment
@unwind: Да, большинство клавиатур имеют нормальное количество клавиш, но виртуальные коды клавиш (константы VK_*) варьируются от 0 до 255. - person Adam Rosenfield; 07.04.2009

Ну, я думаю, вы имеете дело со стандартной функцией Windows. Windows обычно имеет задержку перед запуском повторяющихся событий нажатия клавиш, когда клавиша подавлена.

Я не знаю о других методах, но при первом нажатии клавиши вы можете активировать таймер, который будет проверять, подавляется ли клавиша каждые несколько миллисекунд, а затем соответствующим образом обрабатывать ваш код.

Думаю, это решит вашу проблему.

person Cyril Gupta    schedule 07.04.2009