Запись текстового экрана на диск часто имеет смысл, если многие программы используют один и тот же сложно заполненный или раскрашенный экран. Записать экран, зная его стартовый адрес и размер, несложно, ибо он занимает сплошной промежуток памяти. Программа на рис. 20.8 показывает, как это сделать.
USES CRT; { ДЕМОНСТРАЦИЯ ЗАПИСИ /ЧТЕНИЯ ЭКРАНА С ДИСКА }
{$I get_ptr.inc} {функция GetScreenPtr (см. рис. 20.1) }
{I get_par.inc) (функция GetScreenSize (см. рис. 20.2) }
{ Процедура сохранения текущего текст-экрана на диске }
PROCEDURE SaveCurrentScreenOnDisk(FileName : String );
VAR
f : File; { бестиповый файл }
Res : Word; { контрольное число }
BEGIN
Assign(f, FileName ); { файл открывается }
Rewrite(f, GetScreenSize ); { буфер равен экрану }
{ Запись всего экрана как блока по адресу видеопамяти: }
BlockWrite(f, GetScreenPtr^, 1, Res );
if Res<> 1 { контроль записи }
then Writeln(^G 'Сбой при записи'^G);
Close(f) { закрытие файла }
END.
Рис. 20.8 {484}
{ Процедура считывания текст-экрана с диска на экран. }
{ !!! Процедура не проверяет совпадение режимов }
{ записанного в файле экрана и текущего !!! }
PROCEDURE LoadScreenFromDisk( FileName : String );
VAR
f : File; { бестиповый файл }
FSize.Res : Word; { размер и контроль }
BEGIN
Assign( f, FileName ); { открытие файла }
Reset( f, 40);
{Размер буфера чтения 40 - это наименьший общий делитель для размеров видеопамяти в различных текстовых режимах. }
FSize := FileSize( f ); { число буферов в файле }
{ Чтение всего экрана в ОЗУ по адресу видеопамяти: }
BlockRead( f, GetScreenPtr^, Fsize, Res);
if Res<>Fsize { контроль чтения файла }
then WriteLn( ^G 'Сбой при чтении' ^G };
Close( f ) { закрытие файла f }
END;
VAR { — ОСНОВНАЯ ЧАСТЬ (ПРИМЕР) — }
j : Byte; с : Char;
BEGIN
ClrScr; GotoXY( 1, 5 );
for c:='A' to 'Я' do { Заполнение экрана: }
for j:=1 to 40 do begin
TextAttr := j ; Write( с )
end; {for for}
TextAttr := White + 18 * Black;
SaveCurrentScreenOnDisk('SCREEN.SCN'); {запись на диск }
Delay(2000); { пауза 2 с }
ClrScr; { очистка экрана }
Delay(1000); { пауза 1 с }
LoadScreenFromDisk( 'SCREEN.SCN' ); { чтение с диска }
ReadLn { пауза до нажатия клавиши ввода }
END.
Рис. 20.8 (окончание)
Рассмотренный пример вполне работоспособен, но имеет один достаток: «готовый» экран находится вне рабочего файла. При создании ЕХЕ-файла это может стать неудобным. Существует возможность включать текстовые изображения непосредственно в ЕХЕ-файл. Для этого надо использовать утилиту BINOBJ.EXE из пакета Турбо Паскаль для преобразования файла с изображением в OBJ-файл: {485}
C:\TP> BINOBJ SCREEN.SCN SCREEN.OBJ EXTSCREEN
Первый параметр — исходный файл, второй — имя OBJ-файла, а третий — имя, по которому будет происходить обращение к экрану в программе.
После этого программа должна быть изменена, как на рис. 20.9.
{ ДЕМОНСТРАЦИЯ ВСТАВКИ ГОТОВОГО ЭКРАНА В ПРОГРАММУ }
USES CRT;
{$1 get_ptr.inc} { функция GetScreenPtr (см. рис. 20.1)}
{$1 get_par.inc} { функция GetScreenSize (см. рис. 20.2)}
{$L screen.obj} { включение OBJ -файла }
PROCEDURE ExtScreen; EXTERNAL; { в оболочку процедуры }
{ -- ОСНОВНАЯ ЧАСТЬ — }
BEGIN
Move( @ExtScreen^, GetScreenPtr^, GetScreenSize );
{ Содержимое процедуры-экрана копируется в видеопамять.}
{ Размер экрана равен текущему. Проверка размера файла-}
{ экрана на соответствие текущему не производится. }
ReadLn { пауза до нажатия ввода }
END.
Рис. 20.9
Используя подобные приемы, следует быть уверенными, что они, оправданы. Включение готового экрана в ЕХЕ-файл может занять в нем больше места, чем код рисующей процедуры.