Страница 59 из 60
Использование кодов клавиш сканирования
При работе на ПЭВМ фирмы ИБМ наиболее сложно обрабатывать программно коды функциональных клавиш и клавиш со стрелками /так- же клавиш 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". К сожа- лению этот путь является единственным. Однако, наградой будет возможность работать в вашей программе с полным набором клавиш ПЭВМ фирмы ИБМ.
|