лабораторные на Pasca (Кудрявцев)l
.pdfСкроллинг |
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;