Главная » Win32 API » Сообщения от клавиатуры

0

При нажатии и отпускании клавиш драйвер клавиатуры формирует сообщения и передает их в системную очередь сообщений. Затем со­общения от клавиатуры поступают в очередь сообщений приложения-владельца окна, имеющего фокус ввода (input focus).

Понятие фокуса ввода связано с активным окном. Окно, имеющее фокус ввода это либо активное окно, либо дочернее окно активного окна. Окно является активным, если у него вьщелен заголовок, или рамка диалога, или текст заголовка в панели задач для минимизиро­ванного окна. Часто дочерними окнами для окна являются кнопки, пе­реключатели и другие элементы управления, причем сами дочерние окна никогда не могут быть активными. Если фокус ввода находится в дочернем окне, то активным является родительское окно этого дочер­него окна. То, что фокус ввода находится в дочернем окне, обычно по­казывается посредством мигающего курсора (для полей редактирова­ния), рамки вокруг надписи на кнопке (для кнопок) или другими при­влекающими внимание пользователя средствами. Если активное окно минимизировано, то окна с фокусом ввода нет.

Узнать о получении или потере фокуса ввода окном можно по ин­формирующим сообщениям WMSETFOCUS и WMKILLFOCUS. Сообщение WMSETFOCUS показывает, что окно получило фокус ввода, a WMKILLFOCUS что окно потеряло его. Определить или изменить окно, владеющее фокусом ввода, возможно с помощью функций GetFocus и SetFocus.

Типы сообщений, генерируемых драйвером клавиатуры, делятся на аппаратные и символьные. Аппаратные сообщения связаны с нажа­тием и отпусканием клавиш. Каждой клавише на клавиатуре соответ­ствуют два уникальных числа называемых скан-кодом нажатия и скан-кодом отпускания клавиши. Скан-код {scan code) является аппа-ратно-зависимым, то есть на клавиатурах разных производителей одна и та же клавиша может иметь разные скан-коды. Когда пользователь нажимает или отпускает клавишу, драйвер клавиатуры считывает из порта 60h соответствующий скан-код, который преобразуется драйве­ром в виртуальный код клавиши {virtual-key code). Этот код является уже аппаратно-независимым, поэтому в Windows он однозначно иден­тифицирует нажатую или отпущенную клавишу. Завершающим дейст­вием драйвера является создание сообщения, содержащего скан-код, виртуальный код клавиши и другую информацию о нажа­той/отпущенной клавише. Это аппаратное сообщение помещается в системную очередь сообщений. Далее Windows извлекает сообщение из системной очереди и передает его в очередь сообщений того пото­ка, который является владельцем активного окна.

Виртуальные коды клавиш (virtual key code) определены в файле winuser.h и приведены в таблице 1.1.

Аппаратные сообщения бывают системные и несистемные. Несис­темные аппаратные сообщения это сообщения нажатия клавиши WMKEYDOWN и ее отпускания WMKEYUP. Если нажатие и от­пускание клавиши необходимо Windows для своей обработки, то гене­рируются системные аппаратные сообщения WMSYSKEYDOWN и WMSYSKEYUP.

Эти сообщения обычно вырабатываются при нажатии клавиш в со­четании с клавишей <Alt> и служат для работы с меню или для сис­темных функций, таких, например, как смена активного приложения (<Alt+Tab>).

Приложения обычно игнорируют сообщения WMSYSKEYDOWN и WMSYSKEYUP и передают их в функцию DefWindowProc, a оконная функция получает другие сообщения, являющиеся результа­том обработки этих аппаратных сообщений клавиатуры (например, WMCOMMAND выбор пункта меню).

Если в программе необходимо обрабатывать системные сообщения, то после их обработки следует вызвать DefWindowProc, чтобы Windows могла по-прежнему их использовать

Несистемные сообщения WMKEYDOWN и WMKEYUP обычно вырабатываются для клавиш, которые нажимаются и отпускаются без участия клавиши <Alt>. Приложение может использовать или не использовать эти сообщения клавиатуры. Сама Windows их проигнори­рует.

Таблица 1.1

Шестнадцатеричное

значение

Идентификатор

Клавиатура IBM

03

VK CANCEL

Ctrl + Break

08

VK BACK

Backspace

09

VK TAB

Tfab

0D

VK RETURN

Enter

10

VK SHIFT

Shift

11

VK CONTROL

Ctrl

12

VK MENU

Alt

13

VK PAUSE

Pause

14

VK CAPITAL

Caps Lock

VK ESCAPE

Esc

20

VK SPACE

Пробел

21

VK PRIOR

Page Up

22

VK NEXT

Page Down

23

VK END

End

24

VK HOME

Home

25

VK LEFT

Стрелка влево

26

VK UP

Стрелка вверх

27

VK RIGHT

Стрелка вправо

28

VK DOWN

Стрелка вниз

VK SNAPSHOT

Print Screen

2D

VK INSERT

Insert

VK DELETE

Delete

30…39

0…9 (на основной клавиатуре)

41…5А

A..Z

70…7В

VK F1…VK F12

F1…F12

90

VK NUMLOCK

Num Lock

91

VK SCROLL

Scroll Lock

Обычно сообщения о нажатии и отпускании появляются парами. Однако если пользователь оставит клавишу нажатой так, чтобы вклю­чился автоповтор, то Windows посылает оконной процедуре серию со­общений WMKEYDOWN (или WMSYSKEYDOWN) и одно сообщение WMKEYUP (или WMSYSKEYUP), когда, в конце концов, клавиша будет отпущена. Приложение с помощью функции GetMessageTime может узнать время нажатия и отпускания клавиши относительно старта системы.

Для всех аппаратных сообщений клавиатуры 32-разрядная пере­менная lParam, передаваемая в оконную процедуру, состоит из шести полей:

-  счетчика повторений (число нажатий клавиши);

-  скан-кода OEM (Original Equipment Manufacturer);

-  флага расширенной клавиатуры (1, если сообщение клавиатуры появилось в результате работы с дополнительными клавишами расши­ренной клавиатуры IBM);

-  кода контекста (1, если нажата клавиша <Alt>);

-  флага предыдущего состояния клавиши (0, если в предыдущем состоянии клавиша была отпущена, и 1, если в предыдущем состоянии она была нажата),

-  флага состояния клавиши (0, если клавиша нажимается, и 1, если клавиша отпускается).

Гораздо более важным параметром аппаратных сообщений клавиа­туры, по сравнению с lParam, является параметр wParam. В этом па­раметре содержится виртуальный код клавиши, использующийся при­ложением для идентификации клавиши.

Параметры wParam и lParam аппаратных сообщений клавиатуры ничего не сообщают о состоянии так называемых клавиш сдвига (<Shift>, <Ctrl>, <Alt>) и клавиш-переключателей (<CapsLock>, <NumLock>, <ScrollLock>).

Приложение может получить текущее состояние (нажата или нет) любой виртуальной клавиши с помощью функций GetKeyState и GetAsyncKeyState.

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

Если действительно нужна информация о текущем положении кла­виши, то можно использовать функцию GetAsyncKeyState.

Так как при обработке событий клавиатуры необходимо формиро­вать символы, соответствующие нажатой клавише, то драйвер клавиа­туры помимо аппаратных формирует символьные сообщения. Любая клавиша, например, <S>, в зависимости от состояния клавиш <Ctrl>, <Shift> и <CapsLock>, может использоваться для генерации разных символов строчного ‘s’ или прописного ‘S’. Приложению посылают­ся оба аппаратных и символьное сообщение WMCHAR.

Самостоятельное преобразования аппаратных сообщений клавиа­туры в символьные сообщения в приложении не рекомендуется, так как необходимо знать об особенностях реализации каждой отдельной национальной клавиатуры. Это преобразование предлагается сделать самой Windows с помощью функции TranslateMessage в цикле обра­ботки сообщений:

while(GetMessage(&mess,NULL,0,0))

{

TranslateMessage(&mess);

DispatchMessage(&mess); }

Функция GetMessage заполняет поля структуры mess данными следующего сообщения из очереди. Вызов DispatchMessage организу­ет передачу управления оконной функции. Между двумя этими функ­циями находится вызов функции TranslateMessage, которая преобра­зует аппаратные сообщения в символьные. Если этим сообщением яв­ляется WMKEYDOWN (WMSYSKEYDOWN) и, если нажатие кла­виши в сочетании с положением клавиши сдвига генерирует символ, тогда TranslateMessage помещает символьное сообщение в очередь сообщений.

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

Так же, как и для аппаратных сообщений, символьные сообщения бывают несистемные WMCHAR, WMDEADCHAR и системные -WMSYSCHAR, WMSYSDEADCHAR.

Сообщения WMSYSCHAR и WMSYSDEADCHAR являются следствием сообщений WMSYSKEYDOWN. В большинстве случаев можно обрабатывать только WMCHAR.

Параметр lParam для WMCHAR совпадает с lParam аппаратного сообщения клавиатуры, из которого сгенерировано символьное сооб­щение. Параметр wParam это код символа ASCII.

Сообщения WMDEADCHAR и WMSYSDEADCHAR генериру­ются для неамериканских клавиатур с диакритическими знаками для

букв. Эти знаки называются немыми клавишами (dead keys), поскольку сами по себе клавиши с диакритическими знаками не определяют сим­вол.

Рассмотрим, с какими наборами символов работает система Windows. Для обеспечения возможности работы с символами кирил­лицы фирма Microsoft разработала расширенный набор символов с ки­риллицей набор символов OEM (Original Equipment Manufacturer). Сама же Windows для представления символов использует набор сим­волов ANSI. В этом наборе определены не все коды и отсутствуют символы псевдографики.

По умолчанию для отображения символов выбирается системный шрифт, для которого используется набор символов ANSI.

Источник: Сучкова, Л.И. Win32 API: основы программирования: учебное пособие/ Л.И. Сучкова; АлтГТУ им. ИИ. Ползунова. -Барнаул, АлтГТУ, 2010. 138 с, ил.

По теме:

  • Комментарии