Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
_N6_.doc
Скачиваний:
0
Добавлен:
24.04.2019
Размер:
166.91 Кб
Скачать

2.2 Распознавание нажатых клавиш

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

procedure TForml.EditlMouseDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

Параметр Sender, указывающий на источник события, уже обсуждался выше при описании событий мыши (см. раздел 1.2). Там же рассматривался и параметр Shift, представляющий собой множество элементов, отражающих нажатые в это время функциональные клавиши. Только в обработчике события OnKeyDown множество возможных элементов параметра Shift сокращено до ssShift (нажата клавиша Shift), ssAlt (нажата клавиша Alt) и ssCtrl (нажата клавиша Ctrl). Информация о нажатых кнопках мыши отсутствует.

Основной параметр, которого не было раньше — это параметр Key. Обратите внимание, что он определен как var, т.е. может изменяться в обработчике события. Кроме того, обратите внимание, что это целое число, а не символ.

Параметр Key определяет нажатую в момент события клавишу клавиатуры. Для не алфавитно-цифровых клавиш используются виртуальные коды API Windows. Ниже в таблице 5.4 приведены для дальнейшего обсуждения только несколько строк из нее, соответствующих наиболее распространенным клавишам.

Таблица 5.4. Некоторые коды клавиш

Клавиша

Десятичное число

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

Символическое имя

Сравнение по функции Ord

F1

112

$70

VK_F1

Enter

13

$OD

VK_RETURN

Shift

16

$10

VK_SHIFT

Ctrl

17

$11

VK_CONTROL

Alt

18

$12

VK_MENU

Esc

27

$1В

VK_ESCAPE

0,)

48

$30

ord('O')

1 !

49

$31

ord('l')

n,N,т,Т

78

$4Е

ord('N')

y,Y,H,H

89

$59

ord('Y')

Параметр Key является целым числом, определяющим клавишу, а не символ. Например, один и тот же код соответствует прописному и строчному символам «Y» и «у». Если, как это обычно бывает, в русской клавиатуре этой клавише соответст­вуют символы кириллицы «Н» и «н», то их код будет тем же самым. Различить прописные и строчные символы или символы латинские и кириллицы невозмож­но.

Проверять нажатую клавишу можно, сравнивая Key с целым десятичным ко­дом клавиши, приведенном во втором столбце таблицы 5.4. Например, реакцию на нажатие пользователем клавиши Enter можно оформить оператором:

if (Key = 13) then ... ;

Можно сравнивать Key и с шестнадцатеричным эквивалентом кода, приведен­ным в третьем столбце таблицы 5.4. Например, приведенный выше оператор мож­но записать в виде:

if (Key = $OD) then ... ;

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

if (Key = VK_RETURN) then ... ;

Для клавиш символов и цифр можно производить проверку сравнением с де­сятичным или шестнадцатеричным кодом, но это не очень удобно, так как труднс помнить коды различных символов. Другой путь — воспользоваться функцией ord, определяющей код символа. Коды латинских символов в верхнем регистре совпадают с виртуальными кодами, используемыми в параметре Key. Поэтому, на пример, если вы хотите распознать клавишу, соответствующую символу «Y», вы можете написать:

if (Key = ord('Y') then ... ;

В этом операторе можно использовать только латинские символы в верхнем регистре. Если вы напишете ord('y') или захотите написать русские символы, соот­ветствующие этой клавише — ord('H') или огд('н'), то оператор на сработает.

Помните также, что оператор будет действовать на все символы, относящиеся к указанной клавише: «Y», «у», «Н» и «н». Иногда это хорошо, а иногда плохо. Например, если вы задали пользователю какой-то вопрос, на который он должен ответить Y (да) или N (нет), то подобный оператор избавляет пользователя от необходимости следить, в каком регистре он вводит символ и какой язык — английский или русский включен в данный момент. Ему достаточно просто нажать клавишу, на которой написано «Y». Однако, если пользователь более привык к символам кириллицы, то могут возникнуть неприятности, поскольку нажимая клавишу с латинской буквой «Y» и русской буквой «Н» он может думать, что отвечает не положительно (Yes — да), а отрицательно (Нет).

Приведем еще один пример — автоматическую передачу фокуса очередному оконному компоненту при нажатии пользователем клавиши Enter. Это можно сделать, включив в общий обработчик событий OnKeyDown всех оконных компонен­тов оператор:

if (Key = VK_RETURN) then

FindNextControl(Sender as TWinControl,true,true, false) .SetFocus;

Этот оператор с помощью метода FindNextControl ищет очередной компонент в последовательности табуляции и передает ему фокус. Подробнее этот пример и метод FindNextControl рассмотрен в разделе 5.1.8.

В заключение приведем пример распознавания комбинации клавиш. Пусть вы хотите, например, распознать комбинацию Alt-X. Для этого вы можете написать оператор:

if((Key = ord('X'))and (ssAlt in Shift)) then ... ;

Мы рассмотрели распознавание клавиш при событии OnKeyDown. Заголовок обработчика события OnKeyUp имеет такой же вид, так что все сказанное в равной степени относится и к событиям при отпускании клавиш.

Теперь перейдем к рассмотрению события OnKeyPress. Заголовок обработчика этого события имеет вид':

procedure (Sender: TObject; var Key: Char);

В этот обработчик, как и в описанные выше, передается параметр Key, опреде­ляющий нажатую клавишу символа. Но обратите внимание, что тип этого пара­метра не целое число, как в предыдущих случаях, a Char — символ. В данном слу­чае в обработчик передается не виртуальный код клавиши, а символ, по которому можно определить, прописная это буква, или строчная, русская, или латинская. Поэтому описанных выше сложностей с распознаванием символов не возникает.

Пусть, например, вы задали пользователю вопрос, на который он должен ответить символами «Д» или «д» (да), или символами «Н» или «н» (нет). Тогда распо­знать положительный ответ в обработчике события OnKeyPress можно оператором:

if ((Key = 'Д') or (Key = 'д')) then ...

Этот оператор можно записать короче, воспользовавшись операцией in:

if (Key in ['Д', 'д']) then

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

case Key of

'Д','д':…;

'Н','н':…;

else

beep;

end;

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

Посмотрев на приведенный ранее заголовок обработчика, вы можете увидеть, что параметр Key передается как var. Это позволяет в обработчике изменять этот параметр, изменяя соответственно его стандартную обработку в компоненте, по­скольку ваш обработчик события срабатывает раньше стандартного обработчика компонента. Пусть, например, вы хотите иметь на форме окно редактирования Edit1, в котором пользователь должен вводить только целые числа без знака, разделенные запятыми или пробелами. Вы можете обеспечить безошибочный ввод, подменяя все недопустимые символы нулевым с помощью, например, такого опе­ратора:

if not (Key in ['0'..'9', ' ', ',']) then Key := #0;

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

if not (Key in ['О'..'9', ' ', ',']) then

begin

Key := #0;

Beep;

end;

11