На этом шаге мы рассмотрим способы определения нажатых клавиш.
Заголовок обработчика события OnKeyDown может иметь, например, следующий вид:
procedure TForm1.Edit1MouseDown(Sender: TObject; var Key: Word; Shift: TShiftState);
Параметр Sender, указывающий на источник события, уже рассматривался на шаге 6. Там же рассматривался и параметр Shift, представляющий собой множество элементов, отражающих нажатые в это время функциональные клавиши. Только в обработчике события OnKeyDown множество возможных элементов параметра Shift сокращено до:
Основной параметр, которого не было раньше - это параметр Key. Обратите внимание, что он определен как var, т.е. может изменяться в обработчике события. Кроме того, обратите внимание, что это целое число, а не символ.
Параметр Key определяет нажатую в момент события клавишу клавиатуры. (Для не алфавитно-цифровых клавиш используются виртуальные коды API Windows. Полная таблица этих кодов приведена в приложении 2. Ниже в таблице 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 ... ;
На следующем шаге мы продолжим рассмотривать события, связанные с клавиатурой. В частности, поговорим о событии OnKeyPress.