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