Turbo Vision
ОГЛАВЛЕНИЕ
ВВЕДЕНИЕ ................................................
ОТОБРАЖАЕМЫЕ ОБЪЕКТЫ ....................................
Объект tView ........................................
Группа (tGroup).Z - порядок .........................
Оформление программы, использующей средства Turbo
Vision.Объекты tProgram и tApplication ..............
Обработка событий ...................................
Команды .............................................
ПОРЯДОК РАБОТЫ С ОТОБРАЖАЕМЫМИ ОБЪЕКТАМИ ................
Описание отображаемого объекта ......................
Создание отображаемого объекта ......................
Помещение отображаемого объекта в группу ............
Задание параметров отображаемому объекту ............
Работа с модальными объектами .......................
СОЗДАНИЕ МЕНЮ ...........................................
Создание разворачивающегося меню ....................
Создание локального меню ............................
СОЗДАНИЕ ОКОН И ДИАЛОГОВЫХ ОКОН .........................
Окна в Turbo Vision .................................
Элементы окон в Turbo Vision ........................
Поле скроллинга .....................................
Текстовый элемент буферированной информации .........
Текстовый элемент для пассивного терминала ..........
Линейка скроллинга ..................................
Диалоговое окно .....................................
Элементы диалоговых окон ............................
Строка ввода ........................................
Метка ...............................................
Протокол ............................................
Селективный и триггерный списки .....................
Кнопка ..............................................
Статический и параметрический тексты ................
Списки строк ........................................
Стандартные окна ....................................
СОЗДАНИЕ СТРОК СОСТОЯНИЯ ................................
Строка состояния, отображающая клавиши быстрого
управления ..........................................
ЦВЕТОВАЯ ПАЛИТРА TURBO VISION ...........................
Стандартная палитра .................................
Изменение стандартной палитры .......................
НЕОТОБРАЖАЕМЫЕ ОБЪЕКТЫ TURBO VISION .....................
Анализаторы вводимой информации .....................
Объект - коллекция ..................................
Потоки Turbo Vision .................................
Ресурсы .............................................
Списки строк ........................................
НЕКОТОРЫЕ ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ TURBO VISION .......
Текстовый редактор ..................................
Отображение древовидных структур ....................
Диалоговое окно задания цветной палитры .............
ЗАКЛЮЧЕНИЕ ..............................................
ВВЕДЕНИЕ
Для эффективной работы системы и ее большего покупательского
спроса недостаточно только того, чтобы аппаратура и программы обеспе-
чивали правильные результаты и быструю работу.Не менее важным фактором
является удобство работы пользователя.
Поэтому в настоящее время ни один программный продукт, лишенный
более или менее удобного интерфейса взаимодействия пользователя с
компьютером и программ между собой, не может рассчитывать на успех.
В мире разработано огромное количество различных систем поддержки
создания пользовательского интерфейса.Наиболее прогрессивными, по на-
шему мнению, являются объектноориентированная система Turbo Vision
фирмы Borland International и операционная система Windows фирмы
Microsoft.Рассмотрением возможностей ОС Windows занимался А.А.Галаш-
кин, а в представленной работе производится обзор и изучение особен-
ностей, возможностей, элементов, организации пакета Turbo Vision.
При создании прикладной программы программист большие усилия зат-
рачивает на организацию ввода/вывода информации, т.е. на формирование
интерфейса.Они соизмеримы с усилиями, затрачиваемыми на программирова-
ние основного алгоритма программы, по которому решается конкретная за-
дача.Работа, связанная с организацией ввода/вывода, повторяется от
программы к программе, требует выполнения однотипных операций, отвле-
кает внимание программиста от решения основной задачи.
Хорошим средством упрощения работы по организации ввода/вывода,
его унификации с учетом современных требований к интерфейсу программ
является разработанный фирмой Borland International пакет Turbo
Vision 2.0, представляющий объектно-ориентированную библиотеку средств
формирования пользовательского интерфейса.
Программу можно представить как совокуп-
ность двух частей : часть программы, обеспечивающая решение основной
задачи, и часть, обеспечивающая организацию ввода/вывода информации с
внешних устройств (на внешние устройства), - так называемый интерфейс
программы.В основную часть (из основной части) программы информация
может передаваться двумя способами - непосредственная передача инфор-
мации (например, программа формирует какие-то данные и размещает их в
конкретном файле на магнитном диске) и передача информации с помощью
организации диалога (например, после формирования тех же данных проис-
ходит уточнение, в какой конкретно файл следует поместить сформирован-
ную информацию).Способ, основанный на организации диалога, является
более универсальным и именно для организации диалога предназначен в
первую очередь пакет Turbo Vision.
В современных программах, работающих в текстовом режиме, диалог
обычно организуется с помощью трех средств : меню, диалоговых окон и
строк состояния.Turbo Vision позволяет реализовать все эти средства
диалога.
Turbo Vision представляет собой библиотеку объектов, позволяющих
создать пользовательский интерфейс и широко использующих свойства ин-
капсуляции, наследования и полиформизма.Почти все объекты библиотеки
являются потомками общего абстрактного объекта tObject.Мы рассмотрим
их классификацию, исходя из задач, возникающих при создании интерфейса.
Объект tObject достаточно прост.Он не имеет параметров и обладает
тремя методами, два из которых - конструктор Init :
constructor tObject.Init;
заполняющий выделенную под объект область нулями, и деструктор Done :
destructor tObject.Done;
не выполняющий никаких действий, - должны быть переопределены в его
потомках, а третий метод Free :
procedure tObject.Free;
удаляющий объект из динамической памяти, никогда не переопределяется,
т.к. может удалить любой потомок объекта tObject.
При организации интерфейса приходиться решать две задачи : созда-
ние соответствующего образа на экране и возможность посредством того
образа передачи информации как от пользователя к вычислительной маши-
не, так и от машины к пользователю.Помимо этих двух задач при организа-
ции интерфейса приходиться выполнять различные вспомогательные опера-
ции (вычисления, контроль и преобразование данных, хранение информации
и т.д.).В связи с этим все объекты Turbo Vision можно разбить на две
группы : отображаемые и неотображаемые объекты.
ОТОБРАЖАЕМЫЕ ОБЪЕКТЫ
Отображаемыми объектами являются такие объекты, которые могут
быть изображены на экране.Эти объекты позволяют наглядно представить
пользователю информацию, дать ему средства ввода информации в програм-
му наиболее естественным образом.К таким объектам относятся,в частнос-
ти, меню, строки состояния, диалоговые окна с их компонентами.
Любой отображаемый объект является потомком общего абстрактного
объекта tView, который является непосредственным потомком общего предка
tObject.
Неотображаемыми объектами являются объекты, которые не могут быть
изображены на экране.К этой категории, в частности, относятся объекты,
предназначенные для контроля и хранения данных.Наиболее часто исполь-
зуемыми объектами такого класса являются анализаторы вводимой информа-
ции, коллекции, потоки и ресурсы.
Любой объект Turbo Vision имеет большое количество параметров,
определяющих его свойства и методов (подпрограмм), задающих его пове-
дение.Согласно принципам объектного программирования, желательно пара-
метры объектов не изменять непосредственно, а с помощью соответствую-
щих методов, предназначенных для этой цели.Это связано с тем, что в
ряде случаев только изменение того или иного параметра недостаточно -
следует выполнить дополнительно определенные действия (например, пере-
рисовать объект на экране).В ряде случаев непосредственное изменение
параметров просто недопустимо.Практически для всех параметров объектов
в Turbo Vision указано, допустимо ли его непосредственно изменять (за-
писывать).К сожалению, принцип объектного программирования, требующий
изменения параметров только с помощью того или иного метода, в полной
мере в Turbo Vision не реализован, и приходится в простейших случаях
параметры изменять непосредственно либо писать свои дополнительные ме-
тоды.
Любой отображаемый объект может быть размещен на кране в прямоу-
гольной области, которая задается координатами левого верхнего и пра-
вого нижнего углов.В Turbo Vision координаты задают линии раздела меж-
ду знакоместами, и при этом нумерация по горизонтали и вертикали начи-
нается с нуля (координаты 0,0 - левый верхний угол экрана).Координаты
могут быть абсолютными, отсчитываемыми относительно левого верхнего
угла крана, и относительными, отсчитываемыми от левого верхнего угла
соответствующего окна (так называемого владельца данного отображаемого
объекта).
Для задания координат точки на кране и координат прямоугольной
области используются два объекта - tPoint, содержащий две координаты
точки - X и Y :
type tPoint = object
X, Y : Integer;
end;
и tRect, определяющий левый верхний и правый нижний углы прямоугольной
области.Объект tRect не только содержит соответствующие координаты, но
также обладает методами, позволяющими задавать, изменять, получать эти
координаты и выполнять над ними ряд других операций.
Объект tView
Предком отображаемых объектов является объект tView.Несмотря на
то, что этот объект абстрактный, т.е. нельзя создать конкретный обра-
зец этого типа, он имеет важное значение, т.к. задает общие свойства
всех отображаемых элементов и определяет виртуальные методы, которые
затем переопределяются для конкретных отображаемых объектов.
У объекта tView задаются следующие параметры :
Расположение и размеры объекта.Расположение объекта tView задает-
ся координатами его левого верхнего угла в поле его владельца - пара-
метр Origin, а размеры - параметром Size, задающим его ширину и высо-
ту.Непосредственно изменять эти параметры в программе не следует.Для
их задания нужно использовать методы Locate (одновременное задание
всех координат объекта) :
procedure tView.Locate(var Bounds: tRect);
где Bounds - область, выделяемая под объект в координатах его владель-
ца;
MoveTo (перемещение объекта в поле его владельца без изменения разме-
ров):
procedure tView.MoveTo(X, Y: Integer);
где X, Y - координаты левого верхнего угла объекта в поле его владель-
ца,
и GrowTo (изменение размеров объекта):
procedure tView.GrowTo(X, Y: Integer);
где X, Y - горизонтальный и вертикальный размеры объекта.
При изменении размеров объекта с помощью метода GrowTo остается
на месте левый верхний угол объекта.
Координаты курсора.Ряд отображаемых объектов, таких, как строка
ввода текстовой информации, редакторы и т.д., могут иметь видимый кур-
сор.Координаты этого курсора задаются параметром Cursor.Для объектов,
не имеющих видимого курсора, значение этого параметра безразлично.За-
дать координаты курсора можно с помощью метода SetCursor :
procedure tView.SetCursor(X, Y: Integer);
где X, Y - координаты курсора в поле объекта.
Курсор отображаемого элемента можно сделать видимым и невидимым
(параметр sfCursorVis флагов состояния), а также изменять его размеры
(параметр sfCursorIns).
Флаги свойств.Параметр Options размером в одно 16-разрядное слово
задает ряд свойств отображаемого объекта.Назначение битов этого слова
следующее (в круглых скобках приведены константы, соответствующие еди-
нице в указанном бите) :
0-й бит (ofSelectable) - возможность активизации (выделения) данного
объекта в его владельце либо с помощью мыши,
либо с помощью клавиши табуляции.Это свойство
используется у любого объекта, и обычно флаг
задается равным единице.
1-ый бит (ofTopSelect) - возможность размещения объекта при его акти-
визации (выделении) сверху всех остальных
объектов конкретной группы.Это свойство ис-
пользуется у окон (тип tWindow) и их потомков
- диалоговых окон, стандартных диалоговых
окон и т.д.
2-ой бит (ofFirstClick) - возможность использования первого нажатия
клавиши не только для выделения объекта (бит
0), но и для выполнения действий, которые
активизируются данным объектом.Свойство ис-
пользуется практически у всех отображаемых
объектов.
3-ий бит (ofFramed) - наличие рамки вокруг отображаемого объекта.Это
свойство используется для подэлементов окон.Не
следует этот флаг путать с наличием рамки окна
(tWindow) и его потомков.
4-ый бит (ofPreProcess) - опережающая реакция на событие.Задание флага
приводит к изменению стандартной последова-
тельности реакции отображаемых элементов
группы на событие.Свойство может использо-
ваться у любого элемента по мере необходимос-
ти.
5-ый бит (ofPostProcess) - запаздывающая реакция на событие.Аналогично
предыдущему флагу, но с другими последстви-
ями его использования.
6-ой бит (ofBuffered) - наличие КЭШ-буфера у отображаемого объекта,
когда образ отображаемого объекта не создается
каждый раз заново при его прорисовке на экране,
а хранится в специальном КЭШ-буфере.Флаг важен
для сложных составных объектов типа окна и его
потомков.
7-ой бит (ofTileable) - расположение отображаемых объектов встык или
каскадно (с наложением).Этот флаг использу-
ется только у окон и их потомков.
8-ой бит (ofCenterX) - центрирование объекта по горизонтали.При зада-
нии этого флага объект при его первоначальной
прорисовке центрируется относительно верти-
кальной оси его владельца.Флаг может использо-
ваться у элементов, входящих в группу элемен-
тов.
9-ый бит (ofCenterY) - центрирование объекта по вертикали.Аналогично
предыдущему флагу, но только объект центриру-
ется относительно горизонтальной оси его вла-
дельца.
10-ый бит (ofValidate) - задается проверка правильности введенной в
объект информации при выходе из этого объек-
та (активизации другого объекта).Флаг ис-
пользуется только со строками ввода.
11-ый бит (ofVersion20) - используется Turbo Vision 2.0.Ряд объектов
(как, например, строка ввода) имеют принци-
пиальные отличия в зависимости от версии
Turbo Vision.Версия 2.0 имеет дополнительные
возможности по сравнению с версией 1.0.
12-ый бит (ofVersion10) - используется Turbo Vision 1.0.
Остальные биты слова флагов свойств не используются.Для задания
флагов свойств можно использовать константу ofCentred=$0300 (одновре-
менное центрирование по горизонтали и вертикали), с помощью которой
можно одновременно установить 8 и 9 биты параметра Options.Имеется
константа ofVersion=$3000, позволяющая выделить биты, связанные с вер-
сией Turbo Vision.
Флаги перемещения.Параметр DragMode размером в один байт задает
характеристики отображаемого объекта при его перемещении :
0-й бит (dmDragMove) - разрешение перемещения объекта либо с помощью
мыши, либо с помощью клавиш направления. Используется у тех
объектов, которые по тем или иным причинам могут перемещаться
в поле своего владельца, например у окон и их потомков.
1-й бит (dmDragGrow) - разрешение изменения размеров объекта либо с
помощью мыши, либо с помощью клавиш направления.Используется
у окон и их потомков.
4-й бит (dmLimitLoX) - запрещение левой стороне отображаемого объекта
выходить за заданные границы.В качестве таких границ часто
выступают размеры владельца данного объекта (например, разме-
ры рабочего поля, в котором размещены окна).
5-й бит (dmLimitLoY) - аналогично 4 биту, но запрещение верхней сторо-
не отображаемого объекта выходить за заданные границы.
6-й бит (dmLimitHiX) - аналогично 4 биту, но запрещение правой стороне
отображаемого объекта выходить за заданные границы.
7-й бит (dmLimitHiY) - аналогично 4 биту, но запрещение нижней стороне
отображаемого объекта выходить за заданные границы.
Остальные биты параметра DragMode не используются.Для одновремен-
ного задания ограничений на перемещение во всех направлениях можно ис-
пользовать константу dmLimitAll=$FO, устанавливающую в единицу биты с
4 по 7.
Флаги изменения размеров.Параметр GrowMode размером в один байт
задает свойства отображаемого объекта при попытке изменения размеров
его владельца с помощью мыши или клавиш направления.
0-й бит (gfGrowLoX) - левая сторона отображаемого объекта остается на
одном и том же расстоянии от правой стороны его владельца при
изменении размеров владельца.
1-й бит (gfGrowLoY) - верхняя сторона отображаемого объекта остается
на одном и том же расстоянии от правой стороны его владельца
при изменении размеров владельца.
2-й бит (gfGrowHiX) - правая сторона отображаемого объекта остается на
одном и том же расстоянии от правой стороны его владельца при
изменении размеров владельца.
3-й бит (gfGrowHiY) - нижняя сторона отображаемого объекта остается на
одном и том же расстоянии от нижней стороны его владельца при
изменении размеров владельца.
4-й бит (gfGrowRel) - отображаемый объект изменяет свои размеры про-
порционально размерам владельца.Такой режим может потребовать-
ся при отображении окна в случае изменения режима адаптера с
25 строк на 43/50 строк и наоборот.
Остальные биты параметра GrowMode не используются Для одновремен-
ной фиксации сторон отображаемого объекта относительно размеров его
владельца можно использовать константу gfGrowAll=$OF, устанавливающую
в единицу биты с 0 по 3.
Флаги обработки событий.Параметр EventMask размером в одно слово
определяет, какие события может обрабатывать данный отображаемый объ-
ект.
Флаги состояния.Параметр State размером в одно слово определяет
текущее состояние данного отображаемого объекта.Как правило, изменение
этого параметра происходит автоматически в процессе выполнения прог-
раммы (например, выделенное состояние объекта), и не следует без осо-
бых причин менять его в программе.Если же все-таки потребуется произ-
вести те или иные изменения, их необходимо производить с помощью соот-
ветствующих методов, специально для этого предназначенных.
Отдельные биты параметра имеют следующее значение :
0-й бит (sfVisibl) - объект может быть видим в поле своего владель-
ца.Если этот флаг установлен (такое состояние задается авто-
матически при создании объекта), объект будет видим полностью
или частично, если только он не закрывается другими отобража-
емыми объектами, а его владелец сам виден на кране.Для зада-
ния этого флага используется метод Show :
procedure tView.Show;
Для сброса - метод Hide :
procedure tView.Hide;
Чтобы определить, виден ли на самом деле объект, можно вос-
пользоваться методом Exposed :
function tView.Exposed: Boolean;
где результат - True, если какая-либо часть объекта видна на
экране.
1-й бит (sfCursorVis) - курсор объекта видим в поле объекта.У некото-
рых отображаемых объектов курсор задается видимым (например, у
строки ввода), у других - невидимым (например, у статическо-
го текста).Чтобы изменить заданное состояние и сделать курсор
видимым, следует воспользоваться методом ShowCursor :
procedure tView.ShowCursor;
чтобы сделать его невидимым, используется метод HideCursor :
procedure tView.HideCursor;
2-й бит (sfCursorIns) - увеличенный размер курсора.Для задания курсора
увеличенного размера воспользуемся методом BlockCursor :
procedure tView.BlockCursor;
для задания нормального размера курсора (такой размер задается
автоматически при создании объекта) используется метод
NormalCursor :
procedure tView.NormalCursor;
3-й бит (sfShadow) - объект имеет тень.При создании одних объектов
(например, окон) задается тень, у других объектов (например,
списков) тень не задается.Если требуется изменить заданное
состояние этого флага, следует воспользоваться универсальным
методом SetState :
procedure tView.SetState(AState: Word; Enable: Boolean);virtual;
где AState - флаг, который следует изменитьЖ
Enable=True, если флаг следует установить, и False, если
сбросить.
С помощью этого метода можно изменить любые флаги состояния,
но при каждом обращении к нему можно изменить только один
флаг.
4-й бит (sfActiv) - объект является либо активным окном ( окном, с ко-
торым происходит в настоящее время работа в программе), или
подэлементом активного окна.Как правило, этот флаг автомати-
чески меняет свое значение в процессе работы программы и изме-
нять его в программе практически не требуется.
5-й бит (sfSelected) - объект является выделенным в группе.В каждой
группе может быть только один выделенный объект.Как и предыду-
щий флаг, состояние этого флага изменяется автоматически в
процессе работы программы, и обычно не возникает необходимости
принудительного изменения его состояния (изменить его также
можно с помощью метода SetState).
6-й бит (sfFocused) - объект является сфокусированным, т.е.является
выделенным в группе, и все его владельцы также являются выде-
ленными.Сфокусированный объект - то тот отображаемый объект,
с которым в настоящее время происходит работа (например,
конкретный редактор текста, если на экране открыто несколько
редакторов).
7-й бит (sfDragging) - объект находится в режиме перемещения или изме-
нения своих размеров либо с помощью клавиш направления, либо с
помощью мыши.Обычно этот флаг используется у окон и устанавли-
вается у окна при переходе его в такой режим, а сбрасывается
при выходе из этого режима.Принудительное изменение флага воз-
можно с помощью метода SetState.
8-й бит (sfDisabled) - объект является "запрещенным", т.е. не реагиру-
ющим ни на какие воздействия.Задать этот флаг можно также с
помощью метода SetState.
9-й бит (sfModal) - объект является модальным.Этот флаг характерен для
окон и устанавливается, если окно находится в модальном режиме
(использование метода ExecView или ExecuteDialog).Принудительно
изменять этот флаг не следует.
10-й бит (sfExposed) - объект имеет в качестве окончательного владель-
ца объект tApplication, т.е. имеет возможность отражаться
на экране (не путать с флагом ofVisible).Принудительно изме-
нять флаг не следует.
Остальные биты параметра State не используются.
Контекстная помощь.Этот параметр (HelpCtx) представляет собой
число типа Word, который задает значение параметра контекстной помощи
в случае, если отображаемый объект является сфокусированным.Этот пара-
метр используется в справочной системе и в системе строк состояния.Ес-
ли контекстная помощь не нужна, этот параметр следует задать равным
нулю (константа hcNoContex).Это же значение принимает параметр и при
создании объекта.
Следующий отображаемый элемент.Этот параметр (Next) содержит ука-
затель на следующий объект в группе, в которую входит данный объ-
ект.Параметр устанавливается автоматически при включении объекта в
группу.Принудительно менять значение этого параметра не следует.
Владелец объекта.Параметр (Owner) представляет собой указатель на
владельца объекта - группу, в которой расположен данный объект.Пара-
метр устанавливается автоматически при размещении объекта в группе -
обычно с помощью метода Insert объекта tGroup или другого метода,
включающего в себя метод Insert, и изменять его принудительно не сле-
дует.
Объект tView обладает 67 методами плюс 1 метод, унаследованный от
объекта tObject.Многие из этих методов являются виртуальными и переоп-
ределяются для потомков.Все методы можно условно разбить на несколько
групп.
К первой группе можно отнести методы, с помощью которых создается
или уничтожается объект.Здесь следует отметить два конструктора-Init,
с помощью которого инициализируется новый объект, и Load, с помощью
которого объект загружается из потока, а также деструктор Done, выпол-
няющий действия, обратные действиям конструктора Init.
Ко второй, самой многочисленной группе, можно отнести методы, с
помощью которых либо задаются, либо определяются текущие параметры
объекта (задание и получение указанных выше параметров).
К третьей группе можно отнести методы, позволяющие поместить объ-
ект в группу, отобразить его на экране, удалить из группы, удалить с
экрана.
К четвертой группе относятся методы обработки событий, наиболее
часто используемым из которых является метод HandlEvent, обрабатываю-
щий текущее событие.
Наконец, к пятой группе отнесем все остальные методы, выполняющие
разнообразные дополнительные действия (например, получение палитры
цветов для объекта, разрешение и запрещение выполнения команд и т.д.)
Группа (tGroup).Z-порядок
В общем случае отображаемый объект может иметь достаточно сложную
структуру и включать в себя другие видимые элементы в качестве своих
подэлементов.Эти подэлементы, в свою очередь, могут включать в себя
другие подэлементы и т.д.
Совокупность объединенных отображаемых объектов представляет со-
бой группу (тип tGroup) и может рассматриваться как нечто единое,
предназначенное для использования в программе.Так же как и объект
tView, объект tGroup является абстрактным объектом и не может иметь
конкретные образцы в программе, однако является родоначальником целого
ряда реальных объектов (в первую очередь различных окон) и определяет
основные свойства таких объектов как некоего целого.Сам объект tGroup
является потомком объекта tView и наследует или переопределяет его па-
раметры и методы.
Любой объект типа tGroup представляет собой основной элемент
группы (например, диалоговое окно), называемый владельцем элементов
группы, в который включено то или иное количество подэлементов (напри-
мер, различные элементы управления диалогового окна).Параметры, насле-
дуемые группой от объекта tView, относятся к основному объекту группы
- владельцу группы; отдельные подэлементы, также являющиеся потомками
объекта tView, обладают своими характеристиками, часто не совпадающими
с характеристиками их владельца.
В дополнение к параметрам tView объект tGroup имеет ряд собствен-
ных параметров, наиболее важными и часто используемыми из которых яв-
ляются два.Первый параметр Last, указывающий на последний подэлемент
группы (фактически он является первым включенным в группу подэлемен-
тов).Вторым является параметр Current, указывающий на текущий выделен-
ный подэлемент.Если группа не имеет ни одного подэлемента, эти два па-
раметра равны nil.
Основной элемент группы инициализируется конструктором Init :
constructor tGroup.Init(var Bounds: tRect);
где Bounds - размеры объекта.
Если после инициализации группа помещается в другую группу, уста-
навливаются соответствующие значения параметров Next и Owner.
Любой подэлемент группы должен быть включен в эту группу с по-
мощью метода Insert :
procedure tGroup.Insert(P: pView);
где P - размещаемый объект, или другого метода, включающего в себя ме-
тод Insert и может быть из нее исключен с помощью метода Delete :
procedure tGroup.Delete(P: pView);
где P - исключаемый объект, или какого-либо другого метода, включающе-
го в себя метод Delete.
Последовательность включения подэлементов в группу очень важна,
т.к. от нее зависит порядок работы с подэлементами.Следует начинать
расположение подэлементов с левой верхней части основного элемента и
далее идти вправо и вниз.
Включенные в группу подэлементы образуют так называемый Z-поря-
док, и среди них можно выделить первый, последний и промежуточные эле-
менты.
┌───────────────────────────────────┐
│ Основной элемент (владелец) │
└────────────────┬──────────────────┘
│
┌────────────────┴──────────────────┐
│ Последний элемент (Last) │───────────────┐
└────────────────┬──────────────────┘ │
│ <───── Insert │
┌────────────────┴──────────────────┐ │
│ Предпоследний элемент │ │
└────────────────┬──────────────────┘ │
│ │
... │
│
│ │
┌────────────────┴──────────────────┐ │
│ Второй элемент │ │
└────────────────┬──────────────────┘ │
│ <───── InsertBefore │
┌────────────────┴──────────────────┐ │
│ Первый элемент │ │
└────────────────┬──────────────────┘ │
│ │
│ │
└──────────────────────────────────┘
Рис. 1. Структура группы
У каждого отображаемого объекта есть поле Next, указывающее на
следующий подэлемент группы.Поле Next последнего подэлемента указывает
на предыдущий подэлемент, поле Next предыдущего подэлемента указывает
на его предыдущий подэлемент и т.д.У первого подэлемента это поле ука-
зывает на последний подэлемент группы.Таким образом, все подэлементы
группы образуют циклическую структуру.У каждого подэлемента группы по-
ле Owner (владелец) указывает на основной элемент группы.
Поля, указывающего на предыдущий подэлемент в группе у отображае-
мого объекта нет, однако у него есть метод Prev, который формирует
указатель на такой предыдущий подэлемент.Этот метод даст указатель на
первый подэлемент, если определяется предыдущий подэлемент последнего
подэлемента.
Оформление программы, использующей средства Turbo Vision.
Объекты tProgram И tApplication
В Turbo Vision имеются два объекта - tProgram и tApplication, на
основе которых можно создать интерактивную программу.
Объект tProgram является основой создаваемой программы и включает
общие действия, которые выполняются практически в любой интерактивной
программе.В первую очередь это обработка поступающих событий.tProgram
представляет собой отображаемый объект, занимающий все поле экрана.Он
является непосредственным потомком объекта tGroup и наследует все его
свойства.В частности, это позволяет в поле экрана разместить любые
отображаемые объекты.В свою очередь, этот объект имеет свои характер-
ные свойства, которые позволяют создать программу как нечто целое.
Инициализируется объект tProgram конструктором Init :
constructor tProgram.Init;
После инициализации устанавливаются значения парамет-
ров.ScreenWidth и ScreenHeight - параметры модуля Drivers, содержащие
размеры экрана в текстовом режиме.Параметр DeskTop (модуль App) - ука-
затель на рабочую область программы.Указатель на созданный объект
tProgram помещается в переменную Application (модуль App).
Важным методом объекта tProgram является метод Run :
procedure tProgram.Run; virtual;
представляющий собой цикл обработки событий и выполняющий, таким обра-
зом, основные действия, связанные с работой программы.
Объект tProgram позволяет разместить в поле экрана любые отобра-
жаемые объекты.Их можно помещать в поле экрана произвольным образом,
однако принята следующая система их расположения : в верхней строке
экрана размещается строка меню (тип tMenuBar или его потомок), в ниж-
ней части экрана размещается строка состояния (тип tStatusLine или его
потомок), остальная часть экрана отдается под рабочую область (тип
DeskTop или его потомок).Эти три объекта (tMenuBar, tStatusLine и
tDeskTop) также являются отображаемыми объектами, причем объект
tDeskTop является к тому же потомком объекта tGoup.
Объекты этих типов размещаются на экране автоматически при иници-
ализации программы методом Init.Для размещения меню, строки состояния
и рабочей области вызываются методы InitMenuBar, InitDeskTop и
InitStatusLine.Методы InitMenuBar и InitStatusLine переопределяются,
метод же InitDeskTop обычно не меняется (его следует переопределить,
если у программы нет меню или строки состояния, с тем, чтобы соответс-
твующим образом изменить его размеры).
Рабочая область инициализируется конструктором Init :
constructor tDeskTop.Init((var Bounds: tRect);
где Bounds - размеры рабочей области.
Объект tApplication является непосредственным потомком объекта
tProgram и наследует все его свойства.Кроме этого, он предназначен для
создания оболочки программы, включающей систему управления памятью,
видеосистему, систему обработки событий и т.д., которые могут быть
инициализированы с помощью конструктора Init этого объекта :
constructor tApplication.Init;
а ликвидированы с помощью деструктора Done :
destructor tApplication.Done; virtual;
При инициализации этого объекта его параметры принимают те же
значения, что и у его предка tProgram.
Сформированная на основе объекта tApplication программа обычно
выполняет последовательно три операции : инициализацию программы, об-
работку событий и завершение работы программы.
Инициализация программы, если не требуется каких-либо специальных
дополнительных действий, представляет собой простое обращение к конс-
труктору Init объекта tApplication (или его потомка), который инициа-
лизирует оболочку программы, после чего обращается к конструктору объ-
екта tProgram, который, в свою очередь, выполняет действия, связанные
с инициализацией программы как таковой, устанавливая исходные значения
ее параметров и размещая на экране меню, строку состояния и рабочую
область.
Обработка событий осуществляется методом Run объекта tProgram
(этот метод доступен и объекту tApplication или его потомку).
Завершение работы программы выполняет деструктор Done.
Обычно тело любой программы и состоит из обращения к этим трем
методам.
СТРУКТУРА ОТОБРАЖАЕМЫХ ОБЪЕКТОВ ПРОГРАММЫ
Все отображаемые объекты образуют древовидную структуру, корнем
которой является сама программа - потомок объекта tApplication (напри-
мер, рис. 2).
┌──────────────────────┐
│──────────────────────│
│ Программа │
└───────────┬──────────┘
│
┌────────────────────────┴───────────────────────┐
│ │ │
┌─────────────────┐ ┌───────────┴──────────┐ ┌─────────────────┐
│ Меню │ │──────────────────────│ │Строка состояния │
└─────────────────┘ │ Рабочая область │ └─────────────────┘
└───────────┬──────────┘
│
┌────────────└────────────┐
│ │
┌────────┴────────┐ ┌───────────┴─────────┐
│ Окно │ │─────────────────────│
└────────┬────────┘ │ Диалоговое окно │
│ └─────────┬───────────┘
┌───────────┘───┐ │
│ │ ┌─────┴─────────┐
│ │ │ │ │
┌─────┴────┐ ┌───────┴──┐ ┌─────┴────┐│┌────────┴──────────┐
│ Рамка │ │ Кнопка │ │ Рамка │││───────────────────│
└──────────┘ └──────────┘ └──────────┘││ Строка ввода │
│└───────────────────┘
┌─────└───────┐
│ │
┌─────┴────┐ ┌─────┴──────┐
│ Кнопка │ │Строка ввода│
└──────────┘ └────────────┘
Рис.2 Пример структуры отображаемых объектов программы
Здесь основным отображаемым объектом является программа - потомок
tApplication.Он является группой, в которую входят меню (потомок
tMenuBar), рабочая область (тип tDeskTop) и строка состояния (потомок
tStatusLine).Рабочая область, в свою очередь, является группой, в ко-
торую входят окно и диалоговое окно.Окно и диалоговое окно также явля-
ются группами, включающими различные подэлементы (рамки, строки ввода,
кнопки).
Каждый отображаемый объект может быть в одном из двух состояний -
пассивном и выделенном.На рис. выделенные объекты обозначены двойной
верхней чертой.В каждой группе может быть только один выделенный объ-
ект (или ни одного, если сама группа не является выделенным объек-
том).Указатель на выделенный элемент находится в переменной Current
объекта-группы.Если какой-то объект группы становится выделенным, пре-
дыдущий выделенный объект этой группы становится пассивным.
Сделать выделенным предыдущий или последующий объект группы можно
с помощью метода SelectNext :
procedure tGroup.SelectNext(Forwards: Boolean);
где Forwards - параметр, определяющий, какой объект следует выделить :
если Forwards = True, выделяется следующий в Z-порядке объект группы.
Этот метод не проверяет правильность введенных данных в текущем
выделенном объекте и всегда выделяет другой элемент.Если необходимо
проверять правильность введенных данных, следует вместо этого метода
использовать метод FocusNext :
function tGroup.FocusNext(Forwards: Boolean): Boolean;
где Forwards - тот же параметр; результат - True, если произошло пе-
реключение на другой объект, и False - в противном случае.
Выделенный объект - это тот объект, с которым в настоящее время
происходит работа.Так, в рассматриваемом примере выделенной является
рабочая область - с окнами, расположенными в ней, пользователь может
взаимодействовать.Меню и строка состояния в этом случае являются пас-
сивными.Если выделить меню, то рабочая область становится пассивной,и
уже не будет возможности работать с окнами рабочей области до тех пор,
пока рабочая область опять не станет выделенной.
Выделенные объекты образуют цепочку выделенных объектов (в нашем
примере : программа - рабочая область - диалоговое окно - строка вво-
да).Последний объект такой цепочки называется сфокусированным объек-
том.В нашем примере это строка ввода - именно в эту строку ввода будут
помещаться набираемые на клавиатуре символы.На экране сфокусированный
объект обычно выделяется особым цветом (или он весь изменяет цвет, или
его отдельные детали).В некоторых случаях у него меняются отдельные
детали, так у окна изменяется вид рамки вокруг этого окна.
Если выделенным объектом является окно или его потомок, то такой
объект и его подэлементы называются активными.
Отображаемые объекты могут находиться в одном из двух режимов :
обычном и модальном.Тип режима задается способом размещения объекта в
группе.Если объект является модальным, то все события, возникающие в
программе, обрабатываются только этим объектом и его подэлементами.В
рассматриваемом примере если диалоговое окно находится в модальном ре-
жиме, то все события будут поступать ему и его подэлементам - рамке,
строке ввода и кнопке.Наличие модального объекта приводит к тому, что
нельзя выйти за пределы этого объекта и его подэлементов без снятия
режима модальности (как правило, для этого требуется удалить модальный
объект из группы, в которой он находится).Строка состояния позволяет в
ряде случаев работу с ней и при наличии модального объекта.
Сама программа как отображаемый объект является модальным объек-
том.
Обработка событий
При использовании объектно-ориентированного программирования все
объекты являются в некотором смысле обособленными друг от друга и воз-
никают определенные трудности в передаче информации от объекта к объ-
екту.Тем не менее невозможно представить себе программу, где не осу-
ществлялся обмен информацией между ее отдельными частями.Для того,
чтобы осуществить такую передачу информации между объектами, должен
использоваться тот или иной механизм.В Turbo Vision таким механизмом
является механизм обработки событий.При таком способе любая передавае-
мая информация оформляется в виде так называемого события, представля-
ющего с точки зрения языка Паскаль запись, отдельные слова поля кото-
рой характеризуют те или иные свойства передаваемой информации.Тип
этой записи - tEvent :
type
tEvent = record
What: Word;
case Word of
evNothing: ();
EvMouse: (
Buttons: Byte;
Double: Boolean;
Where: tPoint);
evKeyDown: (
case Integer of
0: (KeyCode: Word);
1: (CharCode: Char;
ScanCode: Byte));
end;
evMessage: (
Command: Word;
case Word of
0: (InfoPrt: Pointer);
1: (InfoLong: Longint);
2: (InfoWord: Word);
3: (InfoInt: Integer);
4: (InfoByte: Byte);
5: (InfoChar: Char);
end;
end;
end;
Запись tEvent состоит из двух частей.Первая часть задает тип со-
бытия (What), определяющий в первую очередь источник данного собы-
тия.Под этот параметр выделяется 16-ти разрядное слово.Отдельные биты
этого слова имеют следующие значения (в скобках - имя константы, имею-
щей единицу в соответствующем разряде слова) :
0-й бит (evMouseDown) - нажата клавиша мыши.
1-й бит (evMouseUp) - отпущена клавиша мыши.
2-й бит (evMouseMove) - мышь перемещена по поверхности.
3-й бит (evMouseAuto) - автоимпульсы от мыши при длительном нажа-
тии клавиши.
4-й бит (evKeyDown) - нажата клавиша клавиатуры.
8-й бит (evCommand) - событие-команда.
9-й бит (evBroadcast) - событие-сообщение.
События-команды и события-сообщения формируются теми или иными
объектами программы для передачи информации другим объектам.Основное
отличие их друг от друга заключается в механизме их обработки.
Помимо указанных констант в Turbo Vision используются константы,
соответствующие группам бит и определяющих источник создания собы-
тия :
evNothing = $0000 - обработанное событие;
evMouse = $000F - событие от мыши;
evKeyboard = $0010 - событие от клавиатуры;
evMessage = $FF00 - событие от объекта (команда или сообщение).
Вторая часть записи tEvent задает информацию, передаваемую с со-
бытием.
Параметры события от мыши.
Buttons (1 байт).Если единица записана в нулевом бите, то событие
поступило от левой клавиши.Если единица в первом бите - была нажата
правая клавиша.
Параметр Double типа Boolean (1 байт) принимает значение True,
если от мыши поступила информация о двойном нажатии, и False - в про-
тивном случае.
Параметр Where типа tPoint (два 16-ти разр.слова) дает текущие
глобальные координаты курсора мыши.
Для событий от клавиш клавиатуры задается информация о нажатой
клавише (либо как 16-ти разрядный код клавиши (KeyCode), либо как со-
вокупность 8-ми разрядного ASCII-кода символа (CharCode) и 8-ми раз-
рядного скэн-кода (ScanCode) - фактически порядкового номера клавиши.
Параметры событий от объектов.
Параметр Command типа Word, задающий код команды, которую необхо-
димо выполнить при появлении данного события.
Второй параметр определяет передаваемую с событием информацию.На-
иболее распространенный вариант - передача указателя (InfoPtr типа
Pointer) на область нахождения информации.Для небольших объемов :
длинное целое (InfoLong типа Longint), беззнаковое целое (InfoWord ти-
па Word), знаковое целое (InfoInt типа Integer), байт (InfoByte типа
Byte), символ (InfoChar типа Char) - предусмотрена их непосредственная
передача.
Обработка события всегда начинается с текущего модального объек-
та, после чего, если необходимо, оно передается подэлементам этого мо-
дального объекта.Если единственный модальный объект - сама программа,
обработка начинается с него.
В зависимости от последовательности обработки событий объектами
все события можно разбить на три группы.
1 группа включает все события от мыши.Эти события воздействуют в
зависимости от координат курсора мыши.Модальный объект, воспринявший
такое событие, передает его своим подэлементам в Z-порядке, отыскивая
подэлемент, в который попадает курсор мыши.Этот подэлемент, если он
существует и является группой, в свою очередь, также передает это со-
бытие своим подэлементам в Z-порядке и т.д., пока этот поиск не оста-
новится из-за отсутствия соответствующего подходящего подэлемента.Если
соответствующий объект найден, то он будет обрабатывать событие, в
противном случае событие обрабатываться не будет.
2 группа предназначена для сфокусированного объекта и включает
события от клавиш клавиатуры и команды.Эти события передаются по це-
почке выделенных объектов непосредственно сфокусированному объекту.Ес-
ли сфокусированный объект "не знает", как обработать соответствующее
событие, то оно передается назад по цепочке выделенных объектов к мо-
дальному объекту.
3 группа включает события-сообщения (стандартные и создаваемые
пользователем).Эти события передаются всем подэлементам модального
объекта в Z-порядке.Те, в свою очередь, передают их своим подэлементам
в Z-порядке и т.д. до тех пор, пока это событие не будет обработано
каким-либо объектом или же не будут просмотрены все объекты.
При обработке события сначала выполняются соответствующие дейс-
твия у объекта, которому предназначено событие, после чего событие
"очищается" стандартным методом ClearEvent :
procedure tView.ClearEvent(var Event: tEvent);
где Event - текущее "очищаемое" событие.Если событие не "очистить", то
оно будет передаваться и дальше в соответствии с механизмом его обра-
ботки и может быть обработано еще каким-либо объектом.
Команды
События от объектов (команды или сообщения) имеют в качестве од-
ного из параметров параметр Command типа Word, задающий код команды,
которую необходимо выполнить при обработке этого события.
Все используемые в Turbo Vision команды делятся на 4 группы :
- команды, зарезервированные за системой и которые можно маскиро-
вать методом DisableCommands объекта tView и демаскировать методом
EnablеCommands объекта tView, - коды от 0 до 99;
- команды, которые может вводить программист и которые можно мас-
кировать и демаскировать аналогично первой группе, - кода от 100 до
225;
- команды, зарезервированные за системой, но которые нельзя мас-
кировать и демаскировать, как команды первой группы, - коды от 256 до
999;
- команды, которые может вводить программист, но которые нельзя
маскировать и демаскировать, - коды от 1000 до 65535.
Программист может использовать зарезервированные за Turbo Vision
команды, не переопределяя их.Более того, команды этой категории имеют
стандартные названия, и средства пакета стандартным образом реагируют
на них.Так, например, команда cmClose вызывает закрытие активного ок-
на, а cmMenu - активизирует меню и т.д.Все стандартные команды начина-
ются с префикса cm.
ПОРЯДОК РАБОТЫ С ОТОБРАЖАЕМЫМИ ОБЪЕКТАМИ
Работа с отображаемыми объектами осуществляется в несколько эта-
пов, выполняемых в определенной последовательности.На этих этапах
отображаемый объект описывается, создается, помещается в соответствую-
щую группу, задаются его параметры, производится работа с объектом,
получаются введенные параметры, наконец, объект удаляется.
Описание отображаемого объекта
Если отображаемый объект не является стандартным, его следует
описать - ввести необходимые параметры и методы на основе правил объ-
ектного программирования.Методы могут быть 4-х видов : конструкторы,
деструкторы, переопределенные методы предка и специфические методы для
данного объекта.
Конструктор позволяет инициализировать отображаемый объект : за-
дать исходные параметры, создать его подэлементы и т.д.Кроме того, он
создает таблицу виртуальных методов, без которой нельзя будет обра-
титься к этим методам.
Деструктор выполняет действия, обратные действиям конструктора, и
используется при удалении отображаемого объекта, имеющего виртуальные
методы.Сам деструктор также является виртуальным.
Переопределенный метод предка позволяет, используя возможности
исходного метода, модифицировать их, добавить в них некоторые дополни-
тельные свойства, специфические для данного объекта.Переопределенный
метод должен быть виртуальным.
Специфический для данного объекта метод - это метод, который не
имеет аналогов у предка данного объекта.
Создание отображаемого объекта
Если отображаемый объект не размещен постоянно в сегменте данных
(не задана соответствующая переменная конкретного типа-объекта), необ-
ходимо создать соответствующий объект.Модальные объекты, как правило,
не размещаются постоянно в сегменте данных и создаются только на время
работы с ними; немодальные объекты могут и одного, и другого вида, но
чаще все-таки также не размещаются постоянно в сегменте данных.Созда-
ется объект с помощью стандартной подпрограммы New, использующей конс-
труктор Init.
Помещение отображаемого объекта в группу
После создания отображаемого объекта его следует поместить в со-
ответствующую группу : если он является элементом окна, то в соответс-
твующее окно, если же он сам является окном, то в рабочую область
DeskTop.
У каждого объекта-группы имеются методы Insert и InsertBefore, с
помощью которых можно поместить немодальный отображаемый объект в
группу.
Для размещения немодального окна в рабочей области вместо метода
Insert лучше воспользоваться методом InsertWindow :
function tProgram.InsertWindow(P: pWindow): pWindow;
где P - указатель на размещаемое окно; результат - указатель на разме-
щенное окно, и nil - если не размещено.
Метод является функцией, которая перед размещением окна проверяет
допустимость такой операции (имеется ли необходимая область памяти и
правильно ли сконструированы окно и его компоненты).
Задание параметров воображаемому объекту
В Turbo Vision принят следующий стандартный способ передачи пара-
метров.Для объекта-группы или его потомка формируется переменная ти-
па-записи, отдельные поля которой представляют собой параметры для по-
дэлементов группы.Поля должны идти в той же последовательности, в ка-
кой подэлементы включались в группу.Для каждого подэлемента параметры
создаются по-своему.Для стандартных элементов параметры должны быть
следующими :
- строка ввода - строка того же размера;
- триггерный список - число типа Word, в котором каждый бит опре-
деляет состояние соответствующего элемента списка;
- селективный список - число типа Word, определяющее порядковый
номер выделенного элемента списка;
- триггерный список с несколькими состояниями - информация разме-
ром в 4 байта, определяющая состояние каждого элемента списка
(под каждый элемент может отводиться 1,2,4 и 8 бит информации;
- список коллекции строк - запись размером в 6 байт, первое поле
которой - указатель на коллекцию просматриваемых строк, а вто-
рое - число типа Word, определяющее порядковый номер выделен-
ного элемента списка;
- параметрический текст - по 4 байта на каждый параметр.
Для нестандартных элементов пользователь сам определяет вид и
размер параметра.
Задать параметры немодальному отображаемому объекту лучше всего с
помощью метода SetData :
procedure <отображаемый объект>.SetData (var Rec); virtual;
где Rec - передаваемая запись с данными.
Работа с модальными объектами
Для работы с модальными отображаемыми объектами используются ме-
тоды, выполняющие комплексные действия.
Универсальным является метод ExecView объекта tGroup :
function tGroup&ExecView(P: pView): Word;
где P - объект, с которым происходит работа; результат - код команды,
вызвавшей прекращение работы с объектом P.
Этот метод помещает воображаемый объект в группу, делает его мо-
дальным, обеспечивает обработку поступающих событий, и, если очередное
событие является командой или сообщением, означающими конец работы с
отображаемым модальным объектом, удаляет отображаемый объект из груп-
пы.Предварительно перед удалением объекта следует снять с него модаль-
ность, что осуществляется с помощью процедуры EndModal объекта tView :
procedure tGruop.EndModal(Command: Word); virtual;
где Command - код команды, при которой снимается модальность.
В качестве результата функция ExecView возвращает код команды,
вызвавшей прекращение работы с модальным отображаемым объектом.После
удаления из группы сам отображаемый объект из динамической памяти не
удаляется.
Если модальный отображаемый объект является диалоговым окном и
его следует поместить в рабочую область, вместо метода ExecView целе-
сообразно использовать метод ExecuteDialog :
function tProgram.ExecuteDialog(P: pDialog;Data: Pointer): Word;
где P - диалоговое окно, с которым происходит работа;
Data - указатель на запись с передаваемыми данными;
результат - код команды, вызвавшей прекращение работы и диалоговым ок-
ном P.
СОЗДАНИЕ МЕНЮ
Turbo Vision позволяет создать меню программы,предназначенное для
выбора дальнейшего пути решения задачи.
После написания объекта-приложения - основного объекта программы,
целесообразно продолжить создание программы именно с описания меню,
так как выбор той или иной структуры меню во многом будет определять и
структуру программы.В Turbo Vision можно использовать либо обычное
разворачивающееся меню, либо так называемое локальное меню.
Создание разворачивающегося меню
Разворачивающееся меню (в дальнейшем - просто меню) может иметь
довольно сложную структуру и любое число уровней вложенности, но сос-
тавляется из однотипных элементов, правда имеющих три варианта : собс-
твенно элемент меню (фактически определяет команду, которую следует
выполнить при выборе этого элемента), подменю, при выборе которого на
экране раскрывается соответствующий пункт исходного меню, и раздели-
тельная линия, которая имеет чисто декоративное назначение и позволяет
отделять в подменю те или иные группы элементов друг от друга.
Элемент меню имеет структуру типа-запись (стандартный тип
tMenuItem) :
tMenuItem = record
Next: pMenuItem;
Name: pString;
Command: Word;
Disabled: Boolean;
KeyCode: Word;
HelpCtx: Word;
case Integer of
0: (Param: pString);
1: (sub>Memu: pMenu);
end;
end;
где Next - указатель на следующий элемент этого же уровня вложенности,
если следующего элемента нет, указатель равен nil;
Name - указатель на строку, содержащую выводимый на экран текст;
этот параметр равен nil, если элемент представляет собой разделитель-
ную линию;
Commаnd - код команды, которую следует выполнить при выборе данно-
го элемента меню; эта величина равна нулю, если данный элемент - под-
меню;
Disabled - признак разрешения или запрета выбора данного элемента
меню;
KeyCode - код клавиши или их совокупности быстрого управления, с
помощью которых можно выполнить команду данного элемента меню, не вы-
зывая это элемент, или 0, если для данного элемента такой клавиши не
предусмотрено;
HelpCtx - параметр контекстной помощи, аналогичный параметру объ-
екта tView, но справочная система выдает информацию об элементе меню;
Param - указатель на строку с дополнительной информацией, которая
выводится в правой части строки подменю, соответствующей данному эле-
менту (обычно это название клавиши быстрого управления);
sub>Memu - указатель на структуру меню следующего уровня, если дан-
ный элемент представляет собой подменю.
ню.
Горизонтальные размеры выводимой на экран строки для любого эле-
мента меню ограничены 31 символом.В связи с этим в Turbo Vision имеет-
ся стандартный тип строк tMenuStr :
tMenuStr = string[31];
который и используется для задания символьной информации элементам ме-
ню.
Для каждого элемента меню можно в его названии выделить одну ла-
тинскую букву или цифру для быстрого выбора элемента путем нажатия
этой клавиши на клавиатуре (для основного меню - в сочетании с клави-
шей Alt).Такая буква выделяется в тексте символами ~~,например, ~N~ew.
В данном примере соответствующий элемент можно активизировать на-
жатием клавиши N (или Alt+N, если это элемент основного меню).На экра-
не такая буква выделяется особым цветом.
Для создания элемента меню, определяющего выполняемую команду,
используется подпрограмма NewItem :
function NewItem(Name, Param: tMenuStr; KeyCode: Word; Command:
Word; AHelpCtx: Word; Next: pMenuItem): pMenuItem;
где Name - текстовая информация для данного элемента, она не должна
быть пустой строкой;
Param - дополнительная текстовая информация для элемента;
KeyCode - код клавиши быстрого управления;
Command - код выполняемой команды, не должен равняться 0;
AHelpCtx - параметр контекстной помощи;
Next - указатель на следующий элемент меню данного уровня;
результат - указатель на созданный элемент меню.
Для создания элемента меню, представляющего собой подменю, ис-
пользуется подпрограмма Newsub>Menu :
function Newsub>Menu(Name: tMenuStr; AHelpCtx: Word; sub>Menu:
pMenu; Next: pMenuItem;
где Name - текстовая информация для данного элемента, не должна быть
пустой строкой;
AHelpCtx - параметр контекстной помощи;
sub>Menu - указатель на структуру подменю;
Next - указатель на следующий элемент подменю данного уровня;
результат - указатель на созданный элемент меню.
Если элемент меню является разделительной строкой, то использует-
ся подпрограмма NewLine :
function NewLine(Next: pMenuItem): pMenuItem;
где Next - указатель на следующий элемент меню данного уровня;
результат - указатель на созданный элемент меню.
Функционально разворачивающееся меню состоит из нескольких частей
- главного меню, постоянно отображаемого на экране, и ряда подменю,
появляющихся на экране по мере необходимости.Главное меню представляет
собой объект типа tMenuBar.Создается оно обычно с помощью стандартной
подпрограммы New, а инициализируется конструктором Init :
сonstructor tMenuBar.Init(var Bounds: tRect; AMenu: pMenu);
где Bounds - область на экране для главного меню;
AMenu - указатель на главное меню.
Создавая меню программы, следует позаботиться лишь о размерах ос-
новного меню, размеры же выпадающих подменю определяются автоматически
при их отображении на экране.Стандартный объект tProgram ( а, следова-
тельно, и объект tApplication) имеет метод InitMenuBar :
procedure tProgram.InitMenuBar; virtual;
с помощью которого можно создать меню и который следует переопределить
для конкретной программы.Этот метод помещает указатель на созданное ме-
ню в стандартную типизированную константу MenuBar пакета Turbo Vision.
Создание локального меню
При работе с программой часто приходится многократно повторять
одни и те же действия, которые разнесены по различным частям меню (а
некоторых в меню вообще не может быть).Количество их обычно небольшое,
а поиск по всему меню неудобен.Целесообразно такие действия собрать в
одно дополнительное меню, доступ к которому осуществляется по тому или
иному событию, например, команде, нажатию клавиши клавиатуры или мыши.
Для создания такого меню можно использовать стандартный объект
пакета Turbo Vision - tMenuPopup.Для этого в метод HandleEvent основ-
ного объекта программы следует включить обработку выбранного для ло-
кального меню события и написать подпрограмму вызова локального ме-
ню.Так как локальное меню должно быть довольно простым, оператор его
конструирования будет также проще, чем у разворачивающегося меню, но
тем не менее состоять из обращений к тем же методам.
Создавать локальное меню целесообразно на завершающих этапах соз-
дания программы, когда становится ясно, какие действия наиболее часто
придется выполнять пользователю программы.
Несмотря на свою сложность, меню в силу своей специфики группой
не является, и у него имеется свой своеобразный механизм обработки со-
бытий.Так, например, если меню получит событие от мыши, когда курсор
не находится в поле отображения меню, оно закрывается, как будто пос-
тупила команда завершения работы с объектом без фиксации результата.В
случае же модального объекта группы (например, диалогового окна) такое
событие игнорируется.
СОЗДАНИЕ ОКОН И ДИАЛОГОВЫХ ОКОН
После того, как будет выбрано меню программы, целесообразно прис-
тупить к формированию отдельных частей программы, обрабатывающих соот-
ветствующие команды меню и строки состояния.Часто эти команды требуют
использования различных окон для передачи информации.Окна могут потре-
боваться и при создании подпрограмм, обрабатывающих те или иные коман-
ды.
Основным средством взаимодействия пользователя с программой в
Turbo Vision являются окна (тип tWindow) и диалоговые окна (тип
tDialog).У окон и диалоговых окон много общего, т.к. диалоговое окно
является непосредственным потомком окна, однако есть и принципиальные
различия, главным образом, в их предназначении, наборе стандартных
элементов, цветовой палитре.Можно сказать, что основное назначение
окон - просмотр той или иной информации, а диалоговых окон - ввод в
программу данных.Диалоговые окна обладают рядом дополнительных возмож-
ностей и более логически завершены, поэтому они чаще используются в
программах.
Окна (tWindow) в Turbo Vision
Окном в TurboVision называется отображаемый объект-группа, имею-
щий специальную рамку и который может иметь средства прокрутки (скро-
ллинга) не умещающейся в окне информации.В него можно поместить инфор-
мацию.Как правило, в программе используется не окно типа tWindow, а
его потомок с переопределенными методами.
В дополнение к параметрам объекта tGroup окно обладает рядом до-
полнительных параметров, отметим два : флаги окна Flags и используемая
палитра Pallete.Назначение флагов параметра Flags, и константы, соот-
ветствующие единице в соответствующем разряде параметра Flags следую-
щие :
0-й бит (wfMove) - возможность перемещения окна по полю его вла-
дельца
1-й бит (wfGrow) - возможность изменения размеров окна.
2-й бит (wfClose) - наличие пиктограммы закрытия окна.
3-й бит (wfZoom) - наличие пиктограммы распахивания окна.
Параметр Pallete определяет тип используемой палитры окна и может
принимать одно из трех следующих значений :
wpBlueWindow = 0 - синяя палитра окна;
wpCyanWindow = 1 - голубая палитра окна;
wpGrayWindow = 2 - серая палитра окна.
Как правило, синяя палитра - для окон, серая - для диалоговых
окон, а голубая - для вспомогательных окон.
Инициализируется окно параметром Init :
constructor tWindow.Init(var Bounds: tRect;
ATitle: tTitleStr; ANumber: Integer);
где Bounds - размеры окна;
ATitle - имя окна размером до 80 символов;
ANumber - номер окна.
После инициализации устанавливаются значения параметров.
Характерной особенностью окна и его потомков является наличие
рамки - специального отображаемого объекта, помещаемого в окно.Таким
образом, окно всегда имеет хотя бы один подэлемент.Рамка окна помимо
декоративного значения несет на себе еще дополнительную информацию о
окне.
Вид рамки окна меняется в зависимости от его состояния.Активное
окно обрамлено двойной рамкой.
В левой части верхней линии рамки располагается пиктограмма зак-
рытия окна.При подведении курсора мыши к этой пиктограмме и нажатии
левой клавиши окно закрывается.
В средней части верхней линии рамки располагается имя окна, зада-
ваемое при его инициализации.
В правой части верхней линии рамки находится пиктограмма распахи-
вания окна "стрелка вверх" до полного размера группы, в которую вклю-
чено окно,Распахивание также осуществляется с помощью мыши.После рас-
пахивания окна пиктограмма изменит свой вид - "двустороняя стрел-
ка".Чтобы восстановить исходные размеры окна, следует повторно подвес-
ти окно, а затем снова его сжать можно и другим способом.Для этого
следует поместить курсор мыши на верхнюю линию рамки окна и дважды на-
жать клавишу.
Правый нижний угол рамки может быть таким же, как и все другие, а
может быть изображен одинарной линией даже в случае активного окна.В
этом случае с помощью мыши можно изменять размеры окна.Для этого кур-
сор мыши поместить на этот угол, нажать на клавишу и, не отпуская ее,
переместить мышь в нужном направлении, а при достижении окном требуе-
мых размеров, отпустить.Минимальные размеры окна - 16 позиций по гори-
зонтали и 6 строк по вертикали.Эти ограничения можно изменить с по-
мощью метода SizeLimits :
procedure'tView.SizeLimits(var Min, Max: tPoint); virtual;
Верхняя линия позволяет в ряде случаев с помощью мыши перемещать
окно по полю его владельца.
Наличие или отсутствие у окна этих возможностей зависит от уста-
новленных флагов параметра Flags.
При работе с окном его следует сначала создать и инициализиро-
вать.При этом создать необходимые компоненты (кроме рамки, которая
создается автоматически) и поместить их в окно.
Далее окно следует поместить в рабочую область.Как правило, окно
используется в немодальном режиме, тогда его помещают при помощи мето-
да InsertWindow, а если окно модальное - при помощи метода ExecView.
Как правило, для окна следует переопределить метод обработки со-
бытий HandlEvent, где необходимо предусмотреть обработку предназначен-
ных для окна событий.
Перед завершением работы следует снять с окна модальность с по-
мощью метода EndModal.
Если окно содержит выделенный элемент, а нужно сделать выделенным
другой, то можно воспользоваться либо мышью, подведя курсор к этому
элементу и нажав клавишу, либо с помощью клавиши клавиатуры Tab
(или Shift+Tab), при этом нажатие Tab выделит следующий в Z-порядке
элемент, а Shift+Tab - предыдущий.
Элементы окон в Turbo Vision
В качестве стандартных элементов окон Turbo Vision можно исполь-
зовать поля скроллинга (тип Scroller), предназначенные для отображения
не умещающейся на экране информации и ее просмотра, текстовые элементы
буферированной информации (тип tTewtDevice), текстовые элементы для
пассивных терминалов (тип tTerminal) наподобие текстовых файлов и ли-
нейки скроллинга.В окне можно помещать также потомки перечисленных вы-
ше стандартных элементов.
Поле скроллинга (tScroller)
Поле скроллинга предназначено для размещения в нем текстовой ин-
формации, которую необходимо вывести в окно, и которая возможно не
уменьшается целиком в поле окна.
При инициализации поля скроллинга следует задать его размеры, ли-
нейки горизонтального и вертикального скроллинга :
constructor tScroller.Init(var Bounds: tRect;
AHScrollBar, AVScrollBar: pScrollBar);
где Bounds - размеры поля;
AHScrollBar, AVScrollBar - указатели на вертикальную и горизон-
тальную линейку скроллинга.
После инициализации устанавливаются значения параметров.Кроме
этого, при инициализации потомка tScroller могут быть заданы параметры
поля скроллинга, в частности максимальный горизонтальный и вертикаль-
ный размер текстовой информации (размер строк и число строк), размеща-
емой в поле скроллинга.
Следует также переопределить метод Draw объекта tScroller для
того, чтобы наполнить поле скроллинга соответствующей информацией.Для
этого необходимо в начале определить, какая часть информации должна
быть отображена (исходя из текущего состояния линеек), затем сформиро-
вать строки, которые необходимо вывести на экран и, наконец, поместить
сформированные строки в поле скроллинга, с атрибутами цвета.
Текстовый элемент буферированной информации
Текстовый элемент буферированной информации (тип tTextDevice) яв-
ляется потомком поля скроллинга и отличается от своего предка наличием
двух абстрактных методов, которые читают из некоторого текстового бу-
фера и записывают в текстовый буфер отображаемую информацию.
Текстовый элемент для пассивного терминала
Текстовый элемент для пассивного терминала (тип tTerminal)
является наследником объекта tTextDevice и предназначен для отображе-
ния в поле скроллинга информации от пассивного терминала, чаще всего
из текстового файла этого терминала.Под пассивным терминалом здесь по-
нимается терминал, хранящий информацию, но не имеющий собственных
средств редактирования информации и управления экраном.
Инициализируется текстовый элемент для пассивного терминала конс-
труктором Init :
constructor tTerminal.Init(var Bounds: tRect;
AHScrollBar, AVScrollBar: pScrollBar; ABufSize: Word);
где Bounds - размеры поля;
AHScrollBar, AVScrollBar - указатели на вертикальную и горизон-
тальную линейку скроллинга;
ABufSize - размер буфера терминала в байтах.
Во время инициализации создается элемент с указанными параметра-
ми, а также буфер для передачи информации размером ABufSize.
Линейка скроллинга (tScrollBar)
Линейка скроллинга предназначена для фиксации места нахождения
отображаемой на экране в данный момент порции информации во всем объ-
еме отображаемой информации.Линейка представляет собой либо горизон-
тальную полосу, либо вертикальную.Полоса оканчивается двумя стрелками,
а в средней части расположен ползунок, указывающий относительное рас-
положение отображаемой порции информации.
Используя этот ползунок, можно быстро переместиться в любое место
отображаемой информации.Для этого необходимо подвести к нему курсор
мыши, нажать клавишу мыши и, не отпуская ее, отбуксировать ползунок в
нужное место линейки скроллинга.Если курсор мыши поместить не на пол-
зунок, а в другое место линейки и нажать клавишу мыши, будет отображе-
на следующая страница информации, находящаяся в соответствующем нап-
равлении.Если курсор мыши поместить на завершающую стрелку и нажать
клавишу мыши, будет осуществлено перемещение на один шаг в соответс-
твующую сторону.
5 параметров объекта tScrollBar :
Min, Max - определяют миним. и максим. значение номера текущего
элемента информации.
ArStep - величина шага перемещения по информации в случае нажатия
клавиш Left, Right, Up, Down или при нажатии клавиши мыши, если ее
курсор находится на завершающей стрелке.
PgStep - размер страницы, на которую происходит перемещение.
Value - текущий элемент информации.Инициализация линейки скрол-
линга осуществляется конструктором Init :
constructor tScrollBar.Init(var Bounds: tRect;
где Bounds - область, выделенная под линейку скроллинга в коорди-
натах его владельца.
Линейка скроллинга не может активизироваться, так как у нее не
установлен флаг ofSelectable параметра Options.Поэтому она не может
обычным образом реагировать на нажатие клавиш клавиатуры.Чтобы этого
не происходило, следует нарушить стандартный порядок обработки собы-
тий, установив флаг ofPostProcess параметра Options.
Диалоговое окно
Диалоговое окно (тип tDialog) представляет специальный тип окна
(является потомком tWindow) и предназначено в первую очередь для ввода
значений параметров в программу.
Так же как и обычное окно, диалоговое окно может использовать
один из трех видов палитры :
dpBlueDialog = 0 - синяя палитра диал. окна;
dpCyanDialog = 1 - голубая палитра диал. окна;
dpGrayDialog = 2 - серая палитра диал. окна.
В отличие от обычного окна диалоговое окно обычно
используется в модальном режиме.Инициализируется диалоговое окно конс-
труктором Init :
constructor tDialog.Init(var Bounds: tRect;
ATitle: tTitleStr);
где Bounds - размеры диалогового окна;
ATitle - имя диалогового окна размером до 80 символов.
В отличие от обычного окна у диалогового окна стандартно нет воз-
можности изменять размеры, оно использует серую палитру и не имеет но-
мера.
К другим особенностям диалогового окна можно отнести обработку им
клавиш Esc и Enter.Если диалоговое окно находится в модальном режиме,
нажатие Esc закрывает окно без сохранения введенной информации.Нажатие
клавиши Enter эквивалентно нажатию кнопки, выбираемой по умолчанию
(закрывает окно с сохранением внесенных изменений).
Для удобной работы с диалоговым окном в Turbo Vision имеется
большое количество стандартных объектов, которые можно использовать в
качестве элементов этого окна.
Работу с диалоговым окном в модальном режиме можно организовать
следующим образом.Сначала создать и инициализировать диалоговое окно,
при этом поместив в него все его элементы.Затем подготовить исходные
данные для передачи диалоговому окну.
Далее диалоговое окно размещается в рабочей области с помощью ме-
тода ExecuteDialog и осуществляется работа с ним.При завершении работы
анализируется, какое происходит завершение - с сохранением внесенных
изменений или без.Изменения, которые требуется сохранить, возвращаются
в том же параметре, в котором передавались исходные данные.
Если окно используется в немодальном режиме, последовательность
работы с ним аналогична последовательности работы с обычным окном.
Элементы диалоговых окон
Возможно использование стандартных элементов или их потомков :
- строки ввода;
- метки;
- протоколы;
- селективные списки;
- триггерные списки;
- кнопки;
- статические и параметрические тексты;
- списки строк;
- линейки скроллинга.
Строка ввода
Строка ввода (тип tInputLine) предназначена для ввода в программу
символьной информации.Фактически строка ввода представляет собой прос-
тейший редактор строки символов и обладает большим набором возможнос-
тей.Основным элементом строки является буфер (строка, в которую поме-
щаются все вводимые символы).Инициализируется строка ввода методом
Init :
constructor tInputLine.Init(var Bounds: tRect;
AMaxLen: Integer);
где Bounds - размер поля строки ввода;
AMaxLen - размер буфера.
Высота поля строки ввода должна равняться единице.Ширина поля мо-
жет быть любой, но не менее 3.Размер буфера может иметь любое значение
до 255.После создания строки ввода непосредственно изменять размеры
буфера нельзя.
Так как строка ввода работает только с символьной информацией, то
перед вводом в нее какого-либо числа оно должно быть преобразовано в
символьную форму, а при получении информации из строки ввода - обратно
преобразовано в двоичную.
Метка (tLabel)
Метка всегда связана с каким-либо другим элементом окна и предс-
тавляет собой текст, поясняющий смысл объекта.Кроме этого, с помощью
метки можно довольно просто активизировать связанный с ней элемент.При
нажатии курсором мыши на поле метки будет активизирован связанный с
ней элемент.
Конструктор метки имеет вид :
constructor tLabel.Init(var Bounds: tRect;
const AText: string; ALink: pView);
где Bounds - размер поля метки;
AText - текст метки;
ALink - указатель на объект, с которым связана метка.
Метка располагается либо над объектом, либо слева от него.Высота
поля метки равна единице.Если текст метки состоит из цифр и латинских
букв, то можно выделить одну букву и поместить ее между символами
~~.Такая буква на экране будет выделена особым цветом, а нажав клавишу
с этим символом, можно активизировать данный элемент.
Протокол
Протокол (тип tHistory) всегда связан со строкой ввода и предназ-
начен для сохранения в своем буфере вводимой в строку ввода информа-
ции.Для вызова ранее набираемой информации следует, находясь в строке
ввода, либо подвести курсор к полю пиктограммы протокола и нажать кла-
вишу мыши, либо нажать клавишу Down.В результате откроется окно прото-
кола, содержащее вводимые ранее строки в данную строку ввода.Следует
выбрать интересующую строку (клавиша мыши или клавиши Up и Down).Далее
дважды нажать клавишу мыши или нажать Enter.
Протокол инициализируется при помощи метода Init :
constructor tHistory.Init(var Bounds: tRect;
ALink: pInputLine; AHistoryID: Word);
где Bounds - поле для размещения пиктограммы протокола;
ALink - указатель на строку ввода, с которым связан протокол;
AHistoryID - номер протокола - число, определяющее данный тип
протокола.
Обычно протокол размещается за строкой ввода, к которой он отно-
сится.Ширина поля должна равняться двум, высота - единице.
Селективный (тип tRadioButtons) и триггерный ( тип tCheckBoxes)
списки
Селективный и триггерный списки очень похожи, так как у них есть
общий предок (tCluster), заключающий в себе общие свойства.
Селективный список позволяет выбрать только один элемент из этого
списка.Количество элементов ограничено числом 65536.
Триггерный список позволяет выбрать из списка любое число элемен-
тов (или ни одного), однако при стандартном использовании число эле-
ментов этого списка ограничено 16-ю.
Оба списка инициализируются одним методом Init объекта tCluster :
constructor tСluster.Init(var Bounds: tRect;
AStrings: pSItem);
где Bounds - поле, выделяемое под образ списка;
AStrings - указатель на список информационных строк.
Чтобы выбрать элемент списка, можно воспользоваться мышью, подве-
дя курсор к соответствующей строке и нажав клавишу, либо клавиатурой,
используя клавиши направления.В триггерном списке при использовании
клавиш направления следует завершить выбор элемента списка нажатием
пробела.
В строке символов каждого элемента списка можно выделить латинс-
кую букву или цифру, поместив ее между ~~.Она будет выделена на экране
особым цветом, и можно выбрать соответствующий элемент списка нажатием
клавиши клавиатуры с этим символом.
Кнопка (тип tButton)
Кнопка позволяет выбрать команду, которая с ней связана.При выбо-
ре команды работа с диалоговым окном часто прекращается.
Кнопка может иметь флаги, находящиеся в параметре Flags при ини-
циализации :
0-й бит (bfDefault) - кнопка, выбираемая по умолчанию.
1-й бит (bfLeftJust) - текст кнопки выравнивается по ее левому
краю ( при отсутствии флага текст центрируется).
2-й бит (bfBroadcast) - кнопка формирует сообщение вместо команды.
3-й бит (bfGrabFocus) - фокусирование кнопки при ее активизации
мышью.
Инициализируется кнопка конструктором Init :
constructor tButton.Init(var Bounds: tRect;
ATitle: tTitleStr; ACommand:Word;AFlags:Byte);
где Bounds - поле, выделяемое под кнопку;
ATitle - текст, размещаемый на кнопке;
ACommand - код команды, связанной с кнопкой;
AFlags - задаваемые флаги кнопки.
Выделяемое под кнопку поле должно быть достаточных размеров,
чтобы в нем отобразилась вся кнопка с текстом и ее тень.Поэтому высоту
кнопки не следует брать меньше двух, а ширина зависит от размещаемого
текста.
Выбрать кнопку можно с помощью мыши, подведя курсор и нажимая на
клавишу, либо с помощью клавиши Tab, а затем клавиши Enter.При выборе
кнопки она формирует событие-команду с кодом команды, который был за-
дан кнопке.В качестве параметра кнопка передает указатель на себя.
Статический (tStaticText) и параметрический (tParamText) тексты
Статический текст предназначен для размещения в диалоговом окне
различной поясняющей информации.
Инициализация осуществляется при помощи метода Init :
constructor tStaticText.Init(var Bounds: tRect;
const AText: String);
где Bounds - поле, выделяемое под статический текст;
AText - размещаемый текст.
Поле, выделяемое под статический текст, должно быть достаточных
размеров, чтобы можно было расположить все слова текста.Текст автома-
тически делится на слова и размещается в выделенном поле без переносов
внутри слов.
Разновидностью статического текста является параметрический
текст, позволяющий модифицировать выводимый текст в зависимости от за-
даваемых параметров.Для того, чтобы указать, в каком месте текста сле-
дует разместить параметры и какого типа, в исходном тексте используют-
ся спецификации там, где должны быть размещены параметры.
Инициализируется параметрический текст методом Init:
constructor tParamText.Init(var Bounds: tRect;
const AText: string; AParamCount: Integer);
где Bounds - поле, выделенное под параметрический текст;
AText - исходный текст со спецификациями параметров;
AParamCount - число параметров текста.
Списки строк
Списки строк в диалоговом окне напоминают поле скроллинга и его
потомков для обычных окон и предназначены для просмотра тех или иных
списков.
Список строк (тип tListViewer) является абстрактным объектом, из
него можно получить реальный объект, который будет работать с конк-
ретным списком информации (вертикальный и горизонтальный скроллинг).
Непосредственным потомком списка строк является список коллекции
строк (типа ListBox), предназначенный в первую очередь для просмотра
коллекции строк (только вертикальный скроллинг).
Инициализируется список коллекции строк с помощью конструктора
Init :
constructor tListBox.Init(var Bounds: tRect;
ANumCols: Word; AScrollBar: pScrollBar);
где Bounds - поле, выделенное под список;
ANumCols - число колонок, в которые выводятся строки;
AScrollBar - указатель на линейку вертикального скроллинга.
Стандартные окна
В Turbo Vision имеется большое количество стандартных окон, имею-
щих специальное назначение.Рассмотрим стандартные информационные ок-
на.Заголовок функции MessageBox имеет вид :
function MessageBox(const Msg: string; Params:
Pointer; AOptions: Word): Word;
где Msg - размещаемое в окне сообщение;
Params - указатель на параметры сообщения;
AOptions - флаги;
результат - код команды, связанной с нажатой кнопкой диалогового
окна.
Функция формирует окно размером 40*60, в котором помещается сооб-
щение Msg, скорректированное параметрами, находящимися по адресу, оп-
ределяемому значением Params и набор кнопок, определяемый параметром
AOptions, который определяет также тип окна (его название).
СОЗДАНИЕ СТРОК СОСТОЯНИЯ
Строка состояния не является необходимым атрибутом.Однако ее ис-
пользование помогает пользователю проще работать с программой, так как
он может получить информацию о текущем состоянии программы и клавишах
быстрого управления.Если программа должна иметь строку состояния, то
ее создание следует начинать непосредственно после создания меню прог-
раммы с тем, чтобы потом одновременно рассматривать команды, формируе-
мые меню и строкой состояния.
Строка состояния, отображающая клавиши быстрого управления
Каждый элемент строки состояния , содержащий информацию о конк-
ретной клавише (их совокупности) быстрого управления, имеет стандарт-
ный тип-запись tStatusItem :
tStatusItem = record
Next: pStatusItem;
Text: pString;
KeyCode: Word;
Command: Word
end;
где Next - указатель на следующий элемент строки состояния;
Text - указатель на строку, содержащую выводимый на экран текст
для данной клавиши быстрого управления;
KeyCode - код клавиши быстрого управления, с помощью которой можно
выбрать данный элемент строки состояния;
Command - код команды, которую следует выполнить при выборе данно-
го элемента строки состояния.
Создать элемент строки состояния можно с помощью стандартной
функции NewStatusKey :
function NewStatusKey(const AText: string;
AKeyCode: Word; ACommand: Word; ANext:
pStatusItem); pStatusItem;
где AText - выводимый на экран текст;
AKeyCode - код клавиши быстрого управления;
ACommand - код команды, которую следует выполнить при выборе дан-
ного элемента;
ANext - указатель на следующий элемент строки состояния;
результат - указатель на созданный элемент строки состояния.
Сама строка состояния имеет стандартный тип-запись tStatusDef :
tStatusDef = recerd
Next: pStatusDef;
Min, Max: Word;
Items: pStatusItem;
end;
где Next - указатель на следующую строку состояния;
Min, Max - миним. и максим. границы диапазона параметра контекс-
тной помощи, для которого отображается именно эта строка состояния;
Items - указатель на первый элемент списка элементов.
Элементы строки состояния также как и строки состояния представ-
ляют собой линейный список.
Для создания строки состояния можно воспользоваться стандартной
функцией NewStatusDef :
function NewStatusDef(AMin, AMax: Word;
AItems: pStatusItem; ANext: pStatusDef): pStatusDef;
где ANext - указатель на следующую строку состояния;
AMin, AMax - миним. и максим. границы диапазона параметра контекс-
тной помощи, для которого отображается именно эта строка состояния;
AItems - указатель на первый элемент списка элементов.
В строке состояния также можно отразить информацию о состоянии
программы в конкретный момент времени (процесс, протекающий в програм-
ме и т.д.)Информация такого вида зависит от значения параметра кон-
текстной помощи активизированного в настоящий момент элемента програм-
мы.Вывести такую информацию можно с помощью метода Hint объекта
tStatusLine :
function tStatusLine(AHelpCtx : Word): string; virtual;
где AHelpCtx - значение параметра контекстной помощи;
результат - строка символов, выводимая на экран.
ЦВЕТОВАЯ ПАЛИТРА TURBO VISION
Turbo Vision позволяет манипулировать цветом изображения объектов
на экране.При этом можно использовать стандартный набор цветов, задан-
ный в пакете, который охватывает расцвечивание всех стандартных объек-
тов и создает благоприятные цветовые ощущения у пользователя програм-
мы, или создавать свою палитру.
Стандартная палитра
Все стандартные отображаемые объекты имеют свою цветовую палитру
- набор цветов для отдельных элементов этого объекта, а окна и диало-
говые окна - по три палитры.Учитывая структуру отображаемых объектов
программы и то, что все отображаемые объекты программы за исключением
основного объекта tApplication, являются подэлементами какой - либо
группы, для каждого такого объекта палитра представляется строкой,
компонентами которой являются не атрибуты цветов, а номера элементов
палитры данной группы.
Если в программе достаточно использовать цвета основной палитры
по их прямому назначению, то никаких действий по раскрашиванию предп-
ринимать не надо, так как цвета выбираются при отображении на экране
соответствующего объекта с помощью метода Draw :
procedure <отображаемый объект>.Draw; virtual;
который, в свою очередь, использует методы GetPallete :
function <отображаемый объект>.GetPallete:
pPallete; virtual;
определяющий указатель на конкретную палитру объекта, и GetColor :
function tView.GetColor(Color: Word): Word;
где Color - номер входа в палитру;
результат - атрибуты соответствующего цвета.
Изменение стандартной палитры
Если требуется изменить уже существующий цвет у всех использующих
его объектов, то следует просто внести изменения в основную палит-
ру.Для этого нужно либо внести изменения в исходный текст модуля App
(константа CAppColor) и перекомпилировать его, либо внести изменения
в метод GetPallete объекта tProgram.
Второй вариант - когда нужно изменить цвета у какого-нибудь объ-
екта группы, а в этой группе есть другой объект, обладающий необходи-
мыми цветами.В этом случае можно изменить соответствующим образом
константу, определяющую палитру у метода GetPallete.
Если необходимо изменить цвета конкретного объекта, а требуемого
сочетания цветов у его владельца нет, то следует дополнить основную
палитру программы новыми элементами, соответствующими требуемым цве-
там.Так как основная палитра исходно имеет 127 элементов, то примерно
столько же можно к ней добавить в случае необходимости.После этого
следует переопределить метод GetPallete основного объекта программы.
В тех случаях, когда следует предусмотреть частое изменение цве-
тов отдельных объектов в процессе выполнения программы, можно восполь-
зоваться средствами модуля ColorSel.
НЕОТОБРАЖАЕМЫЕ ОБЪЕКТЫ TURBO VISION
Помимо отображаемых, в Turbo Vision имеется ряд неотображаемых
объектов, предназначенных для выполнения действий, не связанных непос-
редственно с представлением информации на экране, в частности проверки
вводимой информации или размещения в них той или иной информации.
Основными неотображаемыми объектами являются анализаторы вводимой
информации, коллекции, потоки и ресурсы.Все эти объекты - потомки объ-
екта tObject.
Анализаторы вводимой информации
В Turbo Vision 2.0 имеется возможность контроля размещаемой в
строке ввода информации.Для этого служит серия объектов, называемых
анализаторами вводимой информации, исходным является абстрактный объ-
ект tValidator, а его потомками являются стандартные анализаторы.
Анализатор множества допустимых символов (тип tFilterValidator)
проверяет, входят ли вводимые символы в множество допустимых, и если
входят, то помещаются в буфер строки ввода, а в противном случае сим-
волы игнорируются.Инициализация такого анализатора осуществляется
конструктором Init :
constructor tFilterValidator.Init(AValidChars: tCharSet);
где AValidChars - множество допустимых символов типа tCharSet.
Анализатор границ вводимого числа (тип tRangeValidator) предназ-
начен для контроля вводимых в символьной форме целых чисел (в общем
случае типа Logint).Этот анализатор, являясь потомком объекта
tFilterValidator, помимо проверки допустимых символов (только цифр и
знаков "+" и "-" в первой позиции вводимой информации) проверяет также
значение введенного числа и его нахождение в заданном диапазоне.
Анализатор инициализируется конструктором Init :
constructor tRangeValidator.Init(AMin, AMax: Longint);
где AMin, AMax - миним. и максим. допустимые границы вводимого числа.
Если введенное число не попадает в заданный диапазон, выдается
сообщение об ошибке в виде информационного окна, при выходе из которо-
го происходит возврат к строке ввода для внесения соответствующих из-
менений.Окно не закрывается.
Анализатор по списку строк (тип tStringLookupValidator) сравнива-
ет строку введенных символов со списком допустимых строк, находящимся
в коллекции строк.Реакция при неправильно введенной строке аналогичная.
Анализатор инициализируется конструктором Init :
constructor tStringLookupValidator.Init(
AStrings: pStringCollection);
где AString - коллекция строк, с которыми сравнивается вводимая инфор-
мация.
Анализатор по шаблону (тип tPXPictureValidator) позволяет создать
шаблон, по которому проверяется вводимая информация.Можно проверять
количество вводимых символов, их вид и т.д.
Анализатор инициализируется конструктором Init :
constructor tPXPictureValidator.Init(
const APic: string; AutoFill: Boolean);
где APic - шаблон, по которому проверяется вводимая информация;
AutoFill - если равен True, вводимая информация автоматически до-
полняется символами шаблона, не являющимися служебными символами.
Анализатор должен быть подключен к соответствующей строке ввода с
помощью метода SetValidator строки ввода :
procedure tInputLine.SetValidator(AValid: pValidator);
где AValid - указатель на подключаемый к строке ввода анализатор.
Объект-коллекция
Объект-коллекция (тип Collection) предназначен в первую очередь
для размещения в нем объектов (точнее, указателей на объекты).Основным
отличием коллекции от массива является то, что размеры ее при необхо-
димости могут изменяться.Кроме этого, коллекция может содержать объек-
ты разных типов и элементы, не являющиеся объектами.
Создается коллекция с помощью конструктора Init :
constructor tCollection.Init(ALimit, ADelta: Integer);
где ALimit - первоначальный размер коллекции;
ADelta - величина, на которую изменяется размер в случае необхо-
димости.
Работа с коллекцией осуществляется следующим образом.Вначале соз-
дается коллекция и инициализируется конструктором Init.После этого в
нее можно помещать компоненты.При этом в коллекции помещается указа-
тель на размещаемый объект.Если при размещении очередного объекта в
коллекции нет достаточного места, она автоматически увеличивается на
величину ADelta.
Компоненту в коллекцию можно поместить либо в конце списка, либо
после компоненты с указанным значением индекса.В первом случае исполь-
зуется метод Insert :
procedure tCollection.Insert(Item: Pointer); virtual;
где Item - указатель на размещаемый в коллекции объект,
во втором случае используется метод AtInsert :
procedure tCollection.AtInsert(Index:Integer;Item: Pointer);
где Index - номер компоненты, который получает размещаемый объект;
Item - указатель на размещаемый в коллекции объект.
Эти методы копии размещаемого в коллекции объекта не создают.
Следует отметить три важных метода коллекции.
Метод FirstThat :
function tCollection.FirstThat(Test: Pointer): Pointer;
где Test - указатель на функцию, проверяющую некоторое условие;
результат - указатель на первую компоненту коллекции, для которой
верно условие, проверяемое функцией, указатель на которую равен Test.
Функция с указателем Test не должна быть методом и должна компи-
лироваться с директивой far.Ее заголовок выглядит следующим образом :
function <имя функции>(Item: Pointer): Boolean; far;
В этом заголовке Item - указатель на компоненту коллекции; ре-
зультат функции равен True, если проверяемое функцией условие выполня-
ется, и False - в противном случае.
Второй метод - LastThat :
function tCollection.LastThat(Test: Pointer): Pointer;
где Test - указатель на функцию, проверяющую условие; результат - ука-
затель на последнюю компоненту коллекции, для которой верно условие,
проверяемое функцией, указатель на которую равен Test, либо nil, если
ни для одной компоненты коллекции условие не выполняется.Функция с
указателем Test аналогична такой же функции метода FirstThat.
Третий метод - ForEach :
procedure tCollection.ForEach(Action: Pointer);
где Action - указатель на процедуру, которая выполняет требуемые дейс-
твия с каждой компонентой.Процедура с указателем Action не должна быть
методом и должна компилироваться с директивой far.Ее заголовок :
procedure <имя процедуры>(Item: Pointer); far;
где Item - указатель на компоненту коллекции.
Коллекция может содержать не только объекты, но и элементы других
типов.В частности, имеется стандартная коллекция строк (тип
tStringCollection).В ней переопределен метод FreeItem, который удаляет
компоненту из коллекции и из динамической памяти.
Потоки Turbo Vision
Поток и его потомки предназначены для хранения в них объектов и
данных других типов.Потоки напоминают обычные файлы, но они могут су-
ществовать не только на внешних устройствах, но и в оперативной памя-
ти.Другое важное отличие - возможность хранения данных разных ти-
пов.Возможны запись и чтение.
При создании потока в нем не находится никакой информации.Записы-
ваемая в поток информация последовательно приписывается к его концу,
так что условный указатель на текущий элемент файла в этом случае ука-
зывает на его конец.После чтения очередной компоненты из потока указа-
тель автоматически настраивается на начало следующей.
Поток типа tStream является абстрактным потоком, потому что он не
привязан к конкретному носителю информации.На практике используются
потоки ДОС (тип tDosStream) и буферированный поток (тип
tBufStream).Они позволяют хранить информацию во внешних файлах, причем
у буферированного потока информация передается через промежуточный бу-
фер, что повышает быстродействие работы.
Поток ДОС инициализируется конструктором Init :
constructor tDosStream.Init( FileName: FNameStr; Mode: Word);
где FileName - имя файла, с которым связан поток (размеры по правилам
MS-DOS - до 79 символов);
Mode - категория файла.
Буферированный поток инициализируется конструктором Init :
constructor tBufStream.Init( FileName: FNameStr;
Mode, Size: Word);
где FileName - имя файла, с которым связан поток (размеры по правилам
MS-DOS - до 79 символов);
Mode - категория файла;
Size - размер буфера (обычно от 512 до 2048 байт).
Перед тем как поместить объект в поток или взять из потока, его
следует подготовить.
Следует создать методы записи информации в поток и чтения из не-
го.У стандартных отображаемых объектов в Turbo Vision такие методы уже
имеются.Первый метод - Store :
procedure <отображаемый объект>.Store (var S: tStream);
где S - поток, в который помещается объект.Метод размещает объект в
потоке.
Второй - конструктор Load :
constructor <отображаемый объект>.Load(var S: tStream);
где S - поток, из которого берется объект.Конструктор загружает объект
из потока в память.
Для того, чтобы записать в поток тот или иной параметр объекта
(группу параметров, следующих друг за другом), можно воспользоваться
методом Write :
procedure <тип потока>.Wriye (var Buf; Count: Word); virtual;
Buf - буфер с переписываемой информацией;
Count - размер переписываемой информации в байтах.
Это основной метод записи информации в поток.
Для всех методов имеются аналоги, осуществляющие чтение информа-
ции из потока.Основной - метод Read, позволяющий читать из потока зна-
чение параметра объекта (группы параметров) :
procedure <тип объекта>.Read (var Buf; Count: Word); virtual;
Buf - буфер, в который помещается информация;
Count - размер переписываемой информации в байтах.
Вторая операция, связанная с подготовкой объекта к записи в по-
ток, - его регистрация.В потоке могут быть объекты разных типов, поэ-
тому возникает проблема в определении типов этих объектов при необхо-
димости работы с ними.Для решения этой проблемы используется система
регистрации, заключающаяся в том, что каждому типу объекта, который
предполагается записать в поток, присваивается индивидуальный регист-
рационный номер.По этому номеру будут определяться размер записанной
или записываемой информации, соответствующая таблица виртуальных мето-
дов, а также адреса методов, с помощью которых данный объект загружа-
ется в поток и читается из него.
Для регистрации объекта следует создать регистрационную запись
(типа tStreamRec) :
type
tStreamRec = record
ObjType: Word;
VmtLink: Word;
Load: Pointer;
Store: Pointer;
Next: Word;
end;
где ObjType - индивидуальный регистрационный номер объекта;
VmtLink - смещение адреса таблицы виртуальных методов объекта;
Load - адрес конструктора Load объекта;
Store - адрес метода Store объекта;
Next - смещение адреса следующей регистрационной записи.
В качестве регистрационной записи, как правило, типизированная
константа, у которой заполнены первые 4 поля.Имя регистрационной запи-
си получается из имени объекта заменой префикса t на префикс R.У стан-
дартных элементов уже есть регистрационные записи.За стандартными объ-
ектами зарезервированы индивидуальные регистрационные номера с 1 до
999, так что программист может назначать своим объектам номера от 1000
до 65535.Это число записывается в первое поле регистрационной запи-
си.Во второе поле помещается смещение адреса таблицы виртуальных мето-
дов объекта, в третье поле - адрес конструктора Load, а в четвертое -
адрес метода Store.Пятое поле заполняется автоматически при регистра-
ции объекта.
Запись объекта в поток осуществляется с помощью метода Put
объекта tStream :
procedure tStream.Put(P: pObject);
где P - указатель на размещаемый в потоке объект.
Чтение объекта из потока осуществляет метод Get объекта tStream :
function tStream.Get; pObject;
где результат - указатель на созданный объект.
После работы с потоком его следует закрыть процедурой Dispose :
Dispose(MyStream, Done);
где MyStream - поток, с которым завершается работа;
Done - деструктор потока.
Ресурсы
У рассмотренных потоков есть недостаток - непросто осуществить
произвольный доступ к отдельным компонентам потока.Поэтому имеется
специальный объект - файл ресурсов (tResourceFile), связанный с пото-
ком, в котором обеспечен произвольный доступ к любой компоненте по ее
имени (идентификатору).Этот поток дополнен потомком коллекции строк,
содержащим адреса компонент (ресурсов) в потоке, размеры компонент и
их имена.
Инициализируется файл ресурсов конструктором Init ;
constructor tResourceFile.Init(AStream: pStream);
где AStream - поток, который связывается с файлом ресурсов.
Прежде чем инициализировать файл ресурсов, следует создать соот-
ветствующий поток.
Размещение объекта в файле ресурсов осуществляется с помощью ме-
тода Put :
procedure tResourceFile.Put(Item: pObject; Key: String);
где Item - указатель на размещаемый в файле ресурсов объект;
Key - имя, присвоенное размещаемому объекту.
Извлечение объекта из файла ресурсов осуществляется с помощью ме-
тода Get :
function tResourceFile.Get(Key: String): pObject;
Key - имя, присвоенное размещаемому объекту;
результат - указатель на найденный объект или nil, если нет объ-
екта с таким именем.
В файле ресурсов можно хранить библиотеку интерфейсных элемен-
тов.Использование таких файлов является хорошим средством повышения
эффективности программирования, ускоряя процесс создания программ.
Списки строк
В Turbo Vision имеется специальный объект - список строк (тип
tStringList), предназначенный для хранения в потоке последовательности
строк, которые можно вызвать по номеру.
Прежде чем рассматривать объект tStrihgList, познакомимся с объ-
ектом типа tStrListMaker, позволяющим создать список строк и наполнить
его соответствующим содержанием.Инициализируется он конструктором Init
constructor tStrListMaker.Init(AStrSize,AIndexSize: Word);
где AStrSize - размер буфера для размещения строк;
AIndexSize - максимальный индекс размещаемой строки.
Размещаются строки в список с помощью метода Put :
procedure tStrListMaker.Put(Key: Word; S: string);
где Key - индекс размещаемой строки;
S - размещаемая строка.
Сам список tStrList конструктора не имеет, получить из него стро-
ку можно с помощью метода Get :
function tStrList.Get(Key: Word): string;
где Key - индекс строки;
результат - найденная строка.
НЕКОТОРЫЕ ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ TURBO VISION
Текстовый редактор
В настоящее время создано большое количество текстовых редакто-
ров, но иногда требуется создать свой собственный, особенно когда он
должен входить составной частью какого-либо пакета.Пакет Turbo Vision
содержит ряд объектов, на основе которых можно создать неплохие текс-
товые редакторы.Исходным является объект tEditor.Его потомок - объект
tFileEditor, позволяющий создавать редакторы, связанные с текстовыми
файлами.Без особых изменений можно создавать редакторы, работающие од-
новременно с любым количеством файлов, содержащих тексты до 64 К,
обеспечивающие работу с клавиатурой и мышью, поиск в тексте и замену,
использование буфера и т.д.
Отображение древовидных структур
Часто в программе используются древовидные иерархические структу-
ры, которые желательно отобразить на экране с изображением связей меж-
ду отдельными элементами.К таким структурам относятся меню и строки
состояния.Для отображения подобных структур в Turbo Vision имеются два
специальных объекта : абстрактный объект tOutlineViewer, осуществляю-
щий отображение структуры на экране, и tOutline, осуществляющий работу
с конкретной древовидной структурой.Последний объект позволяет скры-
вать или показывать на экране те или иные ветви структуры с помощью
мыши или клавиатуры.
Диалоговое окно задания цветной палитры
Существует стандартное диалоговое окно задания цветов
tColorDialog.С помощью этого окна можно изменять лишь имеющиеся цвета
и, кроме того, изменение цветов произойдет одновременно у всех отобра-
жаемых объектов программы соответствующего типа.
ЗАКЛЮЧЕНИЕ
Очень важным показателем при оценке программных продуктов являет-
ся удобство работы пользователя.
Поэтому в настоящее время ни один программный продукт, лишенный
удобного интерфейса взаимодействия пользователя с компьютером и
программ между собой, не заинтересует никого так, как заинтересовал бы
программный продукт таких же возможностей, но с удобным пользователь-
ским интерфейсом.
В мире разработано огромное количество различных систем поддержки
создания пользовательского интерфейса.
Представленный в данной работе разработанный фирмой Borland
International пакет Turbo Vision 2.0 является удобным средством уп-
рощения работы по организации ввода/вывода, его унификации с учетом
современных требований к интерфейсу программ. Этот пакет представляет
собой объектно-ориентированную библиотеку средств формирования пользо-
вательского интерфейса.
Более универсальным является диалоговый способ передачи информа-
ции и именно для организации диалога предназначен в первую очередь па-
кет Turbo Vision.Использование этого пакета освобождает программиста
от занимающей много времени работы, связанной с организацией вво-
да/вывода, которая повторяется от программы к программе, требует вы-
полнения однотипных операций, отвлекает внимание программиста от реше-
ния основной задачи.
В современных программах, работающих в текстовом режиме, диалог
обычно организуется с помощью трех средств : меню, диалоговых окон и
строк состояния.Turbo Vision позволяет реализовать все эти средства
диалога.В представленной работе подробно описаны методы создания
этих средств, их виды, особенности, элементы, а также приводятся реко-
мендации по их использованию.
Turbo Vision представляет собой библиотеку объектов, позволяющих
создать пользовательский интерфейс. Почти все объекты библиотеки явля-
ются потомками общего абстрактного объекта tObject.В работе рассмотре-
на их классификацию, исходя из задач, возникающих при создании интер-
фейса.
В работе подробно рассмотрен порядок работы с отображаемыми
объектами (создание, помещение в группу, задание параметров), работы
с модальными объектами, а также виды неотображаемых объектов Turbo
Vision и работу с ними.
Пакет Turbo Vision позволяет использовать стандартную па-
литру или создавать свою.Пакет имеет дополнительные возможности, что
может быть очень важным в ряде случаев : можно создать текстовый ре-
дактор с большими возможностями, при необходимости отобразить древо-
видную структуру, использовать диалоговое окно задания цветовой палит-
ры.
Исходя из средств и особенностей пакета можно сказать, что
Turbo Vision фирмы Borland International является одним из самых удоб-
ных современных средств создания пользовательского интерфейса.