менить статусную строку (напомним, что TApplication в этой строке имеет единственную клавишу AltX). Наша первая в Turbo Vision про- грамма будетиметь вид:
program MyFirst1;
uses App,Objects,Menus,Drivers,Views;
{нам понадобятся константы и
const
переменные, определенные в этих модулях}
cmNewWin=199;
{эта константа определяет реакцию на новую команду}
type
TMyApp=Object(TApplication)
{создаем объект-потомок TApplication
procedure InitStatusLine; virtual;
и перекрываем его метод InitStatusLine}
end;
var
MyApp: TMyApp;
procedure TMyApp.InitStatusLine;
{описываем новый метод}
var R:TRect;
{эта переменная хранит границы статусной строки}
begin
GetExtent(R);
{устанавливает 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,
{и еще один}
nil))),
{больше нет клавиш}
nil)))
{больше нет определений}
end;
BEGIN
MyApp.Init;
MyApp.Run;
MyApp.Done;
END.
Запустив программу на выполнение, вы увидите результат: в ста- тусной строке появились две новые команды – New и Close с соот- ветствующими им «горячими» клавишами. Правда, обе пока не от- зываются на их нажатие. Причина этого проста – первую команду мы придумали сами и еще не указали обработчику событий, как на нее реагировать. Вторая же команда, хотя и является внутренней командой Turbo Vision, но пока не активизирована – на это указыва-
{определяем новую команду} {добавляем новый метод (не забудьтевнести изменения в описание TMyApp)}
254
Лабораторная работа № 23
ет бледный цвет надписи – так как по определению команда закры- вает окно, а окон у нас еще нет!
Теперь заполним полосу меню. Она описывается переменной MenuBar, которая инициализируется вложенными вызовами стан- дартных функций NewMenu (новое меню), NewSubMenu (новое подменю), NewItem (новая команда), NewLine (новая разделительная линия).
Создадим сначала простую полосу меню с одним элементом, со- держащим одну команду. Для этого в нашу программу потребуется внести следующие изменения:
const cmFileOpen=200;
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,
nil)),
{больше нет элементов}
nil))))
{больше нет подменю}
end;
Чтобы окончательно разобраться, что к чему в этом фрагменте, дос- таточно запустить MyFirst1 с внесенными изменениями и посмот- реть на результат.
Чтобы добавить второй элемент в меню File, нужно вложить еще одну функцию NewItem:
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,
nil))),
Элементы Turbo Vision
255
nil))))
end;
Для добавления второго меню вкладываем другую функцию New-
SubMenu:
NewSubMenu('~W~indow',hcNoContext,NewMenu(
NewItem('~N~ext','F6',kbF6,cmNext,
hcNoContext,
NewItem('~Z~oom','F5',kbF5,cmZoom,
hcNoContext,
nil))),
nil)))));
Добавим еще разделительную линию в меню File, после чего наша процедура примет окончательный вид:
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,
nil))),
nil)))))
end;
256
Лабораторная работа № 23
Добавим еще в статусную строку команду «F10 Menu» для активи- зации меню с помощью «горячей клавиши», и наша программа примет такой вид:
1.Выполните программу TFirst2 в пошаговом режиме. Обратите внимание на то, как происходит инициализация объекта MyApp.
2.Замените в Вашей программе названия команд меню и статусной стро- ки их русскими эквивалентами. Проверьте, сохранились ли возможно- сти «горячих клавиш».
3.Добавьте новые пункты меню (и подменю) и новые элементы статус- ной строки по Вашему выбору.
258
Лабораторная работа № 24
ОКНА
Как уже отмечалось, окна в Turbo Vision – это видимые объекты, «знающие» правила своего поведения. Они умеют открываться, из- менять размер, перемещаться и закрываться, реагируя на команды с клавиатуры или от мышки. Для того, чтобы что-то появилось в ок- не, мы должны вставить в окно другие видимые элементы, которы- ми и сможет управлять наше окно. Поэтому начать нужно с созда- ния стандартного окна, а затем уже добавлять новые возможности. В нашей программе TFirst2 уже зарезервирована клавиша F4 с соот- ветствующей командой NewWin, которая должна открывать окно. Необходимолишь написать соответствующие процедуры: для ини- циализации окна и для подключения обработки события, возни- кающего при нажатии клавиши F4.
Поскольку мы включаем в нашу программу новый объект, то необ- ходимо внести добавления в раздел описания типов:
Type PDemoWindow=^TDemoWindow; TDemoWindow=object(TWindow)
end;
Кроме того, нам понадобится новая константа WinCount: Integer=0, с помощью которой инициализируется счетчик окон.
Для того, чтобы окно Turbo Vision – его объект TWindow – смогло себя инициализировать, ему необходимо передать три параметра: его размер и положение на экране, заголовок и номер окна. Первый параметр – переменная типа TRect – описывает прямоугольный объект в Turbo Vision. Его метод Assign задает положение верхнего левого угла окна (относительно верхнего левого угла DeskTop) и положение нижнего правого угла окна. Второй параметр – строка (то есть величина типа string) – будет выведен на экран в качестве заголовка окна. Наконец, последний параметр – величина типа integer – задает номер окна. Если он имеет значения от 1 до 9, он
выводится в рамке окна и выбор пронумерованного окна можно осуществлять, нажимая клавиши от Alt+1 до Alt+9. Если Вы не хоти-
Окна
259
те назначать окну номер, передайте процедуре инициализации в ка- честве третьего параметра константу wnNoNumber.
С учетом сказанного процедура создания окна может выглядеть следующим образом:
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));
DeskTop^.Insert(Window);
{выводим окно на панель экрана}
end;
Теперь нужно сделать так, чтобы записанная выше процедура на- чинала свою работу при нажатии соответствующей клавиши (или при выборе пункта меню). Для этого нужно задействовать обработ- чик событий Turbo Vision. Как уже упоминалось, объект TApplication владеет методом HandleEvent и нам нужно расширить его, включив новую команду (не забудьтедобавить новую процедуру в описание
TMyApp):
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;
else
Exit;
end;
ClearEvent(Event);
{очищает событие после обработки}
end;
end;
Внеся перечисленные дополнения в Вашу программу, Вы получае- те возможность открыть любое число окон. Обратите внимание на
260
Лабораторная работа № 24
то, что после открытия окон немедленно активизируются команды Close в статусной строке и Next и Zoom в меню Window. Как уже указывалось, окно, кроме того, умеет перемещаться по экрану и менять свой размер. Если Вы пользуетесь мышкой, то изменить размер окна или передвинуть его можно с ее помощью, ничего не добавляя в код программы. Если же мышки нет, то соответствую- щие возможности появятся лишь после включения стандартной ко- манды Size/Move, которая обычно связывается с клавишей CtrlF+5. Эту команду можно внести в меню Widow:
(напомним, что после выбора команды Size/Move перемещение окна осуществляется курсорными клавишами, а изменение его размера – курсорными клавишами с нажатой клавишей Shift). После всех не- обходимыхизменений Ваша программа примет вид:
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;
else Exit; end;
ClearEvent(Event);
end;
end; BEGIN
MyApp.Init;
MyApp.Run;
MyApp.Done;
END.
Окна, которые создаются в Вашей программе, обладают свойства- ми, установленными по умолчанию для объектов типа TWindow. Для того, чтобы их изменить, необходимо обратиться к полям, ко- торыми располагает этот объект (описание всех объектов можно найти в справке помощи Турбо Паскаля – меню Help). Одно из по- лей TWindows – Options – это переменная типа Word, которая содер- жит флаги, управляющие поведением окон (или других видимых элементов). По умолчанию при создании окна Options установлено в (ofSelectabl + ofTopSelect). Это означает, что окно может быть вы- брано мышкой (или командой Next), и выбранное окно передвига- ется наверх других окон. Изменим поле Options, добавив флаг ofTileable, который позволяет окнам заполнять DeskTop каскадом или мозаикой. Сделать это нужно после того, как окно создано, то есть в процедуру TMyApp.NewWindow после строки, вызывающей процедуру инициализации окна, нужно добавить строку
Window^.Options:=Window^.Options+ofTileable;
Кроме того, добавим соответствующие команды в меню Window