Вывод текста

По сравнению с рис. 15.4 мы добились немногого, ведь пока еще не решена главная проблема - вывод нужного текста. Разумеется, в Вашем распоряжении всегда имеется процедура WRITELN, однако вывод текста «в лоб» с помощью этой процедуры практически никогда не используется в Turbo Vision, так как в этом случае выведенный текст не будет связан с окнами.

В объекте TScroller для вывода текста предусмотрен абстрактный метод Draw. Абстрактным он называется потому, что не выполняет никакой полезной работы. Однако именно к этому методу обращается обработчик событий объекта TScroller всякий раз, когда понадобится обновить на экране вид окна. Чтобы объект выполнял все заложенные в него функции, нам необходимо перекрыть этот метод новым. Мы уже знаем, что для этого нужно объявить новый объект:

type

PInterior =ATInterior; TInterior = object (TScroller)

Constructor Init(var Bounds: TRect; HS,VS: PScrollBar);

Procedure Draw; virtual;

Procedure ReadFile; 

end;

Мы перекрыли абстрактный метод Draw, стандартный конструктор Init и инкапсулировали в объект новый метод ReadFile. Новый конструктор предназначен для инициации экземпляра объекта TScroller. Кроме того, с помощью метода ReadFile он должен прочитать все записи файла данных и подготовить соответствующий массив строк - это сократит время на обновление текста процедурой Draw.

Перед тем, как двигаться дальше, подумаем о способе хранения строк для процедуры Draw. Если все необходимые действия по чтению нужной записи из файла и преобразования ее к текстовому формату возложить на процедуру Draw, наша программа станет слишком медленной, в особенности, если файл данных записан на дискете. Поэтому предусмотрим такие глобальные переменные:

const

MaxLine = 300; {Максимальная длина массива} 

LLine = LName+LPhone+LAddr; {Длина строки} 

var

NLines: Word; {Истинная длина массива строк} 

Lines: array [1..MaxLine] of String [LLine]; {Массив строк}

Теперь нетрудно подготовить процедуру ReadFile:

Procedure TInterior.ReadFile;

{Читает содержимое файла данных в массив Lines}

var

k: Integer; s: String;

Data: DataType; 

begin

seek(DataFile, 0) ;

NLines := FileSize(DataFile);

if NLines > MaxLine then

NLines := MaxLine; 

for k ':= 1 to NLines do 

begin

Read(DataFile, data); 

with data do 

begin

s := Name;

while Length(s) < LName do

s := s+' '; 

s := s+Phone; 

while Length(s) < LName+LPhone do

s := s+' '; 

s := s+Addr 

end;

Lines[k] := s 

end; 

end; {ReadFile}

В этой процедуре из записей файла данных готовится массив строк Lines, причем начало каждого поля выравнивается так, чтобы поля образовали колонки - такая форма вывода поможет легко найти на экране каждое поле.

Теперь займемся процедурой Draw:

Procedure TInterior.Draw; 

{Выводит данные в окно просмотра}

var

n, {Текущая строка экрана} 

k: Integer; {Текущая строка массива}

В: TDrawBuffer; Color: Byte; 

begin

Color := GetColor(l); {Использовать цвет основного текста} 

for n := 0 to pred(Size.Y) do 

{Size.Y - количество строк окна} 

begin

k := Delta.Y+n+1; {Delta.Y - номер первой выводимой строки} 

MoveChar(B,' ',Color,Size.X);

MoveStr(B, Copy(Lines[k],Delta.X+l,Size.X),Color); 

WriteLine(0,N,Size.X,l,B) 

end 

end; {TInterior.Draw}

Работа процедуры основана на использовании текущих размеров и положения текстового окна относительно текста. Эти параметры хранятся в полях Size и Delta объекта TScroller и обновляются всякий раз, когда пользователь манипулирует полосами управления или изменяет размеры окна. Для вывода текста используются три процедуры: MoveChar, MoveStr, WriteLine. Каждая из них оперирует переменной В типа TDrawBuffer, представляющей собой последовательности кодов выводимых символов и их атрибутов. Процедура MoveChar заполняет переменную В указанным символом (' ') и атрибутом (Color). Процедура MoveStr копирует строку в переменную В, а с помощью WriteLine осуществляется вывод буфера В на экран.

Для вывода изображений (текста) перекрывайте и используйте метод Draw объекта-владельца нужной части экрана. Это обеспечит автоматическое изменение изображения и его прорисовку при изменении границ или положения поля вывода.