Шаг 8.
Распознавание нажатых клавиш. Событие OnKeyDown

    На этом шаге мы рассмотрим способы определения нажатых клавиш.

    Заголовок обработчика события OnKeyDown может иметь, например, следующий вид:

  procedure TForm1.Edit1MouseDown(Sender:  TObject;  
                                     var Key: Word; Shift: TShiftState);

    Параметр Sender, указывающий на источник события, уже рассматривался на шаге 6. Там же рассматривался и параметр Shift, представляющий собой множество элементов, отражающих нажатые в это время функциональные клавиши. Только в обработчике события OnKeyDown множество возможных элементов параметра Shift сокращено до:

Информация о нажатых кнопках мыши отсутствует.

    Основной параметр, которого не было раньше - это параметр 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.




Предыдущий шаг Содержание Следующий шаг