Окно со скроллером

Скроллером называется специальное окно, обеспечивающее просмотр (скроллинг) текста. Типичный скроллер - это окно редактора интегрированной среды системы Турбо Паскаля; его поведение Вам, очевидно, хорошо знакомо. Средства Turbo Vision обеспечивают стандартные функции скроллера для окна, создаваемого в приводимой даже программе. В частности, это окно (см. рис.23.4) управляется мышью, реагирует на клавиши смещения курсора, оно может изменять размеры и свое положение на экране, его можно «распахнуть» на весь экран.

Рис.23.4. Окно со скроллером

Uses Objects,App,Drivers,Menus,Views; var

Lines: PCollection; {Коллекция для хранения текстовых строк}

type

ТМуАрр = object (TApplication)

Procedure Run; Virtual; 

end;

PInterior =TInterior;

TInterior = object (TScroller)

Constructor Init(R: TRect; SX,SY: PScrollBar);

Procedure Draw; Virtual; 

end;

Procedure TMyApp.Run;

{Читает строки из, текстового файла и обеспечивает их просмотр}

var

R: TRect;

W: PWindow;

s,name: String;

f: text; 

begin

{Получаем в NAME имя файла с текстом программы:}

name := copy(ParamStr(0),1,pos('.',Paramstr(0)))+'PAS';

{Создаем коллекцию текстовых строк:}

Lines := New(PCollection, Init(10,5));

assign(f,name);

{$I-}

reset (f);

{$I+}

if IOResult = 0 then

begin {Файл успешно открыт} 

with Lines do while not EOF(f) do

begin

ReadLn ( f , s ) ; 

Insert (NewStr (s) ) 

end;

Close (f) 

end 

else {Файл не был открыт}

Lines . Insert (NewStr (' Нет доступа к файлу '+name)); 

{Создаем окно со скроллером: } 

DeskTop.GetExtent (R) ;

W := New (PWindow, Init (R, 'Просмотр файла '+name,0)); 

with W do 

begin

GetClipRect(R) ; 

R.Grow(-1, -1) ;

Insert (New (PInterior , Init (R, StandardScrollBar ( 

sbHorizontal+ sbHandleKeyboard) , 

StandardScrollBar (sbvertical+sbHandleKeyboard) ) ) ) 

end ;

DeskTop . Insert (W) ; 

{Ждем действий пользователя:} 

Inherited Run end {TMyApp.Run} ;

{----------------}

Constructor TInterior.Init; 

{Создает окно скроллера} 

begin

Inherited Init (R, SX, SY) ;

GrowMode := gfGrowHiX+gfGrowHiY;

SetLimit(128, Lines .count- 1) 

end {TInterior.Init};

{----------------}

Procedure TInterior.Draw;

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

var

Y: Integer; 

В: TDrawBuffer; 

S: String; 

begin

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

begin

MoveChar(B,' ' ,GetColor (1) , Size.X) ; 

if (Y+Delta.Y < Lines. Count) and

(Lines. At (Y+Delta.Y) <> NIL) then 

begin

S := PString (Lines. At (Y+Delta.Y) ); 

MoveStr (В, copy (s, Delta. X+1, Length (s) -

Delta. X), GetColor(1) ) 

end;

WriteLine(0,Y,Size.X,1,B) 

end 

end {TInterior.Draw} ;

{----------}

var

P : TMyApp ; 

begin

P.Init;

P. Run;

P. Done 

end.

В программе перекрывается метод TApplication.Run. В потомке TMyApp этот метод вначале считывает текстовые строки из файла с текстом программы в коллекцию Lines и создает на экране окно со скроллером. После этого вызывается стандартный метод TApplication.Run.

Метод TInterior.Draw обеспечивает вывод нужных строк в окно скроллера. Для определения порядкового номера выводимых строк и их положения относительно границ скроллера используется поле TScroller.Delta. Обратите внимание: если в коллекцию помещается «пустая» строка, т.е. строка нулевой длины, глобальная функция NewStr возвращает значение NIL. В методе TInterior.Draw оператор

if (Y+Delta.Y < Lines. count) and 

(Lines.At(Y+Delta.Y) <> NIL) then ...

осуществляет проверку значения получаемого из коллекции указателя на NIL; если бы мы не предусмотрели эту проверку, прогон программы (использование NIL-указателя) на некоторых ПК мог бы привести к аварийному останову.