| Execute := False; { пусть сначала будет так }
| case DosError of { анализ вызова Exec }
| 0 : begin { все в порядке }
| Execute := True; { Меняем значение функции }
| Exit { и выходим из нее }
| end;
| 2 : WriteLn(#10'He найден файл ', ExeFile );
| 8 : WriteLn(#10'He хватает памяти для субпроцесса )
| else WriteLn(#10'Ошибка DOS номер ', DosError )
| end {case}
| END;
| VAR { ===== ПРИМЕР ВЫЗОВОВ ==== }
| Er, Ex : Byte;
| Ch : Char;
| BEGIN
| ClrScr; { очистка экрана }
| CheckBreak := True; '
| Repeat { вечный цикл }
| WriteLn( 'Нажмите :' );
| WriteLn{ ' ':15, '[D] - для выхода в DOS' );
| WriteLn( '':15, '[S] - для запуска субпроцесса' );
| WriteLn( '':15, '[Q] - для завершения работы' );
| repeat
| Ch := UpCase( ReadKey ) { Выборочный опрос }
| until ( Ch in [ 'D','S','Q'] ); { клавиатуры. }
| case Ch of { Действия : }
| 'D' : begin { 1.Выход в MS-DOS. }
| HighVideo;
| Write( #10'Для возврата введите EXIT...' );
| LowVideo;
| if Execute(GetEnv('COMSPEC'),' ',Er,Ex) then;
| end;
Рис. 16.17
- 384 -
| 'S' : begin { 2. Запуск файла. }
| if not Execute('outer.exe',' ', Er, Ex ) then
| Halt; { запуск неудачен }
| if Ex = 1 then { Вы нажали ^Break:}
| WriteLn(#10'Процесс прерван с консоли.' );
| end;
| 'Q' : Exit { 3. Выход из программы. }
| end; {case}
| until False { условие вечного цикла }
| END.
Рис. 16.17 (окончание)
16.6.2. Процедура Keep и резидентные программы
Процедура Кеер( ExitCode : Word ), пожалуй, наименее описанная в руководстве по Турбо Паскалю. Ее назначение — завершать выполнение программы, выдавая в DOS код, заданный параметром ExitCode и оставлять ее в памяти ПЭВМ, т.е. делать программу резидентно находящейся в памяти. Ставится эта процедура в тексте программы последней по очередности выполнения. Внешне она аналогична процедуре Halt(n), но в отличие от последней резервирует память. Программы, разрабатываемые как резидентные, должны обязательно иметь в первых строках директиву распределения памяти {$М ... } , в которой указываются необходимые для резервирования объемы памяти под стек и кучу (динамические объекты и данные).
Организация резидентных программ — дело достаточно сложное и требующее хороших системных знаний. Ведь мало оставить программу в памяти ПЭВМ — надо еще «заставить» ее реагировать на прерывания, возвращать управление и т.п. Это подразумевает наличие в тексте вставок машинных кодов и процедур с директивой interrupt, что вовсе не упрощает написание программ. Тяжело дается и отладка «резидентов» — после каждой неудачи, как правило, приходится перезапускать ПЭВМ.
Тем не менее ниже мы приводим пример резидентной программы. Она использует ряд функций модуля CRT и специальные приемы определения начала видеопамяти (см. разд. 20.1) и копирования экрана процедурой Move (рис. 16.18).
- 385 -
| { $М 1024, 0, 0} { директивы распределения памяти }
| PROGRAM HideScr;
{ Резидентная программа скрытия экрана от любопытных глаз во время отсутствия программиста. Работает во всех режимах текста и использует пароль (если задан) для возврата }
| USES CRT, DOS;
| VAR
| OldAttr : Byte; { последний цвет символов }
| WX, WY : Byte; { последнее место курсора }
| ScrAddr : Word; { сегмент начала экрана }
| Buffer : Array [1..8000] of Byte; {буфер для экрана }
| PS : String[20]; { нужна для ввода пароля }
| b : Boolean; { значение параметра BREAK }
| CONST
| Password : String[20] = ' '; { задаваемый пароль входа }
| {$F+}
| PROCEDURE MyInt05H; INTERRUPT; { процедура прерывания }
| VAR с : Char;
| BEGIN