Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

лабораторные на Pasca (Кудрявцев)l

.pdf
Скачиваний:
32
Добавлен:
18.03.2015
Размер:
1.63 Mб
Скачать

Окна

263

 

 

Наконец, мы должны определить реакцию на выбор этих команд, то есть добавить в процедуру TMyApp.HandleEvent описание дейст- вий, которые нужно выполнить:

cmTile: begin

DeskTop^.GetExtent(R);

DeskTop^.Tile(R);

end;

cmCascade: begin

DeskTop^.GetExtent(R);

DeskTop^.Cascade(R);

end;

Если Вы все сделали правильно, то открытые Вами окна теперь можно будетрасполагать каскадом или мозаикой.

Еще одно поле, которым располагает TWindow – поле Palette типа integer. Это поле задает цвет элементов окна. Стандартными явля-

ются значения wpBlueWindow, wpCyanWindow и wpGrayWindow. Лег-

ко, например, сделать серыми второе и четвертое из открываемых окон. Для этого в процедуру TMyApp.NewWindow достаточно доба- вить строку:

if ((WinCount=2) or (WinCount=4)) then Window^.Palette:=wpGrayWindow;

Для того, чтобы изменить стандартную раскраскуокон, необхо- димо воспользоваться виртуальной функцией GetPalette: PPalette. Это выглядит так:

function TDemoWindow.GetPalette: PPalette; const

CDemoWindow=#15#9#5;

PDemoWindow: string[Length(CDemoWindow)]=CDemoWindow; begin

GetPalette:=@PDemoWindow;

end;

Константа CDemoWindow и содержит описание новой палитры окна. Ее первый бит (#15) определяет цвет рамки пассивного окна, вто- рой (#9) – цвет рамки активного окна, третий (#5) – цвет кнопок управления окном. Всего в CDemoWindow содержится восемь бит, определяющих полную окраску окна. Вы можете удивиться, поче-

264

Лабораторная работа № 24

 

 

му, указав цвет 15, Вы получили не белое окно, а красное (15 номер соответствует белому цвету в стандартном Паскале). Дело в том, что передача цветов в Turbo Vision происходит достаточно сложным образом. Во-первых, для отображения некоторого видимого объек- та нужно задать два цвета цвет фона и цвет изображения. Во- вторых, каждый видимый объект имеет своего хозяина”, который этим объектом владеет, соответственно должны быть согласованы цвета различных объектов. Поэтому в CDemoWindow на самом деле Вы указываете не сам цвет окна, а то место, которое нужный Вам цвет (точнее пара цвет фона + цвет изображения) занимает в па- литре цветов объекта-хозяина. Хозяином всех наших окон является DeskTop, который, однако, собственной палитры не имеет. Поэто- му, поднимаясь по дереву иерархии, мы находим другого хозяина TProgram, в палитре которого и находятся выбранные нами цвета. Не вдаваясь в подробности описания сложной палитры TProgram, Вы можете попробовать «экспериментально» подобрать те цвета, которые покажутся Вам наиболее удачными.

После всех внесенных изменений Ваша программа должна принять окончательный вид:

program TFirst3;

uses App,Objects,Menus,Drivers,Views; const

cmNewWin=199;

cmFileOpen=200; winCount: Integer=0;

type TMyApp=Object(TApplication) procedure InitStatusLine; virtual; procedure InitMenuBar; virtual; procedure NewWindow; virtual;

procedure HandleEvent(var Event: TEvent); virtual; end;

type PDemoWindow=^TDemoWindow; TDemoWindow=object(TWindow) function GetPalette: PPalette;virtual; end;

Окна

265

 

 

var

MyApp: TMyApp;

function TDemoWindow.GetPalette: PPalette; const

CDemoWindow=#15#13#4;

PDemoWindow: string[Length(CDemoWindow)]=CDemoWindow; begin

GetPalette:=@PDemoWindow;

end;

procedure TMyApp.InitStatusLine; var R:TRect;

begin GetExtent(R); R.A.Y:=R.B.Y-1;

StatusLine:=New(PStatusLine,Init(R, NewStatusDef(0,$FFFF, NewStatusKey('~Alt-X~Exit',kbAltX,cmQuit, NewStatusKey('~F4~New',kbF4,cmNewWin, NewStatusKey('~Alt-F3~Close',kbAltF3,cmClose, NewStatusKey('~F10~Menu',kbF10,cmMenu,

nil)))),

nil)))

end;

procedure TMyApp.InitMenuBar; var R:TRect;

begin GetExtent(R); R.B.Y:=R.A.Y+1;

MenuBar:=New(PMenuBar,Init(R,NewMenu(

NewSubMenu('~F~ile',hcNoContext,NewMenu(

NewItem('~O~pen','F3',kbF3,cmFileOpen,

hcNoContext,

NewItem('~N~ew','F4',kbF4,cmNewWin,

hcNoContext,

NewLine( NewItem('E~x~it','Alt-X',kbAltX,cmQuit,

hcNoContext,

nil))))),

266

Лабораторная работа № 24

 

 

NewSubMenu('~W~indow',hcNoContext,NewMenu(

NewItem('~N~ext','F6',kbF6,cmNext,

hcNoContext,

NewItem('~Z~oom','F5',kbF5,cmZoom,

hcNoContext, NewItem('~S~ize/Move','Ctr-F5',kbCtrlF5,cmResize,

hcNoContext,

NewItem('~T~ile','',0,cmTile,

hcNoContext,

NewItem('~C~ascade','',0,cmCascade,

hcNoContext,

nil)))))),

nil)))))

end;

procedure TMyApp.NewWindow; var

Window: PDemoWindow; R: TRect;

begin Inc(WinCount); R.Assign(0,0,30,7);

R.Move(Random(58),Random(16)); Window:=New(PDemoWindow, Init(R,'Demo Window ', WinCount)); Window^.Options:=Window^.Options+ofTileable; DeskTop^.Insert(Window);

end;

procedure TMyApp.HandleEvent(var Event: TEvent); var R: TRect;

begin TApplication.HandleEvent(Event); if Event.What=evCommand then begin

case Event.Command of cmNewWin: NewWindow; cmTile:

begin DeskTop^.GetExtent(R); DeskTop^.Tile(R);

Окна

267

 

 

end;

cmCascade: begin

DeskTop^.GetExtent(R);

DeskTop^.Cascade(R); end

else Exit; end; end;

end; BEGIN

MyApp.Init;

MyApp.Run;

MyApp.Done;

END.

Задания для самостоятельнойработы

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

Измените атрибуты третьего окна так, чтобы оно стало недоступным для пользователя, то есть после создания не реагировало бы ни на какие ко- манды от мышки или клавиатуры.

268

Лабораторная работа № 25

ИНТЕРЬЕР

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

перемещаться вместе с ним, исчезать при его закрытии и так да- лее. Этот видимый объект и называют интерьером окна или просто интерьером. Как мы уже отмечали, все видимые объекты являются потомками TView, поэтому его объявление в соответствии с общи- ми правилами Turbo Vision будетиметь вид:

PInterior=^TInterior;

TInterior=object(TView)

Для инициализации объекта TInterior нам достаточно указать разме- ры той области, которую он будет занимать, то есть инициализиро- вать единственное поле, определяемое переменной типа TRect. Следовательно, в описание объекта войдет конструктор

constructor TInterior.Init(var Bounds: TRect);

Наконец, TInterior должен уметь себя рисовать. Все видимые объек- ты рисуют себя с помощью родительского метода Draw, который нам необходимо расширить, поскольку создаем мы наш собствен- ный интерьер (в предыдущей работе мы создавали стандартные ок- на и расширение метода Draw нам не потребовалось). Следователь- но, в описание TInterior войдет виртуальная процедура Draw и раз- дел описания типов нашей программы TFirst3 пополнится строками:

PInterior=^TInterior;

TInterior=object(TView)

Интерьер

269

 

 

constructor TInterior.Init(var Bounds: TRect); procedure Draw; virtual;

end;

Входящие сюда конструктор и процедура описываются следующим кодом:

constructor TInterior.Init(var Bounds: TRect);

begin

 

 

TView.Init(Bounds);

 

{вызываем метод Init предка}

GRowMode:=gfGrowHiX+gfGrowHiY;

{и устанавливаем, что при изменении

 

размеров окна его интерьер будетсохранять

постоянное расстояние от правой и нижней границ окна-владельца}

end;

 

 

procedure TInterior.Draw;

 

 

var

 

 

S: string;

 

 

begin

 

 

TView.Draw;

 

{вызываем метод предка}

S:='Я Вам пишу';

 

 

WriteStr(4,2,S,6);

{добавляем в интерьер необходимуюзапись;

 

первые две цифры относительные координаты строки S,

 

 

последняя код цвета строки}

end;

Теперь нужно подсоединить интерьер к окну. На языке Turbo Vision это означает, что мы должны снова инициализировать окно, теперь уже с добавлением к нему интерьера. Поэтому придется написать конструктор Init для нашего объекта TDemoWindow. Он может вы- глядеть, например, так:

constructor TDemoWindow.Init(Bounds: TRect; WinTitle: string; WindowNo: Integer);

Var

 

{не забудьтеобновить описание типов}

S: string[3];

 

 

 

Interior: PInterior;

 

 

 

begin

 

 

 

Str(WindowNo, S);

{переводим численное значение номера окна в строку}

TWindow.Init(Bounds, WinTitle+' '+S, wnNoNumber);

{и добавляем его к

GetClipRect(Bounds);

 

 

заголовку окна}

{запрашиваем размеры доступного пространства окна}

Bounds.Grow(-1,-1);

{устанавливаем размеры интерьера на единицу меньше

 

размеров окна}

 

Interior:=New(PInterior, Init(Bounds));

{инициализируем интерьер}

Insert(Interior);

 

{и вставляем его в окно}

end;

 

 

 

270

Лабораторная работа № 25

 

 

Если Вы правильно внесли изменения в программу TFirst3, то мо-

жете увидеть на экране результат своих трудов и поупражняться в изменении атрибутов созданного интерьера.

Кроме процедуры WriteStr для записи в окно может использоваться

и процедура

WriteChar(X,Y,Ch,Color,Count),

которая позиционирует свой вывод в координаты (X,Y) относитель- но видимого элемента и пишет Count копий символа Ch, цветом Color из палитры видимого элемента. Эту процедуру удобно ис- пользовать при создании, например, рамок.

После внесенных изменений Ваша программа должна принять вид:

program TFirst4;

uses App,Objects,Menus,Drivers,Views; const

cmNewWin=199;

cmFileOpen=200; winCount: Integer=0;

type TMyApp=Object(TApplication) procedure InitStatusLine; virtual; procedure InitMenuBar; virtual; procedure NewWindow; virtual;

procedure HandleEvent(var Event: TEvent); virtual; end;

type PDemoWindow=^TDemoWindow; TDemoWindow=object(TWindow)

constructor Init(Bounds: TRect; WinTitle: string; WindowNo: Integer);

end; type

PInterior=^Tinterior;

TInterior=object(TView)

constructor Init(var Bounds: TRect); procedure Draw; virtual;

end; var

MyApp: TMyApp; S: string;

constructor TInterior.Init(var Bounds: TRect);

Интерьер

271

 

 

begin TView.Init(Bounds);

GRowMode:=gfGrowHiX+gfGrowHiY;

end;

procedure TInterior.Draw; var

S: string; begin

TView.Draw; S:='Запись в окно'; WriteStr(4,2,S,6); end;

constructor TDemoWindow.Init(Bounds: TRect; WinTitle: string; WindowNo: Integer);

var S: string[3]; Interior: PInterior;

begin Str(WindowNo, S);

TWindow.Init(Bounds, WinTitle+' '+S, wnNoNumber); GetClipRect(Bounds);

Bounds.Grow(-1,-1); Interior:=New(PInterior, Init(Bounds)); Insert(Interior);

end;

procedure TMyApp.InitStatusLine; var R:TRect;

begin GetExtent(R); R.A.Y:=R.B.Y-1;

StatusLine:=New(PStatusLine,Init(R, NewStatusDef(0,$FFFF, NewStatusKey('~Alt-X~Exit',kbAltX,cmQuit, NewStatusKey('~F4~New',kbF4,cmNewWin, NewStatusKey('~Alt-F3~Close',kbAltF3,cmClose, NewStatusKey('~F10~Menu',kbF10,cmMenu,

nil)))),

nil)))

end;

procedure TMyApp.InitMenuBar; var R:TRect;

begin GetExtent(R); R.B.Y:=R.A.Y+1;

MenuBar:=New(PMenuBar,Init(R,NewMenu(

272

Лабораторная работа № 25

 

 

NewSubMenu('~F~ile',hcNoContext,NewMenu(

NewItem('~O~pen','F3',kbF3,cmFileOpen,

hcNoContext,

NewItem('~N~ew','F4',kbF4,cmNewWin,

hcNoContext,

NewLine( NewItem('E~x~it','Alt-X',kbAltX,cmQuit,

hcNoContext,

nil))))),

NewSubMenu('~W~indow',hcNoContext,NewMenu(

NewItem('~N~ext','F6',kbF6,cmNext,

hcNoContext,

NewItem('~Z~oom','F5',kbF5,cmZoom,

hcNoContext, NewItem('~S~ize/Move','Ctr-F5',kbCtrlF5,cmResize,

hcNoContext,

NewItem('~T~ile','',0,cmTile,

hcNoContext,

NewItem('~C~ascade','',0,cmCascade,

hcNoContext,

nil)))))),

nil)))))

end;

procedure TMyApp.NewWindow; var Window: PDemoWindow;

R: TRect; begin

Inc(WinCount);

R.Assign(0,0,30,7);

R.Move(Random(58),Random(16)); Window:=New(PDemoWindow, Init(R,'Demo Window ', WinCount)); Window^.Options:=Window^.Options+ofTileable; DeskTop^.Insert(Window);

end;

procedure TMyApp.HandleEvent(var Event: TEvent); var

R: TRect; begin

TApplication.HandleEvent(Event); if Event.What=evCommand then begin

case Event.Command of cmNewWin: NewWindow; cmTile: