21.1. Как организовать опрос алфавитно-цифровой клавиатуры

Это, действительно, просто, если опрашиваются числовые или алфавитные клавиши без нажатий регистров Alt или Ctrl (регистр Shift при этом может быть нажат). Опишем для начала две вспомогательные процедуры, которые понадобятся в последующих примерах. Первая процедура «очищает» буфер клавиатуры (рис. 21.1).

файл CLRKEY.INC

| PROCEDURE ClrKeyBuf;

| VAR

| ch : Char;

| BEGIN

| while KeyPressed do ch:=ReadKey

| END;

Рис. 21.1

Вторая процедура, ожидающая нажатие клавиши, представлена на рис. 21.2.

После этого можно определить фрагмент, который принимает символ нажатой клавиши (рис. 21.3).

- 494 -

файл WAIT.INC

| PROCEDURE Wait;

| BEGIN

| repeat until KeyPressed

| END;

Рис. 21.2

| USES CRT;

| {$I clrkey.inc} { описание процедуры ClrKeyBuf }

| {$I wait.inc) { описание процедуры Wait }

| VAR

| с : Char;

| BEGIN

| ClrScr;

| WriteLn( 'Нажмите любую символьную клавишу' );

| ClrKeyBuf; { очистка буфера клавиатуры }

| с := ReadKey; { программа ждет нажатия клавиши }

| WriteLn( 'Была нажата клавиша с символом ', c );

| WriteLn;

| WritelLn('Программа держит паузу до первого',

| ' нажатия любой клавиши...' );

| Wait; { ожидание нажатия клавиши }

| ClrKeyBuf { мусор из буфера надо убрать }

| END.

Рис. 21.3

В рабочих программах часто надо ожидать нажатия конкретных клавиш, не реагируя на остальные. Такая задача решена в примере, показанном на рис. 21.4.

| CRT

| {$I clrkey.inc} { описание процедуры ClrKeyBuf }

| VAR

| с : Char;

| BEGIN

| ...

| Writeln('Выберите и нажмите клавишу [А], [Б] или [В]');

Рис. 21.4

- 495 -

| ClrKeyBuf;

| { очистка буфера }

| repeat

| c :=ReadKey

| until ( с in ['А'..'В','а'..'в'] );

| { Цикл разомкнется только, если будет нажат один }

| { из трех символов в любом регистре. }

| ClrKeyBuf; { очистка буфера }

| { Далее обрабатывается полученный символ: }

| case с of

| 'A','a' : begin реакция на символ 'a' end;

| 'Б','б' : begin реакция на символ 'б' end;

| 'В','в' : begin реакция на символ 'в' end

| end; {case}

| ClrKeyBuf;

| ...

| End.

Рис. 21.4 (окончание)

В этом примере для проверки принадлежности клавиши используется операция in — проверка наличия символа C в множестве [C1..Cn]. Это стандартный прием, и он весьма эффективен, так как синтаксис множества позволяет легко описывать диапазоны значений. Хотим предостеречь от возможных ошибок: при альтернативной кодировке кириллицы диапазон 'п'..'р' содержит в себе почти всю псевдографику (чего нет при «болгарской» кодировке). Это не очень страшно, так как псевдографика не привязана к клавишам, но лучше не давать повод для возможных «капризов» программ. Обращаем также внимание читателя на то, что и во множестве, и в операторе CASE проверка происходит и по верхнему, и по нижнему регистру написания символа, так как неизвестно, какой из них был включен в момент нажатия. Так всегда следует делать при опросе в режиме кириллицы. При опросе латинских символов достаточно вставить один дополнительный оператор и ограничиться анализом одних лишь заглавных букв, например:

repeat

с := ReadKey;

{ Перевод в верхний режим: только для латинского алфавита}

с := UpCase( с )

until ( с in ['Q'..'V'] );

Можно, конечно, написать свою собственную функцию перевода в верхний регистр, работающую и с кириллицей, но эта функция

- 496 -

будет «от рождения» зависеть от типа кодировки кириллицы. А определить программно тип кодировки практически невозможно.