Окно со скроллером
Скроллером называется специальное окно, обеспечивающее просмотр (скроллинг) текста. Типичный скроллер - это окно редактора интегрированной среды системы Турбо Паскаля; его поведение Вам, очевидно, хорошо знакомо. Средства 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-указателя) на некоторых ПК мог бы привести к аварийному останову.