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

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

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

Скроллинг

293

 

 

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))))),

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;

294

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

 

 

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);

end;

cmCascade: begin

DeskTop^.GetExtent(R);

DeskTop^.Cascade(R); end

else Exit; end;

ClearEvent(Event);

end;

end; BEGIN

ReadFile;

MyApp.Init;

MyApp.Run;

MyApp.Done;

DoneFile;

END.

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

1. Как создать в одном окне два разных интерьера?

295

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

ДИАЛОГОВЫЕ ОКНА

Диалоговые окна представляют собой специальный тип окон. Их назначение вывод различного рода сообщений, ввод данных, ус- тановка параметров и т. д. Другими словами, диалоговые окна слу- жат для организации диалога с пользователем. В Turbo Vision диало- говое окно это объект TDialog. Заметим, что Вам не придется по- рождать новый тип объекта от TDialog, как Вы это делали с TWindow. Вместо создания специального типа диалогового окна Вы добавляете «разумность» в программу: вместо создания объекта типа «диалоговое окно», который знает «как себя вести», Вы соз- даете общее диалоговое окно и говорите ему, что оно должно сде- лать.

Для того чтобы использовать окно диалога в Вашей программе, не- обходимовыполнить следующие действия:

подключить модуль Dialogs;

определить константу cmNewDialog, соответствующую команде открытия диалогового окна;

в меню Window добавить новый элемент меню, который гене- рирует команду открытия диалогового окна (связав ее, напри- мер, с клавишей F2);

добавить метод, который знает, как открыть диалоговое окно:

procedure TMyApp.NewDialog; var

Dialog: PDemoDialog; R: TRect;

begin

R.Assign(0, 0, 40, 13); R.Move(Random(39), Random(10));

Dialog := New(PDemoDialog, Init(R, 'Demo Dialog')); DeskTop^.Insert(Dialog);

end;

добавить строку

cmNewDialog: NewDialog;

в метод HandleEvent, чтобы связать команду с действием.

296

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

 

 

Если Вы все сделали правильно, то сможете открыть несколько диалоговых окон и увидеть их отличие от тех окон, которые ис- пользовались ранее:

цвет диалогового окна по умолчанию серый вместо синего;

диалоговое окно не может изменять размер;

диалоговое окно не имеет номера.

Созданное Вами окно является примером диалогового «немодаль- ного» окна, то есть окна без режимов. Однако в большинстве слу- чаев Вам будут нужны модальные окна окна, определяющие ре- жим действия. Если Вы откроете модальное окно, то активным бу- дет только оно. Отметка других окон или меню не вызывает ника- ких действий до тех пор, пока Вы не закроете активное модальное окно (отметим, что клавиша ESC по умолчанию закрывает модаль- ное диалоговое окно).

Для того, чтобы сделать диалоговое окно модальным, нужно изме- нить метод NewDialog:

procedure TMyApp.NewDialog; var

Dialog: PDemoDialog; R: TRect;

C: Word; begin

R.Assign(0, 0, 40, 13); R.Move(Random(39), Random(10));

Dialog := New(PDemoDialog, Init(R, 'Demo Dialog')); C := DeskTop^.ExecView(Dialog);

Dispose(Dialog, Done); end;

Модальное окно уже знает, как реагировать на событие по клавише ESC (которое преобразуется в команду cmCancel) и событие от кла- виши Enter (которое обрабатывается кнопкой по умолчанию TButton). В ответ на команду cmCancel диалоговое окно всегда за- крывается.

Вызов ExecView вставляет диалоговое окно в группу и делает его модальным. Выполнение программы продолжается в ExecView до тех пор, пока диалоговое окно не закроется или не будет удалено. После этого ExecView удаляет окно из группы и осуществляет вы-

Диалоговые окна

297

 

 

ход. Значение, возвращаемое функцией ExecView, сохраняется в пе- ременной С и может быть использовано в дальнейшем.

Проверьте теперь правильность внесения изменений в Вашу про- грамму:

Program TFirst6;

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

FileToRead='e:\tp60\urok.txt'; MaxLines = 100; cmNewWin=199; cmFileOpen=200; cmNewDialog = 201; winCount: Integer = 0;

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

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

type PInterior=^Tinterior;

TInterior=object(TScroller)

constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);

procedure Draw; virtual; end;

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

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

function MakeInterior(Bounds: TRect; Left: Boolean): PInterior; procedure SizeLimits(var Min,Max:TPoint);virtual;

end; type

PDemoDialog = ^TDemoDialog; TDemoDialog = object(TDialog) end;

var

MyApp: TMyApp;

298

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

 

 

S: string; LineCount: Integer;

Lines: array[0..MaxLines - 1] of PString;

procedure TDemoWindow.SizeLimits(var Min,Max:TPoint); var R: TRect;

begin TWindow.SizeLimits(Min,Max); GetExtent(R);

Min.X:=R.B.X div 2; end;

constructor TInterior.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);

begin

TScroller.Init(Bounds, AHScrollBar, AVScrollBar); Options := Options or ofFramed;

SetLimit(128, LineCount); end;

procedure ReadFile; var

F: Text;

S: String; begin LineCount := 0;

Assign(F,FileToRead);

Reset(F);

while not Eof(F) and (LineCount < MaxLines) do begin

Readln(F, S); Lines[LineCount] := NewStr(S); Inc(LineCount);

end;

Close(F);

end;

procedure DoneFile; var

I: Integer; begin

for I := 0 to LineCount - 1 do

if Lines[I] <> nil then DisposeStr(Lines[i]); end;

procedure TInterior.Draw; var

Color: Byte;

I,Y: Integer;

Диалоговые окна

299

 

 

B: TDrawBuffer; begin

Color := GetColor(1);

for Y := 0 to Size.Y - 1 do begin

MoveChar(B, ' ', Color, Size.X); i := Delta.Y + Y;

if (I < LineCount) and (Lines[I] <> nil) then

MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color); WriteLine(0, Y, Size.X, 1, B);

end;

end;

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

var

S: string[3]; R: TRect;

RInterior, LInterior: PInterior; begin

Str(WindowNo, S);

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

R.Assign(Bounds.A.X, Bounds.A.Y, Bounds.B.X div 2 + 1, Bounds.B.Y); LInterior := MakeInterior(R, True);

LInterior^.GrowMode := gfGrowHiY; Insert(Linterior);

R.Assign(Bounds.B.X div 2, Bounds.A.Y, Bounds.B.X, Bounds.B.Y); RInterior := MakeInterior(R,False);

RInterior^.GrowMode := gfGrowHiX + gfGrowHiY; Insert(RInterior);

end;

function TDemoWindow.MakeInterior(Bounds: TRect; Left: Boolean): PInterior;

var

HScrollBar, VScrollBar: PScrollBar; R: TRect;

begin

R.Assign(Bounds.B.X-1, Bounds.A.Y+1, Bounds.B.X, Bounds.B.Y-1); VScrollBar := New(PScrollBar, Init(R));

VScrollBar^.Options := VScrollBar^.Options or ofPostProcess; if Left then VScrollBar^.GrowMode := gfGrowHiY; Insert(VScrollBar);

R.Assign(Bounds.A.X+2, Bounds.B.Y-1, Bounds.B.X-2, Bounds.B.Y); HScrollBar := New(PScrollBar, Init(R));

300

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

 

 

HScrollBar^.Options := HScrollBar^.Options or ofPostProcess; if Left then HScrollBar^.GrowMode := gfGrowHiY + gfGrowLoY; Insert(HScrollBar);

Bounds.Grow(-1,-1);

MakeInterior := New(PInterior, Init(Bounds, HScrollBar, VScrollBar)); 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))))),

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,

Диалоговые окна

301

 

 

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

hcNoContext,

NewItem('~D~ialog', 'F2', kbF2, cmNewDialog, hcNoContext, nil))))))),

nil)))))

end;

procedure TMyApp.NewDialog; var

Dialog: PDemoDialog; R: TRect;

C: Word; begin

R.Assign(0, 0, 40, 13); R.Move(Random(39), Random(10));

Dialog := New(PDemoDialog, Init(R, 'Demo Dialog')); C := DeskTop^.ExecView(Dialog);

Dispose(Dialog, Done); 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; cmNewDialog: NewDialog; cmTile:

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

end;

302

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

 

 

cmCascade: begin

DeskTop^.GetExtent(R);

DeskTop^.Cascade(R); end

else Exit; end;

ClearEvent(Event);

end;

end; BEGIN

ReadFile;

MyApp.Init;

MyApp.Run;

MyApp.Done;

DoneFile;

END.

Управление диалоговыми окнами

Созданное нами диалоговое окно обладает существенным недос- татком оно не несет никакой информации. Чтобы диалоговое ок- но имело смысл, в него нужно добавить элементы управления. Элементы управления это изменяющиеся элементы внутри диа- логового окна, которые позволяют Вам манипулировать информа- цией. Важно помнить, что элементы управления действуют только внутри диалогового окна. Существует только одно исключение из этого правила в случае кнопки в немодальном диалоговом окне. Поскольку кнопки генерируют команды, эти команды будут рас- пространяться от текущего модального видимого элемента. Если же диалоговое окно это немодальный видимый элемент, то его команды могут распространяться за пределы окна, что приводит, как правило, к неожиданным эффектам.

Когда элементы управления установлены в диалоговом окне, появ-

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