Получение времени нажатия клавиши и состояния управляющих клавиш.
Лекция 5
Клавиатура
Общие сведения
Приложения Windows обязаны поддерживать пользовательский ввод с клавиатуры, так как данный вид ввода информации является основным (совместно с мышью). Windows полностью поддерживает для клавиатуры идеологию сообщений, то есть любая программа узнает о нажатии той или иной клавиши посредством сообщений, которые посылаются оконной процедуре.
Сообщение от клавиатуры проходит две очереди прежде, чем попадет в вашу программу – системную очередь сообщений и очередь сообщений приложения. Из системной очереди Windows выбирает сообщения, предназначенные исключительно ей (например, что нажата перегрузка машины <Ctrl+Alt+Del> или переключение между приложениями <Alt+Tab>). Таким образом, программа получает только адресованные ей сообщения от клавиатуры.
Возникает вопрос: Windows – многозадачное приложение и одновременно в системе могут работать несколько программ и, соответственно, открыты несколько окон, - какое же из окон будет получать сообщения от клавиатуры? Ответ – окно, которое имеет фокус ввода (“input focus”). Концепция фокуса ввода тесно связана с концепцией активного окна. Активное окно – это окно, имеющее фокус ввода, либо имеющее дочернее окно, которое имеет фокус ввода. Только одно окно в данный момент времени может быть активным. В этом случае, фокус ввода принадлежит либо данному окну, либо одному из дочерних окон активного окна (если они существуют).
Когда любое окно получает от системы сообщение WM_SETFOCUS, это означает, что окно получает фокус ввода. Теперь все сообщения от клавиатуры будут посылаться в данное окно. Окно теряет фокус ввода, когда его оконная процедура получает сообщение WM_KILLFOCUS.
Вашей программе не нежно реагировать на все сообщения от клавиатуры, так как операционная система сама обрабатывает многие клавиатурные сообщения (например, начинающиеся с префикса <Alt+ >). Эти сообщения будут обработаны Windows и ваша программа получит сообщение, являющееся обработкой системного сообщения (например, сообщит вам, что окно закрывается, либо окно теряет фокус ввода).
Аппаратные сообщения.
Сообщения, которые приложение (ваша программа) получает от клавиатуры, различаются на аппаратные (keystrokes) и символьные(characters). Любое нажатие на клавиатуре генерирует аппаратное сообщение. Нажатие клавиши с каким-либо символом (буквой, цифрой, значком) должно привести к тому, что Windows, кроме аппаратного сообщения, пошлет в вашу программу символьное сообщение. Как это происходит, мы рассмотрим позже, а сейчас подробно рассмотрим аппаратные сообщения.
Операционная система выделяет в потоке аппаратных сообщений системные и несистемные сообщения. Системные сообщения обычно вырабатываются при нажатии клавиш в сочетании с клавишей <Alt>. Эти сообщения вызывают опции меню программы или системного меню (<Alt+функциональная клавиша>, <Alt+Esc>), или используются для системных функций, таких как смена активного окна (<Alt+Tab>). Обычно программа игнорирует системные сообщения, однако иногда возникает необходимость в их обработке.
Типы сообщений, поступающих в приложение от клавиатуры приведены в следующей таблице:
Типы сообщений
| Клавиша нажата
| Клавиша отпущена
| Несистемные аппаратные сообщения
| WM_KEYDOWN
| WM_KEYUP
| Системные аппаратные сообщения
| WM_SYSKEYDOWN
| WM_SYSKEYUP
| Обычно сообщения о нажатии и отпускании клавиши появляются парами. Исключение составляет тот случай, когда пользователь не отпускает клавишу и включается автоповтор. В последнем случае в программу направляется поток сообщений о нажатии клавиши.
Одновременно с одним из аппаратных сообщений приходят два параметра сообщения: lParam и wParam. Переменная lParam состоит из 6 полей:
Код контекста
Зарезервировано Скан - код Счетчик повторений
Флаги состояния клавиши Флаг расширенной клавиатуры
Счетчик повторений. Равен числу нажатий клавиши, которое отражено в сообщении. В случае, когда его значение отлично от 1 (больше одного нажатия), это обычно означает, что программа не успевает обработать сообщения в реальном времени, либо система загружена в данный момент какой-либо работой. Ваша программа может как игнорировать число нажатий (реагировать только на сам факт нажатия), либо обрабатывать все нажатий клавиши клавиатуры.
Скан-код. Является кодом клавиатуры, генерируемым аппаратурой, то есть является тем кодом, который непосредственно приходит от клавиатуры. Обычно игнорируется приложением.
Флаг расширенной клавиатуры. Устанавливается в 1, если сообщение пришло от дополнительной клавиатуры (клавиши управления курсором, цифровая клавиатура и др.)
Код контекста. Код контекста устанавливается в 1, если нажата клавиша <Alt>. Часто, при помощи этого бита можно выделить системные сообщения.
Флаг предыдущего состояния клавиши. Равен 0, если в предыдущем состоянии клавиша была отпущена, и 1, если в предыдущем состоянии она была нажата.
Флаг состояния клавиши. Равен 0, если клавиши нажимается, и 1, если клавиша отпускается.
Второй параметр wParam содержит виртуальный код клавиши (virtual key code), идентифицирующий нажатую и отпущенную клавишу, чем реализуется аппаратная независимость программного представления клавиатуры. Виртуальные коды клавиш, которые вы используете, имеют имена, определенные в заголовочных файлах Windows. Вот несколько примеров виртуальных кодов:
Нажатая клавиша
| Идентификатор, определенный в windows.h
| Десятичный код
| Ctrl-Break
| VK_CANCEL
|
| Tab (табуляция)
| VK_TAB
|
| Shift
| VK_SHIFT
|
| Enter
| VK_ENTER
|
| Ctrl
| VK_CONTROL
|
| Alt
| VK_MENU
|
| Esc
| VK_ESCAPE
|
| Пробел
| VK_SPACE
|
| Стрелка влево
| VK_LEFT
|
| Стрелка вправо
| VK_RIGHT
|
| Стрелка вниз
| VK_DOWN
|
| Стрелка вверх
| VK_UP
|
| Delete
| VK_DELETE
|
| End
| VK_END
|
| Home
| VK_HOME
|
| Page Up
| VK_PRIOR
|
| Page Down
| VK_NEXT
|
| F1
| VK_F1
|
|
Получение времени нажатия клавиши и состояния управляющих клавиш.
Вы всегда можете узнать время, когда возникло сообщение от клавиатуры при помощи функции GetMessageTime. Время определяется в единицах, отсчитанных от момента старта системы.
Существует ряд управляющих клавиш, от состояния которых зависит реакция системы (и программ) на нажатие остальных клавиш. К таким клавишам относятся: (<Shift>, <Ctrl>, <Alt>, <CapsLock>, <NumLock>, <ScrollLock>). Программа может получить их состояния с помощью функции GetKeyState. Например, для получения состояния SHIFT необходимо выполнить:
GetKeyState(VK_SHIFT);
где в качестве параметра выступает виртуальный код нужной управляющей клавиши.
Следует отметить, что функция GetKeyState выдает состояние клавиши на тот момент, когда программой было выбрано из очереди последнее сообщение от клавиатуры. Это может пригодится, если ваша программа не успевает обработать все сообщения от клавиатуры. Реальное положение клавиш в данный момент времени позволяет выяснить функция GetAsyncKeyState.
Символьные сообщения.
Ранее уже говорилось, что знания о виртуальном коде и положениях управляющих клавиш недостаточно для определения нажатого символа. Операционная система позволяет поддерживать большое число национальных клавиатур, алфавит которых может значительно отличаться друг от друга. В связи с этим, нажатие одной и той же клавиши может означать нажатие разных символов, определяемых выбранным в данный момент драйвером клавиатуры. Например, нажатие клавиши с буквой “V”, при выбранном драйвере русской или украинской клавиатуры, будет означать нажатие символа “М”.
Данное преобразование выполняет функция TranslateMessage, которая преобразует аппаратные сообщения в символьные, используя при этом состояние управляющих клавиш и драйвер клавиатуры. Обычно это происходит в цикле обработки сообщений:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Функция TranslateMessage является своеобразным диспетчером сообщений. Если очередное сообщение, выбранное функцией GetMessage из очереди сообщений, является символьным, то TranslateMessage ставит в очередь сообщений к приложению еще одно сообщение – символьное. При этом, аппаратное сообщение продолжает свой путь в цикле обработки сообщений и попадает в оконную процедуру окна приложения через функцию DispatchMessage.
Аналогично аппаратным сообщениям, существует четыре символьных сообщения:
Типы сообщений
| Клавиша нажата
| Клавиша отпущена
| Несистемные символьные сообщения
| WM_CHAR
| WM_DEADCHAR
| Системные символьные сообщения
| WM_SYSCHAR
| WM_DEADCHAR
| Сообщения WM_CHAR являются следствием сообщений WM_KEYDOWN. В большинстве приложений предпочтительным является использование именно символьных сообщений. Параметр lParam, в случае сообщения WM_CHAR, является таким же, как и соответствующий параметр в аппаратном сообщении, а wParam – определяет код символа ASCII.
В качестве примера рассмотрим случай, когда пользователь программы нажимает и отпускает клавишу "А". Если переключатель <CapsLock> не включен и не нажата клавиша <Shift>, то оконная процедура получит три следующих сообщения:
Не нашли, что искали? Воспользуйтесь поиском по сайту:
©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.
|