На этом шаге мы рассмотрим способы определения нажатых клавиш.
Заголовок обработчика события OnKeyDown может иметь, например,
следующий вид:
procedure TForm1.Edit1MouseDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Параметр Sender, указывающий на источник события, уже
рассматривался на шаге 6.
Там же рассматривался и параметр Shift,
представляющий собой множество
элементов, отражающих нажатые в это время функциональные клавиши. Только
в обработчике события
OnKeyDown множество возможных элементов параметра Shift
сокращено до:
- ssShift (нажата клавиша Shift),
- ssAlt (нажата клавиша Alt) и
- ssCtrl (нажата клавиша Ctrl).
Информация о нажатых кнопках мыши отсутствует.
Основной параметр, которого не было раньше - это параметр Key.
Обратите внимание,
что он определен как var, т.е. может изменяться в обработчике события.
Кроме того,
обратите внимание, что это целое число, а не символ.
Параметр Key определяет нажатую в момент события клавишу
клавиатуры. (Для не алфавитно-цифровых
клавиш используются виртуальные коды API Windows. Полная таблица
этих кодов приведена в
приложении 2. Ниже в таблице 1 приведены для
дальнейшего обсуждения только
несколько строк из нее, соответствующих наиболее распространенным
клавишам.
Таблица 1. Некоторые коды клавиш
Клавиша | Десятичное число | Шестнадцатеричное число | Символическое имя | Сравнение по функции ord |
---|---|---|---|---|
F1 | 112 | $70 | VK_F1 | |
Enter | 13 | $0D | VK_RETURN | |
Shift | 16 | $10 | VK_SHIFT | |
Ctrl | 17 | $11 | VK_CONTROL | |
Alt | 18 | $12 | VK_MENU | |
Esc | 27 | $1B | VK_ESCAPE | |
0,) | 48 | $30 | ord('0') | |
1,! | 49 | $31 | ord('1') | |
n,N,т,Т | 78 | $4E | ord('N') | |
y,Y,н,Н | 89 | $59 | ord('Y') |
Параметр Key является целым числом, определяющим клавишу, а
не символ.
Например, один и тот же код соответствует прописному и строчному символам
"Y" и "y".
Если, как это обычно бывает, в русской клавиатуре этой клавише соответвуют
символы кириллицы "Н" и "н",
то их код будет тем же самым. Различить прописные и строчные символы или
символы латинские и кириллицы
невозможно.
Проверять нажатую клавишу можно, сравнивая Key с целым
десятичными кодом клавиши, приведенном
во втором столбце таблицы 1. Например, реакцию на нажатие пользователем
клавиши Enter можно оформить оператором:
if (Key = 13) then ... ;
Можно сравнивать Key и с шестнадцатеричным эквивалентом кода,
приведенным в третьем
столбце таблицы 1. Например, приведенный выше оператор можно записать в
виде:
if (Key = $0D) then ... ;
Для клавиш, которым не соответствуют символы, введены также именованные
константы, которые облегчают
написание программы, поскольку не требуют помнить численные коды клавиш.
Например, приведенный выше
оператор можно записать в виде:
if (Key = VK_RETURN) then ... ;
Для клавиш символов и цифр можно производить проверку сравнением c
десятичным или шестнадцатеричным кодом,
но это не очень удобно, так как трудно помнить коды различных символов.
Другой путь - воспользоваться функций
ord, определяющей код символа. Коды латинских символов в верхнем
pегистре совпадают с виртуальными
кодами, используемыми в параметре Key. Поэтому, например, если вы
хотите распознать клавишу, соответствующую
символу "Y", можете написать:
if (Key = ord('Y')) then ... ;
В этом операторе можно использовать только латинские символы в верхнем
регистре. Если вы
напишете ord('y') или захотите написать русские символы,
соответствующие этой клавише -
ord('Н') или ord('н'), то оператор не сработает.
Помните также, что оператор будет действовать на все символы, относящиеся к
указанной клавише:
"Y", "у", "Н" и "н". Иногда это хорошо, а иногда плохо. Например, если вы задали
пользователю какой-то вопрос,
на который он должен ответить Y (да) или N (нет), то подобный
оператор избавляет пользователя от
необходимости следить, в каком регистре он вводит символ и какой язык -
английский или русский включен
в данный момент. Ему достаточно просто нажать клавишу, на которой написано
"Y". Однако, если
пользователь более привык к символам кириллицы, то могут возникнуть
неприятности, поскольку нажимая клавишу
с латинской буквой "Y" и русской буквой "Н" он может думать,
что отвечает не положительно
(Yes - да), а отрицательно (Нет).
Приведем еще один пример - автоматическую передачу фокуса
очередному оконному компоненту при нажатии пользователем
клавиши Enter. Это можно сделать, включив в общий обработчик
событий OnKeyDown всех оконных компонентов оператор:
if (Key = VK_RETURN) then FindNextControl (Sender As TWinControl, true, true, false).SetFocus;
Этот оператор с помощью метода FindNextControl ищет очередной
компонент в последовательности табуляции и
передает ему фокус.
В заключение приведем пример распознавания комбинации клавиш. Пусть вы
хотите, например, распознать
комбинацию Alt-X. Для этого вы можете написать оператор:
if ((Key = ord('X')) and (ssAlt in Shift)) then ... ;
Мы рассмотрели распознавание клавиш при событии OnKeyDown.
Заголовок обработчика события
OnKeyUp имеет такой же вид, так что все сказанное в равной степени
относится и к
событиям при отпускании клавиш.
На следующем шаге мы продолжим рассмотривать события, связанные с
клавиатурой. В
частности, поговорим о событии OnKeyPress.