| USES CRT, DOS;
| { Процедура возвращает в буфер клавиатуры слово (Word). }
| { Значение KeyW должно содержать ASCII-код клавиши. }
| PROCEDURE UnReadKey( KeyW : Word );
| CONST
| KbdStart = $1E; { специальные значения }
| KbdEnd = $3C;
| VAR
| KbdHead Word absolute $40:$1A; { голова буфера }
| KbdTail Word absolute $40:$1C; { хвост буфера }
| OldTail Word;
Рис. 21.12
- 512 -
| BEGIN
| OldTail := KbdTail;
| if KbdTail = KbdEnd
| then KbdTail := KbdStart
| else Inc( KbdTail, 2 );
| if KbdTail = KbdHead
| then KbdTail := OldTail
| else MemW[$40:OldTail] := KeyW;
| END;
{Эта процедура посылает в буфер ввода значение расширенного кода, имитируя нажатия Alt-комбинаций, функциональных клавиш и клавиш управления курсором. В ExtCode должен содержаться второй (расширенный) код клавиши. }
| PROCEDURE UnReadExtCode( ExtCode : Word );
| BEGIN
| UnReadKey( Swap( ExtCode ) )
| END;
| { Процедура помещает в буфер строку в 16 символов }
| PROCEDURE UnReadString( S : String );
| VAR i : Byte;
| BEGIN
| Delete( S, 17, 255 ); { первые 16 символов }
| for i:=1 to Length(S) do
{ заполнение буфера }
| UnReadKey( Ord( S[i] ) );
| END;
| VAR St : String; { ПРИМЕР ПРИМЕНЕНИЯ ПРОЦЕДУР }
| BEGIN
| { — Пример 1 : автоматизация чтения с клавиатуры — }
| ClrScr;
| TextAttr := Black + 16*LightGray; { текст запроса: }
| Write( ' Допишите число или исправьте : ' );
| TextAttr := LightGray;
| UnReadString(22-2-19'); {подсовываем ответ в буфер }
| Readln(St); { чтение строки }
| Write(#10'Результирующая строка -> '); { что прочитали }
| HighVideo; WriteLn( St ); LowVideo; ReadLn;
| {--Пример 2: готовые ответы на вопросы внешнего файла-- }
| St := 'Hello, Outer !' + #13;
| {St - передаваемая строка. #13 на конце - символ ввода }
| WriteLn( 'В буфер передается строка : ',St );
| UnReadString(St);
| WriteLn( #10 Запускается внешний файл OUTER.' );
| {запуск внешнего файла}
| SwapVectors; Exec('OUTER.EXE','');
| SwapVectors;
| ReadLn { пауза до нажатия ввода }
| END.
Рис. 21.12 (окончание)
- 513 -
Здесь в качестве примера приводится запуск программы OUTER, ожидающей ввод строки с клавиатуры. При отладке этого примера демонстрационная программа OUTER.PAS имела содержание, приведенное на рис. 21.13.
| VAR { -- ПРОГРАММА OUTER.PAS -- }
| S : String;
| BEGIN
| Write( #10' ЗАПРОС <-- ' ); ReadLn( S );
| WriteLn( #10#10'Ha запрос была введена строка : ', S )
| END.
Рис. 21.13
Вообще говоря, это может быть любая программа, в том числе и начинающая свою работу с опроса меню. В этом случае надо было бы заполнить буфер расширенными кодами клавиш управления курсором и клавишей ввода, например:
UnReadExtCode( 80 ); { три нажатия стрелки }
UnReadExtCode( 80 ); { курсора вниз - код 80 }
UnReadExtCode( 80 );
UnReadKey( #13 ); { клавиша ввода -код 13 }
SwapVectors;
Ехес( '...', '...' ); { запуск программы с меню )
SwapVectors;
К сожалению, всегда существует ограничение в шестнадцать символов в буфере. Это не так неприятно в одной программе, где всегда можно при необходимости «подпитать» буфер новой порцией кодов, но плохо в случае передачи кодов субпроцессу, где уже никак их после запуска не дописать. В принципе, можно организовать «подпитку» буфера, но для этого надо перехватывать прерывание 16H и обрабатывать его весьма нетривиальным способом.
- 514 -
Глава 22. Работа с оперативной памятью видеоадаптеров