Это, действительно, просто, если опрашиваются числовые или алфавитные клавиши без нажатий регистров 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). {493}
файл 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.
USES CRT
{$I clrkey.inc} { описание процедуры ClrKeyBuf }
VAR
с : Char;
BEGIN
...
Writeln('Выберите и нажмите клавишу [А], [Б] или [В]');
Рис. 21.4 {494}
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'] );
Можно, конечно, написать свою собственную функцию перевода в верхний регистр, работающую и с кириллицей, но эта функция {495} будет «от рождения» зависеть от типа кодировки кириллицы. А определить программно тип кодировки практически невозможно.