| USES CRT, DOS;

| VAR

| Ch, ExtCh : Char; {символы с клавиатуры }

| Scan, LastScan : Byte; {скэн-коды клавиш }

| OldInt09H : Pointer; {адрес старого вектора }

| {$F+}

| PROCEDURE IntProc; INTERRUPT; {перехват прерывания }

| BEGIN

| Scan:=Port[$60]; {чтение скэн-кода }

| Inline($FF/$1E/>OldInt09H); {возврат прерывания }

| END;

| {$F-}

| BEGIN

| GetIntVec($09, OldInt09H); {взятие адреса прерывания }

| SetIntVec($09, @IntProc); {подстановка перехватчика }

Рис. 21.10

- 508 -

| Scan := 128;

| { стартовое значение Scan }

| WriteLn('Нажимайте что угодно.', 'Esc - выход из программы.');

| repeat { Основной цикл опроса: }

| Ch := #0;

| ExtCh := #0;

| { сброс значений до опроса }

| repeat

| until Scan<128; { ожидание любого нажатия }

| Write( ' Скэн-код=', Scan:3 );

| if KeyPressed { Клавиша - не регистровая? }

| then Ch:=ReadKey; { да, ее код запоминается }

| if KeyPressed and (Ch=#0) {Клавиша - функциональная? }

| then ExtCh := ReadKey; { да, запоминается расш. код }

| { вывод итогов опроса: }

| Write ( 'Символ', Ch + ExtCh );

| GotoXY( 30, WhereY ); { нейтрализация кода 13 }

| WriteLn(('” Код=', Ord( Ch ):3, ' Расш. код=', Ord( ExtCh ) );

| LastScan := Scan; { нужен последний скэн-код }

| Scan := 128; { снова стартовое значение }

| until LastScan=1; { условие конца — нажата Esc }

| SetIntVec($09, OldInt09H);

| { восстановление прерывания }

| ReadLn { пауза до нажатия ввода }

| END.

Рис. 21.10 (окончание)

Программа перехватывает низкоуровневое прерывание номер 9 и запоминает содержимое порта, через который передаются коды нажатых клавиш, в глобальной переменной Scan. После этого анализируется, внесло ли нажатие что-либо в буфер ввода. Если да, то выводится информация о нажатой клавише. Используя перехват прерывания, кaк это сделано в примере, можно проводить и более сложный анализ (рис. 21.11). После каждого нажатия любой клавиши перехватчик записывает в Scan скэн-код. Но здесь есть особенность: при нажатии клавиши вырабатывается истинный скэн-код, а при отпускании — увеличенный на 128. Поэтому в примере ожидание нажатия возложено на цикл

repeat until Scan < 128;

который размыкается только при нажатии клавиши (Scan содержит число, меньшее 128) и не реагирует на отпускание их.

На рис. 21.11 рассматривается каркас Паскаль-программы, позволяющей «отлавливать» одновременное нажатие нескольких регистровых клавиш вместе с алфавитной клавишей или без нее.

Аналогичным методом можно определять факты нажатия практически всех распознаваемых ПЭВМ комбинаций клавиш. Надо

- 509 -

| { КАРКАС ПРОГРАММЫ, РЕАГИРУЮЩЕЙ НА СПЕЦИАЛЬНЫЕ КОМБИНАЦИИ}

| { НАЖАТИЙ НА КЛАВИАТУРЕ }

| USES CRT, DOS;

| {Необходим модуль DOS. CRT нужен для примера. }

| VAR { глобальные переменные программы : }

| OldInt09H : Pointer; { адрес прерывания 09 }

| CtrlRShiftD : Boolean; { флаг нажатия комбинации }

| CONST { Константы специальной комбинации клавиш: }

| HotKey = $20; { скэн-код клавиши [D]; }

| KlavReg = 1+4; { значение в байте $0:$0417 при нажатии }

| { левого регистра Shift вместе с Ctrl : }

| { 1 - нажата правая клавиша Shift (бит 0); }

| { 4 - Нажато Ctrl+Shift (бит номер 2). }

| {$F+}

| PROCEDURE IntProc; INTERRUPT; {перехват прерывания 09Н }

| VAR

| M: Byte absolute $000:$417; { байт состояния регистров }

| C,L,H : Byte; { значение скэн-кода и др. }

| BEGIN

| С := Port[$60]; { чтение скэн-кода }

Перейти на страницу:

Поиск

Похожие книги