Справочник программиста на персональном компьютере фирмы IBM. Клавиатура - Ожидать ввод символа и не выводить его на экран
ОГЛАВЛЕНИЕ
3.1.3 Ожидать ввод символа и не выводить его на экран.
Обычно вводимые символы выводятся на экран, чтобы было видно,
что напечатано. Но иногда автоматическое эхо на экране нежела-
тельно. Например, выбор пункта меню по нажатию клавиши. Иногда
надо сначала проверить вводимые символы на ошибку перед выводом
на экран. В частности, любая программа, обрабатывающая расширен-
ные коды, должна избегать автоматического эха, так как при этом
первый байт этих кодов (ASCII 0) будет выводиться на экран,
вставляя пробелы между символами.
Высокий уровень.
Функция Бейсика INKEY$ не дает эхо на терминал. Она возвращает
строку длиной 1 байт для символов ASCII и длиной 2 байта для
расширенных кодов. INKEY$ не ожидает нажатия клавиши, до тех пор,
пока она не помещена в цикл, в котором ожидается нажатие клавиши.
Цикл работает, обращаясь к INKEY$, а затем присваивая возвращае-
мую им строку переменной, в данном случае C$. Если клавиша не
была нажата, то INKEY$ возвращает нулевую строку, т.е. строку
длиной ноль символов, которая обозначается двумя знаками кавычек,
между которыми ничего нет (""). До тех пор пока INKEY$ возвращает
"" - цикл повторяется: 100 C$=INKEY$:IF C$="" THEN 100.
В нижеприведенном примере предполагается, что вводимые символы
выбирают одну из возможностей меню и каждый выбор приводит к
выполнению определенной процедуры программы. Выбор может быть
сделан за счет нажатия клавиш A, B, C ... (давая 1-байтные коды
ASCII) или Alt-A, Alt-B, Alt-C ... (давая 2-байтные расширенные
коды). Для их распознавания используется функция LEN, которая
определяет была ли строка длиной в 1 или 2 байта. В случае кодов
ASCII набор операторов IF...THEN сразу начинает проверять какая
клавиша была нажата, отсылая программу на соответствующую проце-
дуру. В случае 2-байтных кодов управление передается отдельной
процедуре. В этой процедуре функция RIGHT$ убирает левый символ,
который просто равен нулю и только отмечает расширенный код.
Затем используется функция ASC для преобразования строки из сим-
вольной формы в числовую. И, наконец, вторая серия операторов
IF...THEN проверяет получившееся число на соответствующие Alt-A,
Alt-B и т.д.
100 C$ = INKEY$:IF C$="" THEN 100 'ожидаем нажатия клавиши
110 IF LEN(C$)=2 THEN 500 'если расш. код - на 500
120 IF C$="a" OR C$="A" THEN GOSUB 1100 'это A?
130 IF C$="b" OR C$="B" THEN GOSUB 1200 'это B?
140 IF C$="c" OR C$="C" THEN GOSUB 1300 'это C?
.
.
500 C$=RIGHT$(C$,1) 'получаем второй байт расш. кода
510 C=ASC(C$) 'преобразуем его в число
520 IF C=30 THEN GOSUB 2100 'это Alt-A?
530 IF C=48 THEN GOSUB 2200 'Alt-B?
540 IF C=46 THEN GOSUB 2300 'Alt-C?
Отметим, что в строке 120 (и последующих) можно также использо-
вать числовые значения кодов ASCII:
120 IF C=97 OR C=65 THEN GOSUB 1100
Конечно надо сначала преобразовать C$ в форму целого числа, как
это сделано в строке 510. В программах, в которых требуется длин-
ная цепочка таких операторов, можно сэкономить место, изменяя C
таким образом, чтобы она всегда соответствовала либо верхнему,
либо нижнему регистру. Сначала нужно только проверить, что код
ASCII C$ находится в правильном диапазоне. Затем установить,
меньше ли этот код 91, тогда мы имеем дело с символом верхнего
регистра. Если это так, то надо для перевода в нижний регистр
добавить 32. В противном случае, оставить все как есть. После
этого будет достаточно более короткого оператора, такого как IF
C=97 THEN ... Вот код этой процедуры:
500 C=ASC(C$) 'получаем ASCII код символа
510 IF NOT ((C>64 AND C<91)OR(C>96 AND C<123)) THEN ...
520 IF C<91 THEN C=C+32 'приводим все к нижнему регистру
530 IF C=97 THEN ... '... начинаем проверку значений
Средний уровень.
Функции 7 и 8 прерывания 21H ожидают ввода символа, если буфер
клавиатуры пуст, а когда он появляется, то не выводится на экран.
При этом функция 8 определяет Ctrl-Break (и инициирует процедуру
обработки Ctrl-Break[3.2.8]), а функция 7 не реагирует на него. В
обоих случаях символ возвращается в AL. Когда AL содержит ASCII
0, то получен расширенный код. Повторите прерывание и в AL поя-
вится второй байт расширенного кода.
;---получаем введенный символ
MOV AH,7 ;номер функции
INT 21H ;ожидаем ввод символа
CMP AL,0 ;проверка на расширенный код
JE EXTENDED_CODE ;если да, то на особую процедуру
. ;иначе, код символа в AL
;---процедура обработки расширенных кодов
EXTENDED_CODE: INT 21H ;берем второй байт кода
CMP AL,75 ;проверяем на "стрелку-влево"
JNE C_R ;если нет, то след. проверка
JMP CURSOR_LEFT;если да, то на процедуру
C_R: CMP AL,77 ;сравниваем дальше и т.д.
BIOS обеспечивает процедуру, которая предоставляет те же воз-
можности, что и функции MS DOS. Поместите 0 в AH и вызовите пре-
рывание 16H. Функция ожидает ввода символа и возвращает его в AL.
В этом случае и расширенные коды обрабатываются за одно прерыва-
ние. Если в AL содержится 0, то в AH будет содержаться номер
расширенного кода. При это не обрабатывается Ctrl-Break.
;---ждем нажатия клавиши
MOV AH,0 ;номер функции ожидания ввода
INT 16H ;получаем введенный код
CMP AL,0 ;проверка на расширенный код
JE EXTENDED_CODE ;если да, то на спец. процедуру
. ;иначе символ в AL
;---процедура обработки расширенного кода
EXTENDED_CODE: CMP AH,75 ;берем расширенный код из AH
;и т.д.