Энциклопедия Turbo Pascal. Главы 1-4
Страница 59. Использование кодов клавиш сканирования


Использование кодов клавиш сканирования

     При работе на ПЭВМ фирмы ИБМ  наиболее  сложно  обрабатывать
программно коды функциональных клавиш и клавиш со стрелками /так-
же клавиш INS,  DEL,  PGOP,  PGDN, END и HOME/. При нажатии такой
клавиши генерируется не восьмибитовый /однобайтовый/ код, как де-
лается при нажатии других клавиш.  При нажатии  такой  клавиши  в
действительности  генерируется шестнадцатибитовый код, называемый
кодом сканирования.  Код сканирования состоит из младшего  байта,
который при нажатии обычной клавиши будет содержать код ASCII для
этой клавиши,  и старшего байта, который содержит позицию клавиши
на клавиатуре.
     Для большинства клавиш операционная система преобразует  код
сканирования  в  соответствующий восьмибитовый код ASCII.  Но для
функциональных клавиш и клавиш со стрелками это преобразование не
делается,  поскольку  код  символа  для специальной клавиши будет
иметь нулевое значение. Это означает, что для определения нажатой
клавиши необходимо воспользоваться кодом позиции.  Программу чте-
ния символа с клавиатуры посредством обращения к  функции  ДОС  с
номером I нельзя использовать для чтения специальных клавиш. Это,
очевидно,  приводит к трудностям,  когда в  программе  необходимо
использовать  специальные клавиши.  В Турбо Паскале версии 4 пре-
дусматривается функция "Readkey",  предназначенная для  чтения  и
символов и кодов. Однако в приводимой ниже процедуре используется
другой подход. Здесь делается прерывание $16 для получения полно-
го шестнадцатибитового кода клавиши.

     ; эта процедура выдает шестнадцатибитовый код,  младший байт
     ; которого содержит либо символ ASCII,  либо нулевое  значе-
     ; ние. В последнем случае старший байт содержит код сканиро-
     ; вания

     code    segment 'code'
             assume cs:code

     public  scan
     scan    proc near

     ; сохранить указатель  стека
             push bp
             mov bp,sp

     ; получить первый параметр
            mov ah,0
            int 16h
            mov [bx+2],ax; возвращаемое значение
     ; восстановление и выход

            pop bp
            ret 2
     scan   endp
     code   endx
            end

     После вызова  код сканирования и код символа уже будут нахо-
диться в регистре АХ,  который следует использовать для  передачи
информации в вызывающую процедуру. После прерывания 16n с нулевым
функциональным номером код позиции будет  находиться  в  регистре
АН,  а  код  символа  будет  находиться в регистре AL.  Процедура
"scan" написана с учетом того, что при нажатии специальной клави-
ши код символа имеет нулевое значение.

     Если код символа имеет нулевое значение, то декодируется код
позиции для определения,  какая клавиша была нужна. Для обработки
всякого  ввода с клавиатуры посредством указанной функции решения
следует принимать на основе содержимого регистров АН и  AL.  Один
из таких способов иллюстрируется ниже в короткой программе:

     program special_keys;

     {SL SCAN}

     var
       t: integer;

     function Scan:integer; external;

     begin
       repeat
         t: = Scan;
         if lo(t)=0 then WriteLn('scan code is', hi(t))
         else WriteLn(chr(lo(t)));
       until chr(lo(t))='q';
     end.

     Для доступа к обеим половинам  шестнадцатиразрядного  значе-
ния, полученного процедурой "scan", можно воспользоваться предус-
мотренными в Турбо Паскале стандартными функциями  "Ht"  и  "Lo".
Кроме того,  для преобразования целого числа в символ потребуется
функция "Chr".
     Для декодирования кода сканирования вы можете воспользовать-
ся техническим справочным руководством фирмы ИБМ.  Другой,  более
интересный  способ,  заключается  в написании короткой программы,
единственным назначением которой является  лишь экспериментальная
выдача кодов нажатых клавиш.  Для начала приведем коды сканирова-
ния для клавиш со стрелками:

     Левая стрелка - 75, Правая стрелка - 77, Стрелка вверх - 72,
     Стрелка вниз - 80.

     Для полного совмещения специальных клавиш с обычными кла ви-
шами необходимо  написать  специальные  функции  ввода  данных  и
использовать их вместо обычных функций "read" и "readln". К сожа-
лению этот путь является  единственным.  Однако,  наградой  будет
возможность  работать  в  вашей программе с полным набором клавиш
ПЭВМ фирмы ИБМ.

 
« Предыдущая статья