Страница 4 из 26
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 ;и т.д.
|