Состояние чтения клавиатуры

Я пишу консольное приложение AC (для платформы Windows, с использованием компилятора msC++), которое требует чтения состояния некоторых клавиш на клавиатуре в очень короткие промежутки времени (порядка пары миллисекунд). Состояние чтения затем передается в FSM, который предоставляет события расширенного ключа (KEY_UP, KEY_RELEASED, KEY_DOWN, KEY_HELD_FOR_LONG_PERIOD и т. Д.) Для остальной части логики приложения. (в основном, перенос встроенного приложения на платформу Windows).

я не знаю, как читать ключевые состояния, поэтому я погуглил и наткнулся на этот ответ. Из того, что я понимаю, он в основном сканирует консольные события для любых событий клавиш (или мыши).

Хотя предоставленный ответ является хорошей отправной точкой, но проблема, с которой я сталкиваюсь, заключается в том, что между последовательными "чтениями" состояния клавиатуры (и когда временной интервал между последовательными чтениями составляет менее 50 мс), я получаю разные ответы (время от времени нажимается, в время отпущено), даже когда клавиша остается физически нажатой. Это портит логику FSM. Но это, вероятно, приемлемое поведение, учитывая, что консоль может не иметь новых событий клавиатуры за столь короткое время. К сожалению, это не решает мою проблему.

Так как я могу

  • Читать RAW состояние клавиш клавиатуры через какой-то API? (но это должно быть согласовано между последовательными чтениями в коротких временных рамках).
  • Или имейте.NET-эквивалент KEY_UP, KEY_DOWN рода событий (или сообщений, обратных вызовов, всего, что возможно в c), над которым я могу написать небольшую оболочку, чтобы мне не пришлось менять логику FSM.

У меня ограниченное понимание доступных окон API для решения поставленной задачи. я в основном парень из Embedded/C#, который либо работает голым металлом (при разработке прошивок), либо использует.net framework (при разработке для windows).

2 ответа

Решение

После предложения arx я оглянулся на API и события клавиатуры и понял, что это был мой план работы с событиями, который создавал мне проблему. Я опрашивал события, как будто они являются "сигналами" для текущего состояние ключей. Скорее события представляют "изменение" в сигнале.

Оригинальный дизайн был что-то вроде:

if ( there_is_an_event_for (KEY_A) )        // i assumed that events represents a key high state
    Update_fsm_for_KEY_A (with_high_signal);
else
    Update_fsm_for_KEY_A (with_low_signal);

Поскольку консоль получает события после нажатия клавиш key_pressed и key_released, этот дизайн был неуместным. Это новый дизайн:

static bool last_key_state = false;

if ( there_is_a_key_pressed_event_for (KEY_A) )
    last_key_state = true;
else if (there_is_a_key_released_event_for (KEY_B) )
    last_key_state = false;

Update_fsm_for_KEY_A (last_key_state)

Спасибо всем за ваши усилия и помощь. Я публикую и принимаю это как ответ. Кто знает, это может помочь кому-то, кто борется с той же проблемой.

Вы можете прочитать исходное состояние клавиатуры с помощью API-интерфейсов GetAsyncKeyState или GetKeyboardState.

Другие вопросы по тегам