Турбо Паскаль 6.0

         

TRadioButtons Dialogs


+------------+ | TObject | +------+-----+ +------+-----+ | TView | +------+-----+ +------+-----+ | TCluster | +----+---+---+ +--------+ +------+ +======+========+ +------+------+ | TRadioButtons | | TCheckBoxes | +===============+ +-------------+

Объекты TRadioButtons - это кластеры, содержащие до 65,536 элементов управления, из которых в любой момент времени может быть выбрана только одна кнопка. Выбор невыбранной кнопки будет автоматически освобождать предварительно выбранную кнопку. Этот объект наследует от TCluster большую часть функций, включая Init, Load и Done. Зависимые кнопки часто ассоциированы с объектом TLabel. TRadioButtons интерпретирует наследуемое поле TCluster.Value как номер "нажатой" кнопки. С номером первой кнопки в кластере, равным 0.

Методы

Draw procedure Draw; virtual; Перекрывается: Редко Рисует кнопки как ' ( ) ' .

Mark function Mark(Item: Integer): Boolean; virtual; Перекрывается: Никогда Возвращает True, если Item = Value, т.е. если кнопка с номером Item представлена текущим значением поля Value.

См. так же: TCluster.Value, TCluster.Mark

MovedTo procedure MovedTo(Item: Integer); virtual; Перекрывается: Никогда Присваивает Value значение Item.

См. так же: TCluster.MovedTo, TRadioButtons.Mark

Press procedure Press(Item: Integer); virtual; Перекрывается: Никогда Присваивает Value значение Item. Вызывается при нажатии кнопки с номером Item.

SetData procedure SetData(var Rec); virtual; Перекрывается: Редко Вызывает TCluster.SetData для установки поля Value, затем устанавливает поле Sel равным Value, поскольку выбранный элемент - это "нажатая" кнопка.

См. так же: TCluster.SetData

Палитра

Объекты TRadioButtons используют CCluster - палитру по умолчанию для всех объектов кластера для отображения элементов с 16 по 18 в палитру стандартного диалога.

1 2 3 4 +====+====+====+====+ CCluster | 16 | 17 | 18 | 18 | +==+=+==+=+==+=+==+=+ Нормальный текст | | +--- Короткая выбранная Выбранный текст ------+ +-------- Короткая нормальная



TRect.


Этот объект представляет прямоугольник. Его поля A и B - это объекты типа TPoint, определяющие верхнюю левую и нижнюю правую точки прямоугольника. TRect имеет методы: Assign, Copy, Move, Grou, Intersect, Union, Contains, Equals и Empty. Объекты типа TRect не являются видимыми элементами и не могут рисовать себя. Однако все видимые элементы являются прямоугольными: их констракторы Init используют параметр Bounds типа TRect для определения области, которую они покрывают.



TRect Objects




Поля

A A: TPoint А - это точка, определяющая верхний левый угол прямоугольника на экране.

B B: Point В - это точка, определяющая нижний правый угол прямоугольника на экране.

Методы

Assign procedure Assign(XA, YA, XB, YB: Integer); Этот метод назначает значения параметров полям прямоугольника. ХА становится А.Х, ХВ становится Х.В и т.д.

Copy procedure Copy(R: TRect); Copy устанавливает все поля равными прямоугольнику R.

Move procedure Move(ADX, ADY: Integer); Перемещает прямоугольник, добавляя ADX к A.X и B.X и добавляя ADY к A.Y и B.Y.

Grow procedure Grow(ADX, ADY: Integer); Изменяет размер прямоугольника, вычитая ADX из A.X, добавляя ADX к B.X, вычитая ADY из A.Y и добавляя ADY к B. Y.

Intersect procedure Intersect(R: TRect); Изменяет положение и размер прямоугольника до области, определенной пересечением текущего положения и R.

Union procedure Union(R: TRect); Изменяет прямоугольник до его объединения с прямоугольником R; т.е. до наименьшего прямоугольника, содержащего этот объект и R.

Contains function Contains(P: TPoint): Boolean; Возвращает True, если прямоугольник содержит точку P.

Equals function Equals(R: TRect): Boolean; Возвращает True, если R равен данному прямоугольнику.

Empty function Empty: Boolean; Возвращает True, если прямоугольник пустой, т.е. не содержит символьного пространства. Таким образом поля A и B равны.



TResourceCollection Objects


+---------+ | TObject | +----+----+ +------+------+ | TCollection | +------+------+ +--------+----------+ | TSortedCollection | +--------+----------+ +--------+----------+ | TStringCollection | +--------+----------+ +=========+===========+ | TResourceCollection | +=====================+

TResourseCollection порожден от TStringCollection и используется с TSourseFile для реализации коллекции ресурсов. Файл ресурсов - это поток, который индексируется ключевыми строками. Следовательно, каждый элемент ресурса имеет целое поле Pos и строковое поле Key. Перекрытие методов TResourseCollection главным образом связано с обработкой дополнительных строк в его элементах. TResourseCollection используется внутри объектов TResourseFile для поддержки индекса файла ресурсов.



TResourceFile Objects


+---------+ | TObject | +----+----+ +=======+=======+ | TResourceFile | +===============+

TResourseFile реализует поток, который может индексироваться ключевыми строками. Когда объекты сохраняются в файле ресурса, используя TResourseFile.Put, задается ключевая строка, которая идентифицирует этот объект. Объект может быть позже получен указанием этой ключевой строки в вызове TResourseFile.Get. Для обеспечения быстрого и эффективного доступа к объектам, хранящимся в файле ресурса, TResourseFile хранит ключевые строки в отсортированной коллекции строк (используя тип TResourseCollection) вместе с позицией и размером данных этого ресурса в файле ресурса. Как и в случае потоков, типы объектов, записываемые и читаемые из файла ресурсов, должны быть зарегистрированы с помощью RegisterType.

Поля

Stream Stream: PStream; Только чтение Указатель на поток, связанный с этим файлом ресурса.

Modified Modified: Boolean; Чтение/Запись Установлен в True, если файл ресурса был модифицирован.

Методы

Init constructor Init(AStream: Pstream); Перекрывается: Никогда Инициализирует файл ресурса, используя поток, заданный через AStream, и устанавливает поле Modified в False. Например:

ResFile.Init(New(TBufStream, Init("MYAPP.RES', stOpenRead, 1024)));

Во время инициализации Init смотрит в заголовке файла ресурсов текущую позицию в потоке. Формат заголовка файла ресурсов:

type TResFileHeader = record Signature: array[14] of Char; ResFileSize: Longint; IndexOffset: Longint; end;

где Signature содержит 'FBPR', ResFileSize содержит размер всего файла ресурсов, за исключением полей Signature и ResFileSize (т.е. размер файла ресурса -8 байт) и IndexOffset содержит смещение коллекции индексов от начала заголовка. Если Init не находит заголовка файла ресурса в текущей позиции AStream, он считает, что создается новый файл ресурса и создает пустой индекс. Если Init видит метку .EXE файла в текущей позиции потока, он просматривает поток до конца файла .EXE и ищет заголовок файла ресурса здесь. Аналогично Init будет пропускать оверлейный файл, добавленный к .EXE файлу (так же как OvrInit пропускает файл ресурса). Это означает, что Вы можете добавить оверлейный файл и файл ресурса (в любом порядке) в конец .EXE файла Вашей программы. (Именно это сделано с выполнимым файлом IDE - TURBO.EXE).


См. так же: TResourceFile.Done

Done destructor Done; virtual; Перекрывается: Никогда Выталкивает файл ресурса, используя TResourseFile.Flush, затем освобождает индекс и поток, указанный полем Stream.

См. так же: TResourceFile.Init, TResourceFile.Flush

Count function Count: Integer; Возвращает число ресурсов, запомненных в файле ресурсов.

См. так же: TResourceFile.KeyOf

Delete procedure Delete(Key: String); Удаляет ресурс, индексируемый ключем Key из файла ресурсов. Пространство, ранее занятое удаленным ресурсом, не используется. Вы можете удалить эту память, используя SwitchTo для создания упакованной копии файла в новом потоке.

См. так же: TResourceFile.SwitchTo

Flush procedure Flush; Если файл ресурса был модифицирован (проверяется поле Modified) Flush сохраняет обновленный индекс в конце потока и обновляет заголовок ресурса в начале потока. Затем Modified устанавливается в False.

См. так же: TResourceFile.Done, TResourceFile.Modified

Get function Get(Key: String): PObject; Ищет Key в индексе файла ресурсов. Возвращает nil, если ключ не найден. Иначе, устанавливает поток на позицию, заданную индексом и вызывает Stream^.Get для создания и загрузки объекта по этому индексу. Например

DeskTop^.Insert(ValidView(ResFile.Get('EditorWindow')));

См. так же: TResourceFile.KeyAt, TResourceFile.Put

KeyAt function KeyAt(I: Integer): String; Возвращает ключевую строку для ресурса с номером i в файле ресурса. Индекс первого ресурса 0 и индекс последнего ресурса TResourseFile.Count-1. Используя Count и KeyAt Вы можете обработать все ресурсы в файле ресурса.

См. так же: TResourceFile.Count

Put procedure Put(Item: PObject; Key: String); Добавляет объект, заданный через Р в файл ресурса с ключевой строкой, заданной в Key. Если индекс содержит Key, новый объект замещает старый. Объект добавляется в конец существующих объектов файла ресурса с использованием Stream^.Put

См. так же: TResourceFile.Get

SwitchTo function SwitchTo(AStream: PStream; Pack: Boolean): PStream; Переключает файл ресурса из его потока в поток, переданный через AStream и возвращает указатель на новый поток. Если параметр Pack равен True, поток будет отбрасывать пустое и неиспользуемое пространство из файла ресурса до записи в новый поток. Это единственный способ сжать файл ресурса. Копирование с параметром Pack = False будет выполняться быстрее, но без сжатия.


TScrollBar Views


+---------+ | TObject | +----+----+ +---+---+ | TView | +---+---+ +======+=====+ | TScrollBar | +============+

Поля

Value Value : Integer; Только чтение Поле Value представляет текущую позицию индикатора полосы скроллинга. Этот маркер выделенный цветом, перемещается по полосе скроллинга, указывая относительную позицию (горизонтальную или вертикальную в зависимости от полосы скроллинга) в тексте относительно всего текста, доступного для скроллинга. Многие события могут прямо или косвенно изменять Value такие, как отметки мышкой на элементах полосы скроллинга, изменение размера окна или изменение текста в скроллере. Аналогично изменения в Value могут потребовать отображение в события. TScroolBar.Init устанавливает Value в 0.

См. так же: TScrollBar.SetValue, TScrollBar.SetParams, TScrollBar.ScrollDraw, TScroller.HandleEvent, TScrollBar.Init

Min Min: Integer; Только чтение Min представляет минимальное значение поля Value. По умолчанию TScrollBar устанавливает Min в 0.

См. так же: TScrollBar.SetRange, TScrollBar.SetParams

Max Max: Integer; Только чтение Max представляет максимальное значение поля Value. По умолчанию TScrollBar устанавливает Max в 0.

См. так же: TScrollBar.SetRange, TScrollBar.SetParams

PgStep PgStep: Integer; Только чтение PgStep - это количество добавляемое или вычитаемое из поля Value полосы скроллинга, когда событие от мышки возникает в любой части области страницы (sbPageLeft, sbPageRight, sbPageUp, sbPageDown) или обнаруженные эквивалентные клавиши (Ctrl-ц, Ctrl-ч, PgUp, PgDn). По умолчанию TScrollBar.Init устанавливает PgStep в 1. PgStep может изменяться при использовании TScrollBar.SetStep, TScrollBar.SetParams и TScroller.SetLimit.

См. так же: TScrollBar.SetStep, TScrollBar.SetParams, TScroller.SetLimit, TScrollBar.ScrollStep

ArStep ArStep: Integer; Только чтение ArStep - это количество добавляемое или вычитаемое из поля Value полосы скроллинга когда отмечена область стрелок (sbLeftArrow, sbRightArrow, sbUpArrow, sbDownArrow) или обнаружены эквивалентные нажатия клавиш. По умолчанию TScrollBar,Init устанавливает ArStep в 1.


См. так же: TScrolBar.SetStep, TScrollBar.SetParam, TScrollBarScrollStep

Методы

Init constructor Init(var Bounds: TRect); Создает и инициализирует полосу скроллинга с границами Bounds, вызывая TView.Init. Value, Max и Min устанавливаются в 0. PgStep и ArStep устанавливаются в 1. Формы элементов полосы скроллинга по умолчанию устанавливаются в TScrollChars. Если Bounds задает Size.X = 1, Вы получите вертикальную полосу скроллинга, иначе - горизонтальную. Вертикальные полосы скроллинга имеют поле GrowMode, установленное в gfGrowLoX + gfGrowHiX + gfGrowHiY; вертикальные полосы скроллинга имеют поле GrowMode, установленное gfGrowLoY + gfGrouHiX + gfGrowHiY.

Load constructor Load(var S: TStream); Создает и загружает полосу скроллинга из потока S, вызывая TView.Load, затем читая 5 целочисленных полей через S.Read.

См. так же: TScrollBar.Store

Draw procedure Draw; virtual; Перекрывается: Никогда Рисует полосу скроллинга в зависимости от текущих Bounds, Value и палитры.

См. так же: TScrollBar.ScrollDraw, TScrollBar.Value

GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на CScrollBar, палитру по умолчанию для полосы скроллинга.

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Никогда Обрабатывает события полосы скроллинга, вызывая TView.HandleEvent, затем анализируя Event.What. События от мышки - это общие сообщения владельцу полосы скроллинга (см. функцию Message), которые должны обрабатываться неявными изменениями полосы скроллинга, например скроллинг текста. TScrollBar.HandleEvent так же определяет, какая часть полосы скроллинга получила отметку от мышки (или эквивалентную клавишу). Поле Value настраивается в соответствии с текущими значениями ArStep и PgStep и индикатор полосы скроллинга перерисовывается.

См. так же: TView.HandleEvent

ScrollDraw procedure ScrollDraw; virtual; Перекрывается: Редко ScrollDraw вызывается при изменении поля Value. Этот псевдоабстрактный метод вызывается передачей сообщения cmScrollBarChanged владельцу полосы скроллинга:



Message(Owner, evBoadcast, cmScrollBarChanged, @Self);

См. так же: TScrollBar.Value, Message функция

ScrollStep function ScrollStep(Part: Integer): Integer; virtual; Перекрывается: Никогда По умолчанию ScrollStep возвращает положительное или отрицательное значение шага в зависимости от части полосы скроллинга, заданной в Part и текущих значений ArStep и PgStep. Аргумент Part должен быть одной из констант sbXXXX описанных в главе 14.

См. так же: TScrollBar.SetStep, TScrollBar.SetParams

SetParams procedure SetParams(AValue,AMin, AMax, APgStep, AArStep: Integer); SetParams устанавливает поля Value, Min, Max, PgStep и ArStep в заданные значения. Если аргументы конфликтуют, выполняются согласования. Например, Min не может быть больше Max, поэтому если AMax < AMin, Max устанавливается в Min. Value должно лежать в диапазоне [Min, Max], поэтому, если Value < AMin, Value устанавливается в Min; если AValue > AMax, Value устанавливается в Max. DrawView перерисовывает полосу скроллинга. Если Value изменяется, будет вызвана ScroolDraw.

См. так же: TView.DrawView, TScrollBar.ScrollDraw, TScrollBar.SetRange, TScrollBar.SetValue

SetRange procedure SetRange(AMin, AMax: Integer); SetRange задает допустимый диапазон для поля Value, устанавливая Min и Max в AMin и AMax. SetRange вызывает SetParams, поэтому DrawView и ScroolBar будут вызываться, если изменения требуют перерисовки полосы скроллинга.

См. так же: TScrollBar.SetParams

SetStep procedure SetStep(APgStep, AArStep: Integer); SetStep устанавливает поля PgStep и ASrStep в APgStep и AArStep. Этот метод вызывает SetParams с остальными аргументами, равными их текущим значениям.

См. так же: TScrollBar.SetParams, TScrollBar.ScrollStep

SetValue procedure SetValue(AValue: Integer); SetValue устанавливает поле Value в AValue, вызывая SetParams с остальными аргументами, установленными в их текущие значения. DrawView и ScrollDraw вызываются, если этот вызов изменяет значение Value.

См. так же: TScroll Bar.SetParams, TView.DrawView, TScrollBar.ScrollDraw, TScroller.ScrollTo

Store procedure Store(var S:TStream); Сохраняет объект TScrollBar в потоке S, вызывая TView.Store, затем записывая 5 целочисленных полей в поток, используя S.Write.

См. так же: TScrollBar.Load

Палитра

Объекты полосы скроллинга используют палитру по умолчанию CScrollBar для отображения в 4 и 5-й элементы палитры стандартной программы.

1 2 3 +===+===+===+ CScrollBar | 4 | 5 | 5 | +=+=+=+=+=+=+ Страница ------+ | +----- Индикатор Стрелки -----------+


TScroller Views


+---------+ | TObject | +----+----+ +----+----+ | TView | +----+----+ +=====+=====+ | TScroller | +=====+=====+ +------+------+ | TTextDevice | +------+------+ +-----+-----+ | TTerminal | +-----------+

Поля

HScrollBar HScrollBar:PScrollBar; Только чтение Указывает на горизонтальную полосу скроллинга, связанную с этим скроллером. Если такой полосы скроллинга нет, HScroolBar равен nil.

VScrollBar VScrollBar: PScrollBar; Только чтение Указывает на вертикальную полосу скроллинга, связанную с этим скроллером. Если такой полосы скроллинга нет, VScroolBar равен nil.

Delta Delta: TPoint; Только чтение Содержит Х (горизонтальная) и Y (вертикальная) компоненты позиции скроллера относительно вирутального видимого элемента. Автоматический скроллинг достигается изменением одной или обоих компонент в ответ, например, на события полосы скроллинга, изменяющих значения поля Value. Ручной скроллинг изменяет Delta, отображает изменения в поле Value полосы скроллинга и приводит к обновлению индикаторов полосы скроллинга.

См. так же: TScroller.ScrollDraw, TScroller.ScrollTo

Limit Limit: TPoint; Только чтение Limit.X Limit.Y - это максимально допустимые значения для Delta.X и Delta.Y.

См. так же: TScroller.Delta

Методы

Init constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar); Создает и инициализирует объект TScroller с заданным размером и полосами скроллинга. Вызывает TView.Init для установки размера видимого элемента. Options устанавливается в ofSelectabble, а EventMask устанавливается в evBroadcast. AHScrollBar должен быть nil, если Вы не хотите горизонтальную полосу скроллинга; аналогично AVScrollBar должен быть nil, если Вы не хотите вертикальной полосы скроллинга.

См. так же: TView.Init, TView.Options, TView.EventMask

Load constructor Load(var S: TStream); Загружает видимый элемент скроллера из потока S, вызывая TView.Load, затем восстанавливает указатели на полосы скроллинга, используя GetPeerViewPtr и читает поля Delta и Limit, используя S.Read.

См. так же: TScroller.Store


ChangeBounds procedure ChangeBounds(var Bounds: TRect); virtual; Перекрывается: Никогда Изменяет размер скроллера, вызывая SetBounds. Если необходимо, скроллер и полосы скроллинга перерисовываются вызовом DrawView и SetLimit.

См. так же: TView.SetBounds, TView.DrawView, TScroller.SetLimit

GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на палитру скроллера по умолчанию CScroller.

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Редко Обрабатывает большинство событий, вызывая TView.HandleEvent. Общие события с командой cmScrollBarChanged, если они пришли от HScrollBar или VScrollBar, приводят к вызову TScroller.ScrollDraw.

См. так же: TView.HandleEvent, TScroller.ScrollDraw

ScrollDraw procedure ScrollDraw; virtual; Перекрывается: Никогда Проверяет, соответствует ли Delta соответствующим позициям полос скроллинга. Если нет - Delta устанавливается в корректное значение и вызывается DrawView для перерисовки скроллера.

См. так же: TView.DrawView, TScroller.Delta, TScroller.HscrollBar, TScroller.VScrollBar

ScrollTo procedure ScrollTo(X, Y: Integer); Устанавливает полосы скроллинга в (X, Y), вызывая HScrollBar^.SetValue(X) и VScrollBar^.SetValue(Y) и перерисовывает видимый элемент, вызывая DrawView.

См. так же: TView.DrawView, TScroller.SetValue

SetLimit procedure SetLimit(X, Y: Integer); Устанавливает Limit.X в X и Limit.Y в Y, затем вызывает HScrollBar^.SetParams и VScrollVar^.SetParams (если эти полосы скроллинга существуют), чтобы настроить их поля Max. Эти вызовы могут привести к перерисовке полосы скроллинга. Наконец вызывается DrawView для перерисовки скроллера, если это необходимо.

См. так же: TScroller.Limit, TScroller.HScroller, TScroller.VScrollBar, TScrollBar.SetParams

SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Перекрывается: Редко Этот метод вызывается при изменении состояния скроллера. Вызов TView.SetState устанавливает или очищает флаги состояния в State. Если новое состояние - sfSelected и sfActive, SetState отображает полосы скроллинга, иначе они скрываются.

Store procedure Store(var S: TStream); Записывает скроллер в поток S, вызывая TView.Store, затем сохраняет ссылки на полосы скроллинга, используя PutPeerViewPtr, наконец записывает значения Delta и Limit, используя S.Write.

См. так же: TScroller.Load, TStream.Write

Палитра

Объекты скроллера используют палитру по умолчанию CScroller для отображения в 6 и 7 элементы палитры стандартной программы.

1 2 +===+===+ CScroller | 6 | 7 | +=+=+=+=+ Нормальный ---+ +---- Подсвеченный


TSortedCollection Objects


+---------+ | TObject | +----+----+ +------+------+ | TCollection | +------+------+ +========+==========+ | TSortedCollection | +========+==========+ +--------+----------+ | TStringCollection | +--------+----------+ +---------+-----------+ | TResourceCollection | +---------------------+

TSortedCollection порожден от TCollection и реализует коллекцию, отсортированную по ключу без дублирования. Сортировка производится методом TStringCollection.Compare, который Вы перекрываете, чтобы задать свое определение упорядочивания элементов. Когда новые элементы добавляются, они автоматически втавляются в порядке, заданном методом Compare. Элементы будут располагаться, используя двоичный метод поиска TStringCollection.Search. Виртуальный метод KeyOf, возвращающий указатель для Compare, так же может быть перекрыт, если Compare требует дополнительной информации.

Методы

Compare function Compare(Key1, Key2: Pointer): Integer; virtual; Перекрывается: Всегда Compare - это абстрактный метод, который должен быть перекрыт во всех порожденных типах. Compare должен сравнивать 2 ключевых значения и возвращать результат:

-------------------------------------------- -1 if Key1 < Key2 0 if Key1 = Key2 1 if Key1 > Key2 --------------------------------------------

Key1 и Key2 - это значения указателей, извлеченных из соответствующей коллеции элементов методом TSortedCollection.KeyOf. Метод TSortedCollection.Search реализует двоичный поиск элементов коллекции, используя Compare для сравнения элементов.

См. так же: TSortedCollection.KeyOf, TSortedCollection.Compare

IndexOf function IndexOf(Item: Pointer): Integer; virtual; Перекрывается: Никогда Использует TSortedCollection.Search для нахождения индекса элемента Item. Если элемент не в коллекции, IndexOf возвращает -1. Реализация TSortedCollection.IndexOf:

if Search(KeyOf(Item), I) then IndexOf := I else IndexOf := -1;

См. так же: TSortedCollection.Search

Insert procedure Insert(Item: Pointer); virtual; Перекрывается: Никогда Если элемент не найден в коллекции, он вставляется в позицию, определенную индексом, вызывает TSortedCollection.Search для определения, существует ли элемент. Если нет, куда вставить его. Реализация TSortedCollection.Insert:


if nоt Search(KeyOf(Item), I) then AtInsert(I, Item)

См. так же: TSortedCollection.Search

KeyOf function KeyOf(Item: Pointer): Pointer; virtual; Перекрывается: Иногда Для данного элемента коллекции KeyOf возвращает соответствующий ключ элемента. По умолчанию TSortedCollection.KeyOf просто возвращает Item. KeyOf перекрывается в случае, когда ключ элемента не совпадает с элементом.

См. так же: TSortedCollection.IndexOf

Search function Search(Key: Pointer; var Index: Integer): Boolean; virtual; Перекрывается: Редко Возвращает True, если элемент, заданный ключем Key, не найден в отсортированной коллекции. Если элемент найден, Index устанавливается в найденный индекс; иначе Index устанавливается в индекс, куда будет помещаться элемент при вставке.

См. так же: TSortedCollection.Compare, TSortedCollection.Insert

TStaticText Dialogs

+---------+ | TObject | +----+----+ +---+---+ | TView | +---+---+ +======+======+ | TStaticText | +======+======+ +---+----+ | TLabel | +--------+

Объекты TStaticText представляют простейшие видимые элементы: они содержат фиксированный текст и игнорируют все события, переданные им. Они используются как сообщения или пассивные метки. Наследники TStaticText выполняют более активную роль.

Поля

Text Text: PString; Только чтение Указатель на строку текста, отображаемую в видимом элементе.

Методы

Init constructor Init(var Bounds: TRect; AText: String); Создает объект StaticText заданного размера, вызывая TView.Init, затем устанавливая текст в NewStr(AText).

См. так же: TView.Init

Load constructor Load(varS: TStream); Создает и инициализирует объект TStaticText из данного потока. Вызывает TView.Load и устанавливает текст с помощью S.ReadStr. Используется совместно с TStaticText.Store для сохранения и чтения статического текстового видимого элемента из потока.

См. так же: TViewLoad, TStaticText.Store, TStream.ReadStr

Done destructor Done; virtual; Перекрывается: Редко Освобождает строку Text, затем вызывает TView.Done для разрушения объекта.



Draw procedure Draw; virtual; Перекрывается: Редко Рисует строку текста внутри видимого элемента, слово при необходимости переносится. Ctrl-M в тексте указывает на начало новой строки. Если строка начинается с Ctrl-C, она центрируется в видимом элементе.

GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на палитру по умолчанию CStaticText.

GetText procedure GetText(varS: String); virtual; Перекрывается: Иногда Возвращает в S строку, на которую указывает Text.

Store procedure TStaticText.Store(var S: TStream); Сохраняет объект TStaticText в потоке, вызывая TView.Store и S.WriteStr. Используется совместно с TStaticText.Store для сохранения и чтения статического текстового видимого элемента из потока.

См. так же: TStaticText.Load, TView.Store, TStream.WriteStr

Палитра

Статический текст использует палитру по умолчанию CStaticText для отображения в 6-й элемент палитры стандартного диалога.

1 +===+ CStaticText | 6 | +=+=+ Цвет текста ---+


TStatusLine Menus


+---------+ | TObject | +----+----+ +----+----+ | TView | +----+----+ +======+======+ | TStatusLine | +=============+

Объект TStatusLine - это видимый элемент, обычно отображаемый внизу экрана. Типичная строка статуса отображает список доступных горячих клавиш, свободную память, время дня, текущий режим редактирования и подсказки пользователя. Отображаемые элементы устанавливаются в связанный список, используя InitStatusLine в TApplication и отображаемый элемент зависит от контекста подсказки текущего видимого элемента. Как и полоса меню и панель экрана, строка статуса обычно принадлежит группе TApplication. Элементы строки статуса - это записи типа TStatusItem, которые содержат поля для текстовой строки, отображаемой в строке статуса, кода ключа, связываемого с горячей клавишей (обычно функциональная клавиша или комбинация Alt -клавиша) и команды, генерируемой, если отображаемый текст отмечен мышкой или нажата горячая клавиша. Строка статуса отображает контекстно-ориентированную подсказку. Каждый объект строки статуса содержит связанный список строк статуса Defs (типа TStatusDef), которые определяют диапазон контекстных подсказок и список элементов статуса, отображаемый, когда текущий контекст подсказки находится в этом диапазоне. Кроме того, может отображаться предопределенная строка в соответствии с текущим контекстом подсказки.

Поля

Items Items: PStatusItem; Только чтение Указатель на текущий связанный список записей типа TStatusItem.

См. так же: TStatusItem

Defs Defs: PStatusDef; Только чтение Указатель на текущий связанный список записей типа TStatusDef. Список для использования определяется текущим контекстом подсказки.

См. так же: TStatusDef, TStatusLine.Update, TStatusLine.Hint

Методы

Init constructor Init(var Bounds: TRect; ADefs: PStatusDef); Создает объект TStatusLine с размером Bounds, вызывая TView.Init. Бит ofPreProcess в Options устанавливается, EventMask устанавливается, включая evBroadcast и GrowMode устанавливается в gfGrowLoY + gfGrowHiX + gfGrowHiY. Поле Defs устанавливается в ADefs. Если ADefs - nil, Items устанавливается в nil, иначе Items устанавливается в ADefs^.Items.


См. так же: TView.Init

Load constructor Load(var S: TStream); Создает объект TStatusLine и загружает его из потока S, вызывая TView.Load, затем читая Defs и Items из потока.

См. так же: TView.Load, TStatusLine.Store

Done destructor Done; virtual; Перекрывается: Никогда Освобождает все Items и Defs в объекте TStatusLine, затем вызывает TView.Done.

См. так же: TView.Done

Draw procedure Draw; virtual; Перекрывается: Редко Рисует строку статуса, выводя строку Text для каждого элемента статуса, затем все подсказки, определенные для данного текущего контекста подсказки за полосой разделителя.

См. так же: TStatusLine.Hint

GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на палитру по умолчанию CStatusLine.

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Редко Обрабатывает события, передаваемые строке статуса, вызывая TView.HandleEvent, затем проверяет на 3 вида специальных событий. Отметки мышкой, которые попадают внутрь прямоугольника, занимаемого элементом статуса, генерируют командное событие с Event.What, установленного в Command, для этого элемента статуса. События от клавиатуры сравниваются с полем KeyCode каждого элемента; соответствие вызывает командное событие с Command этого элемента. Общие события с командой cmCommand, SetChanged заставляют строку статуса перерисовывать себя, чтобы отразить любые горячие клавиши, которые могут быть разрешены или запрещены.

См. так же: TView.HandleEvent

Hint function Hint(AHelpCtx: Word): String; virtual; Перекрывается: Часто Этот псевдоабстрактный метод возвращает пустую строку. Он должен быть перекрыт для обеспечения строки контекстно-ориентированной подсказки для аргумента AHelpCtx. Непустая строка будет рисоваться в строке статуса после полосы разделителя.

См. так же: TStatusLine.Draw

Store procedure Store(var S: TStream); Сохраняет объект TStatusLine в потоке S, вызывая TView.Store, затем записывая все определения статуса и их ассоциированные списки элементов в поток. Сохраненный объект может быть восстановлен используя TStatusLine.Load.

См. так же: TView.Store, TStatusLine.Load

Update procedure Update; Выбирает корректный Items из списка Defs. В зависимости от текущего контекста подсказки, затем вызывает DrawView для перерисовки строки статуса, если элементы были изменены.

См. так же: TStatusLine.Defs

Палитра

Строки статуса используют палитру по умолчанию CStatusLine для отображения в элементы со 2 по 7-й в палитре стандартной программы.

1 2 3 4 5 6 +====+====+====+====+====+====+ CStatusLine | 2 | 3 | 4 | 5 | 6 | 7 | +==+=+==+=+==+=+==+=+==+=+==+=+ Нормальный текст -+ | | | | +-- Выбранный короткий Запрещенный текст -----+ | | +------ Выбранный запрещенный Короткий текст -------------+ +------------ Выбранный нормальный


TStream Objects


+-----------+ | TObject | +-----+-----+ +====+====+ | TStream | +==+===+==+ +-------+ +------+ +----+-------+ +-----+------+ | TDosStream | | TEmsStream | +----+-------+ +------------+ +----+-------+ | TBufStream | +------------+

TStream - это общий абстрактный обект, обеспечивающий полиморфический В/В в и/из устройства памяти. Вы можете создать порожденный объект потока, перекрывая виртуальные методы GetPos, GetSize, Read, Seek, Truncate и Write. Turbo Vision делает это в порожденных потоках TDosStream и TEmsStream. Для порожденного буферизованного потока Вы должны так же перекрыть TStream.Flush.

Поля

Status Status: Integer; Чтение/Запись Указывает текущий статус потока:

Таблица 13.1. Коды ошибок потока.

------------------------------------------------- Коды ошибок TStream ------------------------------------------------- stOk Нет ошибок stError Ошибка доступа stInitError Нельзя инициализироввать поток stReadError Чтение за концом файла stWriteError Нельзя расширить поток stGetError Get для незарегистрированного типа stPutError Put для незарегистрированного типа -------------------------------------------------

Если Status <> stOK, все операции над потоком будут запрещены до тех пор, пока не будет вызван Reset.

ErrorInfo ErrorInfo: Integer; Чтение/Запись Содержит дополнительнительную информацию когда Status не stOK. Для значений Status: stError, stInitError, stReadError, stWriteError, ErrorInfo содержит код ошибки DOS или EMS, если такой существует. Когда Status stGetError, ErrorInfo содержит IDE типа объекта (поле ObjType в TStreamRec) не зарегистрированного типа объекта. Когда Status - stPutError, ErrorInfo содержит смещение VMT в сегменте данных (поле VmtLink в TStreamRec) не зарегистрированного типа объекта.

Методы

CopyFrom procedure CopyFrom(var S: TStream; Count: Longint); Копирует Count байт из потока S в вызывающий поток. Например:

NewStream := New(TEmsStream, Init(OldStream^.GetSize)); OldStream^.Seek(0); NewStream^.CopyFrom(OldStream, OldStream^.GetSize);


См. так же: TStream.GetSize, TObject.Init

Error procedure Error(Code, Info: Integer); virtual; Перекрывается: Иногда Вызывается, если возникла ошибка потока. По умолчанию TStream.Error сохраняет Code и Info в полях Status и ErrorInfo. Затем, если глобальная переменная StreamError не nil, вызывает процедуру, заданную в StreamError. После возникновения ошибки, все операции над потоком запрещены до тех пор, пока не будет вызван Reset.

См. так же: TStream.Reset, StreamError переменная

Flush procedure Flush; virtual; Перекрывается: Иногда Абстрактный метод, который должен быть перекрыт, если Ваш порожденный тип реализует буфер. Этот метод может выталкивать любые буфера, очищая буфер чтения и записывая буфер вывода. По умолчанию TStream.Flush ничего не делает.

См. так же: TDosStream.Flush

Get function Get: PObject; Читает объект из потока. Объект должен быть предварительно записан в поток через TStream.Put. Get вначале читает ID типа объекта (слово) из потока. Затем он находит соответствующий тип объекта, сравнивая ID с полем ObjType всех зарегистрированных типов объектов (см. тип TStreamRec). Наконец вызывает констрактор Load этого типа объекта для создания и загрузки объекта. Если ID типа объекта, считанного из потока, равен 0, Get возвращает указатель nil; если ID типа объекта не зарегистрирован (используя RegisterType) Get вызывает TStream.Error и возвращает указатель nil; иначе Get возвращает указатель на вновь созданный объект.

См. так же: TStream.Put, RegisterType, TStreamRec, Load методы

GetPos function GetPos: Longint; virtual; Перекрывается: Всегда Возвращает текущую позицию в потоке. Этот абстрактный метод должен всегда перекрываться.

См. так же: TStream.Seek

GetSize function GetSize: Longint; virtual; Перекрывается: Всегда Возвращает размер потока. Это абстрактный метод и должен перекрываться.

Put procedure Put(P: PObject); Записывает объект в поток. Объект позже можно считать из потока, используя TStream.Get. Put вначале находит регистрационную запись типа этого объекта, сравнивая смещение VMT объекта с полем VmtLink всех зарегистрированных типов объектов (см. тип TStreamRec). Затем записывает ID типа объекта (поле ObjType регистрационной записи) в поток, и наконец вызывает метод Store этого типа объекта для записи объекта. Если аргумент Р, переданный в Put - nil, Put записывает в поток слово, содержащее 0. Если тип объекта в Р не зарегистрирован (испольуя RegisterType), Put вызывает TStream.Error и ничего не пишет в поток.



См. так же: TStream.Get, RegisterType, TStreamRec, Store методы

Read procedure Read(var Buf; Count: Word); virtual; Перекрывается: Всегда Это абстрактный метод и должен перекрываться во всех порожденных типах. Read должен читать Count байт из потока в Buf и перемещать текущую позицию потока на Count байт. Если произошла ошибка, Read должен вызывать Error и заполнять Buf Count байтами, равными 0.

См. так же: TStream,Write, TStream.Error

ReadStr function ReadStr: PString; Читает строку из текущей позиции потока, возвращая указатель PString. TStream.ReadStr вызывает GetMem для распределения (Length+1) байт для строки.

См. так же: TStream.WriteStr

Reset procedure Reset; Сбрасывает ошибочное условие потока, устанавливая Status и ErrorInfo в 0. Этот метод позволяет Вам продолжать обработку потока после ошибочной ситуации, которую Вы скорректировали.

См. так же: TStream.Status, TStream.ErrorInfo, sfXXXX коды ошибок

Seek procedure Seek(Pos: Longint); virtual; Перекрывается: Всегда Это абстрактный метод и должен перекрываться во всех потомках. TStream.Seek устанавливает текущую позицию в Pos байт, начиная от начала потока. Начало потока - позиция 0.

См. так же: TStream.GetPos

Truncate procedure Truncate; virtual; Перекрывается: Всегда Это абстрактный метод и должен перекрываться во всех потомках. TStream.Truncate удаляет все данные в потоке от текущей позиции до конца.

См. так же: TStream.GetPos, TStream.Seek

Write procedure Write(var Buf; Count: Word); virtual; Перекрывается: Всегда Это абстрактный метод и должен перекрываться во всех потомках. Write записывает Count байт из Buf в поток и перемещает текущую позицию потока на Count байт. Если возникла ошибка, Write должен вызывать Error.

См. так же: TStream.Read, TStream.Error

WriteStr procedure WriteStr(P: PString); Записывает строку P^ в поток, начиная с текущей позиции.

См. так же: TStream.ReadStr


TStringCollection Objects


+---------+ | TObject | +----+----+ +------+------+ | TCollection | +------+------+ +--------+----------+ | TSortedCollection | +--------+----------+ +========+==========+ | TStringCollection | +========+==========+ +---------+-----------+ | TResourceCollection | +---------------------+

TStringCollection порожден от TSortedCollection и реализует сортированный список ASCII строк. Метод TStringCollection.Compare перекрывается для задания обычного лексикографического упорядочения строк ASCII. Вы можете перекрыть Compare для задания другого упорядочения, такого как для неанглийских наборов символов.

Методы

Compare function Compare(Key1, Key2: Pointer): Integer; virtual; Перекрывается: Иногда Сравнивает строки Key1^ и Key2^ : возвращает -1, если Key1 < Key2; 0, если Key1 = Key2 и +1, если Key1 > Key2.

См. так же: nTStringCollection.Search

FreeItem procedure FreeItem(Item: Pointer); virtual; Перекрывается: Редко Удаляет строку Item^ из отсортированной коллекции и освобождает строку.

GetItem function GetItem(var S: TStream): Pointer; virtual; Перекрывается: Редко По умолчанию читает строку из TStream, вызывая SReadStr.

См. так же: TStream.ReadStr

PutItem procedure PutItem(var S: TStream; Item: Pointer); virtual; Перекрывается: Редко По умолчанию записывает строку Item^ в TStream, вызывая S. WriteStr.

См. так же: TStream.WriteStr



TStringList Objects


+-----------+ | TObject | +---+---+---+ +------+ +------+ +======+======+ +------+--------+ | TStringList | | TStrListMaker | +=============+ +---------------+

TStringList предоставляет механизм для доступа к строкам, хранящимся в потоке. Каждая строка, хранящаяся в списке строк идентифицируется уникальным номером (ключем) между 0 и 65,535. Списки строк занимают меньше памяти, чем обычные строки, поскольку строки хранятся в потоке, а не в памяти. Кроме того, списки строк легко решают проблему настройки программ на языки, поскольку строки не "встроены" в программу. TStringList имеет методы только для доступа к строкам; для создания списка строк Вы должны использовать TStrListMaker. Заметим, что TStringList и TStrListMaker имеют один ID типа объекта (поле ObjType в TStreamRec) и следовательно, не могут регистрироваться и использоваться одновременно в одной программе.

Методы

Load constructor Load(var S:TStream); Загружает индекс списка строк из потока S и хранит ссылку на S так, что TStringLis.Get может обращаться к потоку при чтении строк. Считая, что TStringList был зарегистрирован, используя RegisterType(RStringList), здесь показано, как считать список строк (созданный с использованием TStrListMaker и TResourseFile.Put) из файла ресурса:

ResFile.Init(New(TBufStream, Init('MYAPP.RES', stOpenRead, 1024))); Strings := PStringList(ResFile.Get('Strings'));

См. так же: TStrListMaker.Init, TStringList.Get

Done destructor Done; virtual; Перекрывается: Никогда Освобождает память, распределенную под список строк.

См. так же: TStrListMaker.Init, TStringList.Done

Get function Get(Key: Word): String; Возвращает строку, заданную через Key, или пустую строку, если нет строки с данным Key. Например:

P := @FileName; FormatStr(S, Strings^.Get(sLoadingFile), P);

См. так же: TStringListMaker.Put



TStrListMaker Objects


+-----------+ | TObject | +---+---+---+ +--------+ +------+ +======+========+ +------+------+ | TStrListMaker | | TStringList | +===============+ +-------------+

TStrListMaker - это простой тип объекта, используемый для создания списка строк, который используют с TStringList. Следующий фрагмент кода показывает как создавать и сохранять список строк в файле ресурса.

const sInformation = 100; sWarning = 101; sError = 102; sLoadingFile = 200; sSavingFile = 201;

var ResFile: TResourceFile; S: TStrListMaker;

begin RegisterType(RStrListMaker); ResFile.Init(New(TBufStream, Init('MYAPP.RES', stCreate, 1024))); S.Init(16384, 256); S.Put(sInformation, 'Information'); S.Put(sWarning, 'Warning'); S.Put(sError, 'Error'); S.Put(sLoadingFile, 'Loading file #s.'); S.Put(sSavingFile, 'Saving file #s.'); ResFile.Put(@S,'Strings'); S.Done; ResFile.Done; end;

Методы

Init constructor Init(AStrSize, AIndexSize: Word); Создает в памяти список строк размера AStrSize с индексом из AIndexSize элементов. Буфер строк и буфер индексов заданного размера распределяются в куче. AStrSize должен быть достаточно велик для хранения всех строк, добавляемых в список строк - каждая строка занимает свою длину плюс 1 байт. При добавлении строк в список строк (используя TStrListMaker.Put) строится индекс строк. Строки с последовательными ключами (такими как sInformation, sWarning и sError в предыдущем примере) записываются в одну индексную запись до 16. AIndexSize должен быть достаточно большим для добавления всех сгенерированных индексных записей. Каждый элемент индекса занимает 6 байт.

См. так же: TStringList.Load, TStrListMaker.Done

Done destructor Done; virtual; Освобождает память, распределенную этим объектом.

См. так же: TStrListMaker.Init

Put procedure Put(Key: Word; S: String); Добавляет String к списку строк (с заданным числовым Key).

Store procedure Store(var S: TStream); Записывает список строк в поток.



TTerminal TextView


+---------+ | TObject | +----+----+ +---+---+ | TView | +---+---+ +-----+-----+ | TScroller | +-----+-----+ +------+------+ | TTextDevice | +------+------+ +=====+=====+ | TTerminal | +===========+

TTerminal реализует "немой" терминал с буферизованным чтением и записью строк. По умолчанию - это циклический буфер размером 64К байт.

Поля

BufSize BufSize: Word; Только чтение Размер буфера терминала в байтах.

Buffer Buffer: PTerminalBuffer; Только чтение Указывает на первый байт буфера терминала.

QueFront QueFront: Word; Только чтение Смещение (в байтах) первого байта запомненного в буфере терминала.

QueBack QueBack: Word; Только чтение Смещение (в байтах) последнего байта, запомненного в буфере терминала.

Методы

Init constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar; ABufSize: Word); Перекрывается: Иногда Создает объект TTerminal с данным Bounds, горизонтальной и вертикальной полосами скроллинга и буфером, вызывая TTextDevice.Init с аргументами Bounds и скроллерами, затем создает буфер (указываемый через Buffer) с BufSize равным ABufSize. GrowMode устанавливается в gfGrowHiX + gfGrowHiY. QueFront и QueBack инициализируются в 0, указывая на пустой буфер. Курсор выводится в начале видимого элемента (0, 0).

См. так же: TScroller.Init

Done destructor Done; virtual; Перекрывается: Иногда Освобождает буфер и вызывает TTextDevice.Done для освобождения объекта.

См. так же: TScroller.Done, TTextDevice.Done

BufDec procedure BufDec(var Val: Word); Используется для манипуляции смещением очереди с кольцевым переносом: если Val = 0, Val устанавливается в BufSize-1; иначе Val уменьшается.

См. так же: TTerminal.BufInc

BufInc procedure BufInc(var Val: Word); Используется для манипуляции смещением очереди с кольцевым переносом: увеличивает Val на 1, если Val >= BufSize, Val устанавливается в 0.

См. так же: TTerminal.BufDec

CalcWidth function CalcWidth: Integer; Возвращает длину самой длинной строки в текстовом буфере.

CanInsert function CanInsert(Amount: Word): Boolean: Возвращает True, если число байт, заданное в Amount, можно вставить в буфер без уничтожения верхней строки.


Draw procedure Draw; virtual; Перекрывается: Редко Вызывается когда скроллер TTerminal должен быть перерисован. Например, когда отмечена полоса скроллинга, когда изменен размер видимого элемента, когда изменены значения Delta или когда добавление текста приводит к скроллингу.

NextLine function NextLine(Pos: Word): Word; Возвращает смещение в буфере начала строки, которое следует за позицией Pos.

См. так же: TTerminal.PrevLines

PrevLines function PrevLines(Pos: Word; Lines: Word): Word; Перекрывается: Иногда Возвращает смещение в буфере начала строки, которое стоит перед позицией Pos.

StrRead function StrRead(var S: TextBuf) : Byte; virtual; Перекрывается: Иногда Абстрактный метод, возвращающий 0. Вы должны перекрыть его, если хотите, чтобы порожденный тип мог читать строки из текстового буфера.

StrWrite procedure StrWrite(var S:TextBuf; Count: Byte); virtual; Перекрывается: Редко Вставляет Count строк текста, заданного в S, в терминальный буфер. Этот метод управляет любым требуемым скроллингом, перерисовывая видимый элемент с помощью DrawView.

См. так же: TView.DrawView

QueEmpty function QueEmpty: Boolean; Возвращает True, если QueFront равна QueBack.

См. так же: TTerminal,QueFront, TTerminal.QueBack

Палитра

Теримальные объекты используют палитру по умолчанию CScroller для отображения элементов 6 и 7 в палитру стандартной программы.

1 2 +===+===+ CScroller | 6 | 7 | +=+=+=+=+ Нормальный ---+ +---- Подсвеченный


TTextDevice TextView


+---------+ | TObject | +----+----+ +---+---+ | TView | +---+---+ +-----+-----+ | TScroller | +-----+-----+ +======+======+ | TTextDevice | +======+======+ +-----+-----+ | TTerminal | +-----------+

TTextDevice - это скроллингуемый TTY тип просмотра текста/ драйвера устройства. Кроме полей и методов, наследуемых от TScroller, TTextDevice определяет виртуальные методы для чтения и записи строк в и из устройства. TTextDevice существует как базовый тип для порождения реальных терминальных драйверов. TTextDevice использует констрактор и дестрактор TScroller.

Методы

StrRead function StrRead(var S:TextBuf): Byte; virtual; Перекрывается: Часто Абстрактный метод, возвращающий по умолчанию 0. Вы должны перекрыть его в любом порожденном типе для чтения строки текстового устройства в S. Этот метод возвращает число прочитанных строк.

StrWrite procedure StrWrite(var S: TextBuf; Count: Byte); virtual; Перекрывается: Всегда Абстрактный метод для записи строки на устройство. Он должен перекрыватся в порожденных типах. Например, TTerminal.StrWrite вставляет Count строк текста, заданных в S в терминальный буфер и перерисовывает видимый элемент.

Палитра

Объекты текстового устройства используют палитру по умолчанию CScroller для отображения в 6 и 7 элементы палитры стандартной программы.

1 2 +===+===+ CScroller | 6 | 7 | +=+=+=+=+ Нормальный ---+ +---- Подсвеченный



TView Views


+---------+ | TObject | +----+----+ +======+======+ | TView | +++++++++++++++ +--------------+|+--------------+ | +------+|+------+ | | |+------+|+------+| | +---+----+ +------+|+------+ +---+----+ | TGroup | |+------+|+------+| | TFrame | +--------+ +------+|+------+ +--------+ +-------+ +----+----+ +--------+ +----+-----+ | TButton | +-----+----+ | TCluster | +---------+ | THistory | +----------+ |+------+ +----------+ +-------+ +-----+-----+ |+--------+ +-----+-----+ | TScroller | | +------+-----+ | TMenuView | +-----------+ | | TScrollBar | +-----------+ +--------+ +------------+ +-------+| +-----+------+ |+--------+ +------+------+ | | TInputLine | | +------+------+ | TBackGround | | +------------+ | | TListViewer | +-------------+ | | +-------------+ +------+------+ +------+------+ | TStatusLine | | TStaticText | +-------------+ +-------------+

Включите оператор

uses Views;

в программы, которые используют объекты TView, TFrame, TScrollBar, TScroller, TListViewer, TGroup, TWindow. Трудно представить программу на Turbo Vision, которая не использует эти объекты. В программах на Turbo Vision редко создаются экземпляры объектов TView. Тип объекта TView обеспечивает основные поля и методы своим потомкам.

Поля

Owner Owner: PGroup; Только чтение Указывает на объект TGroup, который владеет этим видимым элементом. Если nil, видимый элемент не имеет владельца. Видимый элемент отображается внутри видимого элемента владельца и будет отсекаться по прямоугольнику владельца.

Next Next: PView; Только чтение Указывает на следующий равный видимый элемент в Z-порядке. Если это последний подэлемент, Next указывает на Owner первого подэлемента.

Origin Origin: TPoint; Только чтение Координаты (X, Y) верхнего левого угла видимого элемента относительно Origin владельца.

См. так же: MovTo, Locate

Size Size: TPoint; Только чтение Размер видимого элемента.

См. так же: GrowTo, Locate

Cursor CurSor: TPoint; Только чтение Положение аппаратного курсора внутри видимого элемента. Курсор видим только если видимый элемент активен (sfFocused) и курсор включен (sfCursorVis). Форма курсора или подчеркивание или блок (определен sfCursorIns).


См. так же: SetCursor, ShowCursor, HideCursor, NormalCursor, BlockCursor

GrowMode GrowMode: Byte; Чтение/Запись Определяет, как видимый элемент будет увеличиваться, когда его владелец изменяет размер. GrowMode определяется одной или более масками:

Рис. 13.1. Отображение бит в GrowMode.

+--- GrowMode --+ msb lsb +-+-+-+--- gfGrowAll = $0F +=+=+=+=+++++++++ +++=+++++++++++++ +-+-+ | | | | +--- gfGrowLoX = $01 | | | | +----- gfGrowLoY = $02 Неопределено | | +------- gfGrowHiX = $04 | +--------- gfGrowHiY = $08 +----------- gfGrowRel = $10

Пример: GrowMode := gfGrowLoX or gfGrowLoY;

См. так же: gfXXXX константа grow mode

DragMode DragMode: Byte; Чтение/Запись Определяет поведение видимого элемента при перемещении мышкой. Биты DragMode определены:

Рис. 13.2. Отображение бит в DragMode.

+--- DragMode --+ msb lsb +-+-+-+----------- dmLimitAll = $F0 +++++++++=+=+=+=+ +++++++++=+=+++++ | | | | | +--- dmDragMove = $01 | | | | +----- dmDragGrow = $02 | | | +----------- dmLimitLoX = $10 | | +------------- dmLimitLoY = $20 | +--------------- dmLimitHiX = $40 +----------------- dmLimitHiY = $80

Маски DragMode определены в "Константы DragMode dmXXXX" главы 14.

См. так же: TView.DragView

HelpCtx HelpCtx: Word; Чтение/Запись Контекст подсказки видимого элемента. Когда видимый элемент активен, это поле представляет контекст подсказки программы, если номер контекста подсказки не hcNoContext (в этом случае нет контекста подсказки).

См. так же: TView.GetHelpCtx

State State: Word; Только чтение Состояние видимого элемента представлено набором бит в поле State. Многие методы TView проверяют и/или изменяют поле State, вызывая TView.SetState. TView.GetState (AState) возвращает True, если State видимого элемента равна AState. Биты State мнемонически представлены константами, описанными в "Константы флагов состояния sfXXXX" главы 14.

Options Options: Word; Чтение/Запись Флаги Options определяют поведение видимого элемента. Биты Options определены:

Рис. 13.3. Биты в Options.



+-------- TView.Options --------+ msb lsb +-+------------------- ofCentered = $0300 +=+=+=+=+=+=+++++=+=+=+=+=+=+=+=+ +++=+=+=+=+++++++++++++++++++++++ +----+----+ | | | | | | | | | +--- ofSelectable = $0001 | | | | | | | | | +----- ofTopSelect = $0002 Неопределено | | | | | | | +------- ofFirstClick = $0004 | | | | | | +--------- ofFramed = $0008 | | | | | +----------- ofPreProcess = $0010 | | | | +------------- ofPostProcess = $0020 | | | +--------------- ofBuffered = $0040 | | +----------------- ofTileable = $0080 | +------------------- ofCenterX = $0100 +--------------------- ofCenterY = $0200

Для детального описания флагов см. "Константы флагов опций ofXXXX" главы 14.

EventMask EventMask: Word; Чтение/Запись EventMask - это битовая маска, которая определяет, какие классы событий будут распознаваться видимым элементом. По умолчанию EventMask разрешает evMouseDown, evKeyDown и evCommand. Назначение EventMask равным $FFFF заставляет видимый элемент реагировать на все классы событий; а значение 0 приводит к тому, что видимый элемент не реагирует на любые события. Для детального описания классов событий см. "Константы событий evXXXX" главы 14.

См. так же: HandleEvent методы

Методы

Init constructor Init(var Bounds: TRect); Перекрывается: Часто Создает объект TView с прямоугольником Bounds. Init вызывает TObject.Init и создает поля нового TView со значениями:

------------------------------------------------------------ Owner nil Next nil Origin (Bounds.A.X, Bounds.A.Y) Size (Bounds.B.X - Bounds.A.X, Bounds.B.Y - Bounds.A.Y) Cursor (0, 0) GrowMode 0 DragMode dmLimitLoY HelpCtx heNoContext State sfVisible Options 0 EventMask evMouseDown + evKeyDown + evCommand ------------------------------------------------------------

Заметим, что TObject.Init заполняет нулями все поля потомков TView. Всегда вызывайте TView.Init до инициализиции любых полей.

См. так же: TObject.Init

Load constructor Load(var S: TStream); Перекрывается: Часто Создает объект TView и загружает его из потока S. Размер данных, читаемых из потока должен точно соответствовать размеру данных, записанных в поток методом Store. Если видимый элемент содержит указатели на равные видимые элементы, Load должен использовать GetPeerViewPtr для чтения этих указателей. Перекрытый констрактор Load всегда должен вызывать констрактор Load своего предка. По умолчанию TView.Load устанавливает поля Owner и Next в nil и читает оставшиеся поля из потока.



См. так же: TView.Store, TStream.Get, TStream.Put

Done destructor Done; virtual; Перекрывается: Часто Скрывает видимый элемент и затем, если он имеет кладельца, удаляет его из группы.

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Всегда Центральный метод, через который реализована вся обработка событий Turbo Vision. Поле What параметра Event содержит класс события (evXXXX) и оставшиеся поля Event описывают событие. Для указания, что он обработал событие, HandleEvent должен вызывать ClearEvent. HandleEvent почти всегда перекрывается в порожденных объектных типах. TView.HandleEvent обрабатывает события evMouseDown следующим образом: если видимый элемент не выбран (sfSelected) и не запрещен (sfDisabled) и если видимый элемент - выбираемый (ofSelectable), то видимый элемент выбирает себя, вызывая Select. Другие события в TView.HandleEvent не обрабатываются.

См. так же: TView.ClearEvent

BlоckCursor procedure BlоckCursor; Перекрывается: Никогда Устанавливает sfCursorIns, чтобы изменить курсор в форму блока. Курсор будет видимым только если установлен sfCursorVis (и видимый элемент так же видим).

См. так же: sfCursorIns, sfCursorVis, TView.NormalCursor, TView.ShowCursor, TView.HideCursor

CalcBounds procedure CalcBounds(var Bounds: TRect; Delta: TPoint); virtual; Перекрывается: Редко Когда владелец видимого элемента изменяет размер, он вызывает CalcBounds и ChangeBounds для всех подэлементов. CalcBounds должен вычислять новые границы видимого элемента на основе Delta, на которое изменился размер его владельца, и возвращает новые границы в Bounds. TView.CalcBounds вычисляет новые границы, используя флаги, заданные в поле TView.GrowMode.

См. так же: TView.GetBounds, TView.ChangeBounds, gfXXXX константы grow mode

ChangeBounds procedure ChangeBounds(var Bounds: TRect); virtual; Перекрывается: Редко Должен изменять границы видимого элемента (поля Origin и Size) на прямоугольник, заданный параметром Bounds. После изменения границ ChangeBounds должен перерисовать видимый элемент. ChangeBounds вызывается различными методами TView, но не должен вызываться прямо.



См. так же: TView.Locate, TView.MoveTo, TView.GrowTo

ClearEvent procedure ClearEvent(var Event: TEvent); Стандартный метод используется в HandleEvent для указания, что видимый элемент успешно обработал событие. Устанавливает Event.What в evNоthing и Event.InfoPtr в @Self.

См. так же: HandleEvent методы

CommandEnabled function CommandEnabled(Command: Word): Boolean; Возвращает True, если команда Command разрешена, иначе - False. Заметим, что когда Вы изменяете модальное состояние, Вы можете запретить или разрешить необходимые команды; однако, когда Вы возвращаетесь в предыдущее модальное состояние, оригинальный набор команд должен быть восстановлен.

См. так же: TView.DisableCommand, TView.EnableCommand, TView.SetCommands

DataSize function DataSize: Word; virtual; Перекрывается: Редко DataSize должен возвращать размер данных читаемый из и записываемый в запись данных с помощью SetData и GetData. Механизм записи данных обычно используется только в видимых элементах, которые реализуют элементы управления для диалоговых окон.

См. так же: TView.GetData, TView.SetData

DisableCommands procedure DisableCommands(Commands: TCommandSet); Запрещает команды, указанные в аргументе Commands.

См. так же: TView.CommandEnabled, TView.EnableCommands, TView.SetCommands

DragView procedure DragView(Event: TEvent; Mode: Byte; var Limits: TRect; MinSize, MaxSize: TPoint); Перемещает мышкой видимый элемент, используя режим перемещения, заданный флагами dmXXXX в Mode. Limits указывает прямоугольник (в координатной системе владельца) внутри которого может перемещаться видимый элемент, а Min и Max указывают минимальный и максимальный размеры видимого элемента, которые он может принимать. Событие, приводящее к операции перемещения мышкой, требуется в Event для различения перемещения мышкой от использования клавиш курсора.

См. так же: TView.DragMode, dmXXXX константы drag mode

Draw procedure Draw; virtual; Перекрывается: Всегда Вызывается, когда видимый элемент должен перерисовать себя. Draw должен покрывать всю область видимого элемента. Этот метод должен соответственно перекрываться для каждого порожденного объекта. Draw редко вызывается прямо, поскольку более эффективно использовать DrawView, который рисует только ожидаемые видимые элементы, т.е. когда часть или весь видимый элемент видим на экране. При необходимости Draw может вызвать GetClipRect для получения прямоугольника, который необходимо перерисовать и затем рисовать только эту область. Для сложных видимых элементов это может значительно улучшить производительность.



См. так же: TView.DrawView

DrawView procedure DrawView; Вызывает Draw, если TView.Exposed возвращает True, указывая, что видимый элемент ожидается (см. sfExposed). Вы должны вызвать DrawView (а не Draw), когда Вам необходимо перерисовать видимый элемент после изменения, которое воздействует на его видимое отображение.

См. так же: TView.Draw, TGroup.ReDraw, TView.Exposed

EnableCommands procedure EnableCommands(Commands: TCommandSet); Разрешает все команды в аргументе Commands.

См. так же: TView.DisableCommands, TView.GetCommands, TView.CommandEnabled, TView.SetCommands

EndModal procedure EndModal(Command: Word); virtual; Перекрывается: Никогда Завершает текущее модальное состояние и возвращает Command, как результат вызова функции ExecView, которая создала это модальное состояние.

См. так же: TGroup.ExecView, TGroup.Execute, TGroup.EndModal

EventAvail function EventAvail: Boolean; Возвращает True, если событие доступно для GetEvent.

См. так же: TView.MouseEvent, TView.KeyEvent, TView.GetEvent

Execute function Execute: Word; virtual; Перекрывается: Рддко Вызывается из TGroup.ExecView когда видимый элемент становится модальным. Если видимый элемент разрешает модальное выполнение, он должен перекрыть Execute для выполнения цикла событий. Результатом Execute становится значение, возвращаемое из TGroup.ExecView. TView.ExecView просто возвращает cmCancel.

См. так же: sfModal, TGroup.Execute, TGroup.ExecView

Exposed function Exposed: Boolean; Возвращает True, если любая часть видимого элемента видна на экране.

См. так же: sfExposed, TView.DrawView

GetBounds procedure GetBounds(var Bounds: TRect); Возвращает в переменной Bounds граничный прямоугольник видимого элемента в координатной системе его владельца. Bounds.A устанавливается в Origin, а Bounds.B устанавливается в Origin + Size.

См. так же: TView. Origin, TView.Size, TView.CalcBounds, TView.ChangeBounds, TView.SetBounds, TView.GetExtent

GetClipRect procedure GetClipRect(var Clip: TRect); Возвращает в переменной Clip минимальный прямоугольник, который требуется перерисовать в вызове Draw. Для сложных видимых элементов Draw может использовать GetClipRect для значительного улучшения производительности.



См. так же: TView.Draw

GetColor function GetColor(Color: Word): Word; Отображает индексы палитры младшего и старшего байта Color в физические атрибуты символа, проходя через палитру видимого элемента и палитры всех его владельцев.

См. так же: TView.GetPalette

GetCommands procedure GetCommands(var Commands: TCommandSet); Возвращает в Commands текущий набор команд.

См. так же: TView.CommandsEnabled, TView.EnableCommands, TView.DisableCommands, TView.SetCommands

GetData procedure GetData(var Rec); virtual; Перекрывается: Редко Должна копировать DataSize байт из видимого элемента в запись данных Rec. Механизм записей данных обычно используется только в видимых элементах, которые реализуют элементы управления для диалоговых окон. По умолчанию TView.GetData ничего не делает.

См. так же: TView.DataSize, TView.SetData

GetEvent procedure GetEvent(var Event: TEvent); virtual; Перекрывается: Редко Возвращает следующее доступное событие в TEvent. Возвращает evNothing, если событие недоступно. По умолчанию он вызывает GetEvent владельца видимого элемента.

См. так же: TView.EventAvail, TProgram.Idle, TView.HandleEvent, TView.PutEvent

GetExtent procedure GetExtent(var Extent: TRect); Возвращает в переменной Extent прямоугольник видимого элемента. Extent.A устанавливается в (0,0), а Extent.B устанавливается в Size.

См. так же: TView.Origin, TView.Size, TView.CalcBounds, TView.ChangeBounds, TView.SetBounds, TView.GetBounds

GetHelpCtx function GetHelpCtx: Word; virtual; Перекрывается: Редко Должна возвращать контекст подсказки видимого элемента. По умолчанию TView.GetHelpCtx возвращает значение поля HelpCtx или возвращает hcDragging, если видимый элемент перемещается мышкой (см. sfDragging).

См. так же: HelpCtx

GetPalette function GetPalette: PPalette; virtual; Перекрывается: Всегда Должна возвращать указатель на палитру видимого элемента или nil, если видимый элемент не имеет палитры. GetPalette вызывается из GetColor, WriteChar и WriteStr при преобразовании индексов палитры в физические атрибуты символов. При возвращаемом значении nil трансляция цвета этим видимым элементом не производится. GetPalette почти всегда перекрывается в порожденных типах объектов.



См. так же: TView.GetColor, TView.WriteXXXX

GetPeerViewPtr procedure GetPeerViewPtr(var S: TStream; var P); Загружает указатель Р равного видимого элемента из потока S. Равный видимый элемент - это видимый элемент с тем же владельцем, что и у этого видимого элемента; например TScroller содержит 2 равных видимых элемента HScrollBar и VScrollBar. GetPeerViewPtr должен использоваться только внутри констрактора Load для чтения значений указателей, которые были записаны при вызове PutPeerViewPtr из метода Store. Загруженное в Р значение не является действительным до тех пор, пока владелец видимого элемента не завершит полностью операцию Load; следовательно ссылка по указателю на равный видимый элемент внутри констрактора Load не дает корректного значения.

См. так же: TView.PutPeerViewPtr, TGroup.Load, TGroup.Store

GetState function GetState(AState: Word): Boolean; Возвращает True, если состояние в AState установлено в поле State.

См. так же: State, TView.SetState

GrowTo procedure GrowTo(X, Y: Integer); Увеличивает или уменьшает видимый элемент на данный размер, используя вызов TView.Locate.

См. так же: TView.Origin, TView.Locate, TView.MoveTo

Hide procedure Hide; Прячет видимый элемент, вызывая SetState для очистки флага sf Visible в State.

См. так же: sfVisible, TView.SetState, TView.Show

HideCursor procedure HideCursor; Прячет курсор, очищая бит sfCursorVis в State.

См. так же: sfCursorVis, TView.ShowCursor

KeyEvent procedure KeyEvent(var Event: TEvent); Возвращает в переменной Event следующее событие evKeyDown. Он ожидает игнорируя все другие события до тех пор, пока событие от клавиатуры не будет доступно.

См. так же: TView.GetEvent, TView.EventAvail

Locate procedure Locate(var Bounds: TRect); Изменяет границы видимого элемента на Bounds. Видимый элемент перерисовывается в его новом положении. Locate вызывает SizeLimits для проверки, что данные Bounds правильны, затем вызывает ChangeBounds для изменения границ и перерисовывает видимый элемент.

См. так же: TView.GrowTo, TView.MoveTo, TView.ChangeBounds



MakeFirst procedure MakeFirst; Перемещает видимый элемент на вершину списка подэлементов владельца. Вызов MakeFirst соответствует PutInFrontOf(Owner^.First).

См. так же: TView.PutInFrontOf

MakeGlobal procedure MakeGlobal(Source: TPoint; var Dest:TPoint); Перобразует координаты в точке Sourсe из локальных (видимый элемент) в глобальные (экран) и возвращает результат в Dest. Source и Dest могут быть одной переменной.

См. так же: TView.MakeGlobal, TView.MouseInView

MakeLocal procedure MakeLocal(Source: TPoint; var Dest:TPoint); Преобразует координаты точки Source из глобальных (экран) в локальные (видимый элемент) и возвращает результат в Dest. Полезно для преобразования поля Event.Where в событии evMouse из глобальных координат в локальные. Например MakeLocal(Event.Where, MouseLoc).

См. так же: TView.MakeGlobal, TView.MouseInView

MouseEvent function MouseEvent(var Event: TEvent; Mask: Word): Boolean; Возвращает следующее событие от мышки в Event. Возвращает True, если возвращенное событие есть в аргументе Mask, и False, если возникло событие evMouseUp. Этот метод позволяет Вам трассировать мышку, когда ее кнопка нажата, например в операциях отметки блока мышкой в текстовых редакторах. Приведем фрагмент программы HandleEvent, которая следит за мышкой с курсором видимого элемента.

procedure TMyView.HandleEvent(var Event: TEvent); begin TView.HandleEvent(Event); case Event.What of evMouseDown: begin repeat MakeLocal(Event.Where, Mouse); SetCursor(Mouse.X, Mouse.Y); until not MouseEvent(Event, evMouseMove); ClearEvent(Event); end; . end; end;

См. так же: EventMasks, TView.KeyEvent, TView.GetEvent

MouseInView function MouseInView(Mouse: TPoint): Boolean; Возвращает True, если аргумент Mouse (заданный в глобальных координатах) внутри видимого элемента.

См. так же: TView.MakeLocal

MoveTo procedure MoveTo(X, Y: Integer); Перемещает Origin в точку (X, Y) относительно владельца видимого элемента. Size видимого элемента не изменяется.

См. так же: Origin, Size, TView.Locate, TView.GrowTo



NextView function NextView: PView; Возвращает указатель на следующий подэлемент в списке подэлементов владельца. Возвращается nil, если видимый элемент последний в списке владельца.

См. так же: TView.PRevView, TView.Prev, TView.Next

NormalCursor procedure NormalCursor; Очищает бит sfCursorIns в State, переводя курсор в режим подчеркивания. Если sfCursorVis установлен, новый курсор будет отображаться.

См. так же: sfCursorIns, sfCursorVis, TView.HideCursor, TView.BlockCursor, TView.HideCursor

Prev function Prev: PView; Возвращает указатель на предыдущий подэлемент в списке подэлементов владельца. Если видимый элемент первый в списке владельца, Prev возвращает последний видимый элемент в списке. Заметим, что TView.Prev интерпретирует список как кольцевой, в то время как TView.PrevView интерпретирует его как линейный.

См. так же: TView.NextView, TView.PrevView, TView.Next

PrevView function PrevView: PView; Возвращает указатель на предыдущий подэлемент в списке подэлементов владельца. Возвращается nil, если видимый элемент - первый в списке владельца. Заметим, что TView.Prev интерпретирует список как кольцевой, а TView.PrevView - как линейный.

См. так же: TView.NextView, TView.Prev

PutEvent procedure PutEvent(var Event: TEvent); virtual; Перекрывается: Редко Помещает событие, заданное в Event, в очередь событий, в результате чего это событие будет следующим событием, возвращаемым GetEvent. Этим способом в очередь может быть помещено только одно событие. Это часто используется видимыми элементами, генерирующими командные события, например:

Event.What := evCommand; Event. Command := cmSaveAll; Event.InfoPtr := nil; PutEvent(Event);

По умолчанию TView.PutEvent вызывает PutEvent владельца видимого элемента.

См. так же: TView.EventAvail, TView.GetEvent, TView.HandleEvent

PutInFontOf procedure PutInFontOf(Target: PView); Помещает видимый элемент перед видимым элементом Target в списке подэлементов владельца. Вызов

TView.PutInFontOf(Owner^.First);

эквивалентен TView.MakeFirst. Этот метод работает, изменяя указатели в списке подэлементов. В зависимости от позиции других видимых элементов и их состояния, PutInFrontOf может отсекать закрываемые видимые элементы. Если видимый элемент - выбираемый (см. ofSelectable) и помещается сверху всех других подэлемиентов, этот видимый подэлемент становится выбранным.



См. так же: TView.MakeFirst

PutPeerViewPtr procedure PutPeerVieewPtr(var S: TStream; P: PView); Сохраняет указатель P на равный видимый элемент в потоке S. Равный видимый элемент - это видимый элемент с тем же владельцем, что и этот видимый элемент. PutPeerViewPtr должен использоваться только внутри метода Store для записи значений указателей, которые позже могут быть считаны с помощью GetPeerViewPtr в констракторе Load.

См. так же: TView.PutPeerViewPtr, TGroup.Load, TGroup.Store

Select procedure Select; Выбирает видимый элемент (см. sfSelected). Если владелец видимого элемента активизируется, то видимый элемент так же активизируется (см. sfFocused). Если видимый элемент имеет установленный флаг ofTopSelect в поле Options, то видимый элемент перемещается на вершину списка подэлементов владельца (используя вызов TView.MakeFirst).

См. так же: sfSelected, sfFocused, ofTopSelect, TView.MakeFirst

SetBounds procedure SetBounds(var Bounds: TRect); Устанавливает граничный прямоугольник видимого элемента в значения параметра Bounds. Поле Origin устанавливается в Bounds.A и поле Size устанавливается в Bounds.B - Bounds.A. Метод SetBounds вызывается только из перекрытого метода ChangeBounds - Вы не должны вызывать SetBounds прямо.

См. так же: TView.Origin, TView.Size, TView.CalcBounds, TView.ChangeBounds, TView.GetBounds, TView.GetExtent

SetCommands procedure SetCommands(Commands: TCommandSet); Изменяет текущий набор команд на заданный аргументом Commаnds.

См. так же: TView.EnableCommands, TView.DisableCommands

SetCursor procedure SetCursor(X, Y: Integer); Перемещает аппаратный курсор в точку (X,Y) используя относительные координаты видимого элемента (локальные). (0,0) - это верхний левый угол.

См. так же: TView.MakeLocal, TView.HideCursor, TView.ShowCursor

SetData procedure SetData(var Rec); virtual; Перекрывается: Редко SetData должен копировать DataSize байт из записи данных Rec в видимый элемент. Механизм записи данных обычно используется только в видимых элементах, которые реализуют элементы управления для диалоговых окон. По умолчанию TView.SetData ничего не делает.



См. так же: TView.DataSize, TView.GetData

SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Перекрывается: Иногда Устанавливает или очищает флаг состояния в поле TView.State. Параметр AState задает флаг состояния для модификации (см. sfXXXX), а параметр Enable указывает, будет этот флаг устанавливаться (True) или выключаться (False). TView.SetState затем выполняет соответствующие действия для отражения нового состояния, такие как перерисовка видимых элементов, которые появляются, когда данный видимый элемент скрывается (sfVisible) или перепрограммирование аппаратуры, когда изменяется форма курсора (sfCursorVis и sfCursorIns). SetState иногда перекрывается для выполнения дополнительных действий, основанных на флагах состояний. Например, тип TFrame перекрывает SetState для своей перерисовки, когда окно выбирается или перемещается мышкой.

procedure TFrame.SetState(AState: Word; Enable: Boolean); begin TView.SetState(AState, Enable); if AState and (sfActive + sfDragging) <> 0 then DrawView; end;

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

procedure TMyView.SetState(AState: Word; Enable: Boolean); const MyCommands = [cmOut, cmCopy, cmPaste, cmClear] begin TView.SetState(AState, Enable); if AState = sfSelected then if Enable then EnableCommands(MyCommands) else DisableCommands(MyCommands); end;

См. так же: TView.GetState, TView.State, sfXXXX константы state flag

Show procedure Show; Показывает видимый элемент, вызывая SetState для установки флага sfVisible в поле State.

См. так же: TView.SetState

ShowCursor procedure ShowCursor; Включает аппаратный курсор, устанавливая sfCursorVis. Заметим, что по умолчанию курсор невидим.

См. так же: sfCursorVis, TView.HideCursor

SizeLimits procedure SizeLimits(var Min, Max: TPoint); virtual; Перекрывается: Иногда Возвращает, в переменных Min и Max, минимальное и максимальное значения, которые может принимать поле Size.



См. так же: TView.Size

Store procedure Store(var S: TStream); Перекрывается: Часто Сохраняет видимый элемент в потоке S. Размер данных, записываемых в поток, должен точно соответствовать размеру данных, читаемых из потока констрактором Load видимого элемента. Если видимый элемент содержит указатель на равные видимые элементы, Store должен использовать PutPeerViewPtr для записи этих указателей. Перекрытый метод Store должен всегда вызывать родительский метод Store. По удолчадию TView.Store пишет все поля, кроме Owner и Next в птоток.

См. так же: TView.Load, TStream.Get, TStream.Put

TopView function TopView: PView; Возвращает указатель на текущий модальный видимый элемент.

Valid function Valid(Commands: Word): Boolean; virtual; Перекрывается: Иногда Этот метод используется для проверки правильности видимого элемента после его создания (с использованием Init или Load) или в момент, когда заканчивается модальное состояние (при вызове EndModal). Значение параметра Command, равное cmValid (ноль), указывает, что видимый элемент должен проверять результат своего создания: Valid(cmValid) должен возвращать True, если видимый элемент был успешно создан и готов к использованию; иначе - False. Любое другое (не ноль) значение параметра Command указывает, что текущее модальное состояние (такое как модальное диалоговое окно) должно завершаться с результирующим значением Command. В этом случае Valid должна проверять правильность видимого элемента. Valid должна сообщить пользователю, если видимый элемент неправильный, например используя программу MessageBox в модуле StdDlg. Типы объектов, определенные в модуле StdDlg содержат ряд примеров перекрытия Valid. По умолчанию TView.Valid просто возвращает True.

См. так же: TGroup.Valid, TDialog.Valid, TProgram.ValidView

WriteBuf procedure TView.WriteBuf(X, Y, W, H: Integer; var Buf); Записывает буфер на экран, начиная с координат (X,Y) и заполняет область шириной W и высотой H. Должен использоваться только в методах Draw. Обычно пареметр Buf типа ТDrawBuffer, но может быть любым массивом слов, где каждое слово содержит символ в младшем байте и атрибут в старшем байте.



См. так же: TView.Draw

WriteChar procedure TView.WriteChar(X, Y: Integer; Ch: Char; Color: Byte; Count: Integer); Начиначя с точки (X,Y) записывает Count копий символа Ch цветом, определенным элементом с номером Color, в палитре текущего видимого элемента. Должен использоваться только в методах Draw.

См. так же: TView>draw

WriteLine procedure TView.WriteLine(X, Y, W, H: Integer; var Buf); Записывает строку, содержащуюся в буфере Buf на экран, начиная с точки (X,Y) и внутри прямоугольника, определенного шириной W и высотой H. Если H больше 1, строка будет повторяться Н раз. Должен использоваться только в методе Draw. Параметр Buf обычно типа TDrawBuffer, но может быть любым массивом слов, где каждое слово содержит символ в младшем байте и атрибут - в старшем байте.

См. так же: TView.Draw

WriteStr procedure TView.WriteStr(X, Y: Integer; Str: String; Color: Byte); Записывает строку Str c цветом элемента с номером Color в палитре видимого элемента, начиная с точки (X,Y). Должен использоваться только в методе Draw.

См. так же: TView.Draw


TWindow Views


+---------+ | TObject | +----+----+ +----+----+ | TView | +----+----+ +----+----+ | TGroup | +-+--+--+-+ +----------+ | +------------+ +====+====+ +----+-----+ +------+-------+ | TWindow | | TDeskTop | | TProgram | +====+====+ +----------+ +------+-------+ +----+----+ +------+-------+ | TDialog | | TApplication | +---------+ +--------------+

Объект TWindow - это группа, которая обычно владеет объектом TFrame, объектом интерьера TScroller и одним или двумя объектами TScrollBar. Объект TFrame задает обычную рамку, размещает необязательный заголовок и номер и функциональные кнопки (закрытия, масштабирования, перемещения). Объекты TWibdow имеют встроенные возможности перемещения и масштабирования с помощью мышки и клавиатуры. Они могут масштабироваться и закрываться отметкой мышки соответствующих кнопок. Они так же "знают" как работать с полосами скроллинга и скроллера. Окна с номерами от 1 до 9 могут выбираться клавишами Alt-n (n от 1 до 9).

Поля

Flags Flags: Byte; Чтение/Запись Поле Flags содержит комбинацию следующих бит:

+ TWindow.Flags + | | msb lsb +=+=+=+=+=+=+=+=+ +++=+=+++++++++++ +--+--+ | | | +- wfMove = $01 | | | +--- wfGrow = $02 Неопределено | +----- wfClose = $04 +------- wfZoom = $08

Описание флагов окна см. в "Константы флагов окна wfXXXX" главы 14.

ZoomRect ZoomRect: TRect; Только чтение Нормальные несмасштабированные границы окна.

Number Number: Integer; Чтение/Запись Номер этого окна. Если TWindow.Number в диапазоне 1 - 9, номер будет появляться в заголовке рамки и окно может быть выбрано клавишами Alt-n (n от 1 до 9).

Palette Palette: Integer; Чтение/Запись Определяет какая палитра окна будет использоваться: wpBlueWindow, wpCyanWindow, wpGrayWindow. Палитра по умолчанию wpBlueWindow.

См. так же: TWindow.GetPalette, wpXXXX константы

Frame Frame: PFrame; Только чтение Frame - это указатель на объект TFrame, связанный с окном.

См. так же: TWindow.InitFrame

Title Title: RString; Чтение/Запись Строка символов, определяющая (необязательный) заголовок, который появляется в рамке.


Методы

Init constructor Init( var Bounds: TRect; ATitle: TTitleStr; ANumber: Integer); Вызывает TGroup.Init(Bounds). Устанавливает State в sfShadow. Устанавливает по умолчанию Options в (ofSelectable + ofTopSelect). Устанавливает GrowMode в gfGrowAll + gfGrowRel. Устанавливает Flags в (wfMove + wfGrow + wfClose + wfZoom). Устанавливает поле Title в NewStr(ATitle), поле Number в ANumber. Вызывает InitFrame, и если поле Frame не nil, вставляет его в группу окна. Наконец, устанавливает ZoomRect в Bounds.

См. так же: TFrame.InitFrame

Load constructor Load(var S: TStream); Создает и загружает окно из потока S, вызывая TGroup.Load, затем читая дополнительные поля, введенные в TWindow.

См. так же: TGroup.Load

Done destructor Done; virtual; Перекрывается: Иногда Освобождает окно и подэлементы.

Close procedure Close; virtual; Перекрывается: Редко Закрывает и освобождает окно обычно в ответ на командное событие cmClose. Соответствует вызову дестрактора Done.

GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на палитру, заданную индексом палитры в поле Palette.

См. так же: TWindow.Palette

GetTitle function GetTitle(MaxSize: Integer): TTitleStr; virtual; Перекрывается: Редко Должна возвращать строку заголовка окна. Если строка заголовка больше, чем MaxSize символов, GetTitle должна пытаться сократить ее; иначе она будет отсекаться отбрасыванием текста после MaxSize символов. TFrame.Draw вызывает Owner^.GetTitle для получения строки текста, отображаемой в рамке. По умолчанию GetWindow.Title возвращает строку Title^ или пустую строку, если поле Title равно nil.

См. так же: TWindow.Title, TFrame.Draw

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Часто Вначале вызывает TGroup.HandleEvent, затем обрабатывает специфические для TWindow события: события evCommand обрабатываются, если поле TWindow.Flags разрешает эту операцию: cmResize (переместить или изменить размер окна, используя метод TView.DrawView), cmClose (закрыть окно, используя метод TWindow.Close) и cmZoom (масштабировать окно, используя метод TWindow.Zoom). События evKeyDown со значением KeyCode, равным kbTab или kbShiftTab обрабатываются, выбирая следующий или предыдущий выбираемый подэлемент (если он существует). Событие evBroadcast со значением Command, равным cmSelectWindowNum, обрабатывается выбором окна, если поле Event.InfoInt равно TWindow.Number.



См. так же: TGroup.HandleEvent, wfXXXX константы

InitFrame procedure InitFrame; virtual; Перекрывается: Редко Создает объект TFrame для окна и сохраняет указатель на эту рамку в поле TWindow.Frame. InitFrame вызывается из TWindow.Init и никогда не должен вызываться прямо. InitFrame может быть перекрыт для создания экземпляра объекта, порожденного от TFrame.

См. так же: TWindow.Init

SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Перекрывается: Редко Вначале вызывает TGroup.SetState. Затем, если AState равно sfSelected, активизирует или деактивизирует окно и все его подэлементы, используя вызов SetState(sfActive, Enable) и вызов TView.EnebleCommands или TView.DisableCommands для cmNext, cmPrev, cmResize, cmClose и cmZoom.

См. так же: TGroup.SetState, EnableCommands, DisableCommands

SizeLimits procedure SizeLimits(var Min, Max: TPoint); virtual; Перекрывается: Редко Перекрывает TView.SizeLimits. Вызывает TView.SizeLimits, затем изменяет Min на значение, хранимое в глобальной переменной MinWindowSize.

См. так же: TView.SizeLimits, MinVinSize переменная

StandardScrollBar function StandardScrollBar(AOptions: Word): PScrollBar; Создает, вставляет и возвращает указатель на "стандартную" полосу скроллинга для окна. "Стандартный" означает, что полоса скроллинга вставляется в рамку окна не закрывая углов или кнопки масштабирования. Параметр AOptions может быть либо sbGorizontal для создания горизонтальной полосы скроллинга внизу окна, либо sbVertical для создания вертикальной полосы скроллинга в правой стороне окна, либо может быть скомбинировано с sbHandleKeyboard, чтобы разрешить полосе скроллинга откликаться на клавиши стрелок и страниц, а не только отметок от мышки.

См. так же: sbXXXX константы scroll bar

Store procedure TWindow.Store(var S: TStream); Сохраняет окно в потоке S, вызывая TGroup.Store, затем записывая дополнительные поля, определенные в TWindow.

См. так же: TGroup.Store

Zoom procedure TWindow.Zoom; virtual; Перекрывается: Редко Масштабирует окно. Этот метод обычно вызывается в ответ на команду cmZoom (генерируемую при отметке кнопки масштабирования). Zoom принимает во внимание относительные размеры окна и его владельца, и значение ZoomRect.



См. так же: cmZoom, ZoomRect

Палитра

Объекты окна используют палитры по умолчанию CBlueWindow (для текстовых окон), CCyanWindow (для сообщений) и CGrayWindow (для диалоговых окон).

1 2 3 4 5 6 7 8 +===+===+===+===+===+===+===+===+ CGrayWindow | 24| 25| 26| 27| 28| 29| 30| 31| +===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+ CCyanWindow | 16| 17| 18| 19| 20| 21| 22| 23| +===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+ CBlueWindow | 8 | 9 | 10| 11| 12| 13| 14| 15| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Пассивная -+ | | | | | | +-- Зарезервировано рамка | | | | | | Активная рамка ----+ | | | | +---- Выбранный текст | | | | скроллера Кнопка рамки ----------+ | | +-------- Нормальный текст | | скроллера Страница полосы -----------+ +------------ Зарезервировано скролинга


Удаление "мусора" из старого кода.


Есть простой путь. Сейчас Вы знаете, что сущность программирования отдельной программы на Turbo Vision сконцентрирована в методах Init, Draw и HandleEvent программы. Наилучший подход к встраиванию существующей программы - это вначале написать интерфейс Turbo Vision, который заменит существующий, а затем выбрать необходимый код из старой программы. Большинство этого кода попадет в методы Init, Draw и HandleEvent новых видимых элементов. Вам потребуется определенное время, чтобы осмыслить сущность Вашей программы так, чтобы Вы могли отделить код интерфейса от кода, выполняющего работу Вашей программы. Это может быть непросто, поскольку Вы привыкли представлять программу по-другому. Работа по переносу будет включать определенное переписывание для того, чтобы научить новые объекты представлять самих себя, а так же приведет к отбрасыванию большого количества старого интерфейсного кода. Это не должно приводить к новым ошибкам и Вы будете делать это с удовольствием. Если Вы переносите программу, Вы будете удивлены, обнаружив как много кода предназначено для управления пользовательским интерфейсом. Когда Вы позволите Turbo Vision работать за Вас, большая часть работы пользовательского интерфейса, которую Вы делали раньше, просто исчезнет. Мы обнаружили это, когда переносили интегрированную среду Turbo Pascal в Turbo Vision. Мы освободили компилятор, редактор и отладчик от старого пользовательского интерфейса и перенесли их в пользовательский интерфейс, написанный на Turbo Vision.



Удаление потока.


Когда Вы заканчиваете использование потока, Вы вызываете его метод Done точно так же, как Вы вызывали Close для дискового файла. Как и для любого объекта Turbo Vision, Вы делаете это

Dispose(SomeStream, Done);

который удаляет объект потока.



Украденные события.


Вторая возможность, которую необходимо рассмотреть - это то, что другой объект мог "украсть" событие. Т.е. событие обработано и очищено не тем объектом, которому Вы намеревались передать событие. Это может происходить по нескольким причинам. Первая - это дублирование объявлений команд: если две команды назначены одному константному значению, они могут обрабатываться взаимозаменяемо. Вот почему необходимо отследивать, каким константам назначаются какие значения, особенно в ситуации, когда Вы повторно используете код модулей. Вторая возможная причина в дублировании меток команд, особенно при повторном использовании кода. Так, если Вы назначаете команду cmJump и существует метод HandleEvent в каком-то другом объекте, который уже откликается на команду cmJump и о котором Вы забыли, это может привести к конфликтам. Всегда просматривайте не используют ли другие объекты события, которые кажутся "потерянными".



Управление.


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



Управление экраном.


Одно из ограничений при использовании Turbo Vision касается прямого вывода на экран. Вместо использования Write и Writeln для выдачи информации пользователю, Вы передаете информацию в Turbo Vision, который гарантирует, что информация появится в нужное время и в нужном месте. Основной блок построения программ в Turbo Vision - видимый элемент. Видимый элемент - это объект Turbo Pascal, который управляет прямоугольной областью экрана. Например, полоса меню на вершине экрана - это видимый элемент. Любое действие программы в этой области экрана (например отметка мышкой в полосе меню) будет обрабатываться видимым элементом, который контролирует эту область. Меню - это видимые элементы так же как и окна, строка статуса, кнопки, полосы скроллинга, диалоговые окна и обычно даже простая строка текста. В общем случае все, что Вы видите на экране программы Turbo Vision должно быть видимым элементом и наиболее важное свойство видимого элемента то, что он знает как представлять себя на экране. Так, например, когда Вы хотите сделать систему меню, Вы просто говорите Turbo Vision, что Вы хотите создать полосу меню, содержащую определенные меню, а Turbo Vision управляет остальным. Наиболее зримым примером видимого элемента, о котором Вы, вероятно, не будете думать как о видимом элементе, является сама программа. Она управляет всем экраном, но Вы не замечаете этого, поскольку программа устанавливает другие видимые элементы для управления их взаимодействий с пользователем. Как Вы увидите, то, что представляется пользователю как объект (такой как окно) часто является группой связанных видимых элементов.



Управление объектами в потоке.


Все, что Вы должны сделать - это определить для потока, какие объекты он должен обрабатывать, чтобы он знал как совместить данные с VMT. Затем Вы можете поместить объекты в поток и получить их обратно без малейших усилий. Но как можно читать и писать в один поток такие различные объекты как TDeskTop и TDiаlog и во время компиляции не знать даже какие объекты будут обрабатываться? Это сильно отличается от В/В традиционного Паскаля. В действительности поток может обрабатывать даже новые типы объектов, которые еще не были созданы в момент компиляции потока. Это решается с помощью регистрации. Каждому типу объекта Turbo Vision (и новым типам объектов, которые Вы порождаете из иерархии) назначается уникальный регистрационный номер. Этот номер записывается в поток перед данными объекта. Затем, когда Вы читаете объект из потока, Turbo Vision берет регистрационный номер и на основании его знает сколько данных прочитать и какую VMT подсоединить к Вашим данным.



Установить бит.


Чтобы установить бит используйте оператор or. Например, чтобы установить бит ofPostProcess в поле Options для кнопки MyButton используйте:

MyButton.Options := MyButton.Options or ofPostProcess;

Вы можете использовать сложение для установки битов, только если Вы абсолютно уверены что делаете. Например, если вместо предыдущего кода Вы используете

MyButton.Options := MyButton.Options + ofPostProcess;

Ваша операция будет работать если и только если бит ofPostProcess не был установлен. Если бит уже был установлен, двоичное сложение приведен к переносу в следующий бит (ofBuffered), устанавливая или очищая в зависимости от его значения. Другими словами: прибавление битов может привести к неожиданным эффектам. Вместо этого используйте операцию or. Заметим, что Вы можете установить несколько бит в одной операции. Следующий код будет устанавливать 2 различных флага:

MyScroller.GrowMode := MyScroller.GrowMode or (gfGrowHiX + gfGrowHiY);



Установка и получение данных.


Сейчас, когда Вы сконструировали достаточно сложное диалоговое окно, Вам нужно узнать как использовать его. Вы создали интерфейс пользователя, теперь Вам необходимо создать интерфейс с программой. Элементы управления бесполезны, если Вы не знаете как получить информацию от них! Вы должны иметь возможность сделать 2 вещи: установить начальные значения элементов управления при открытии диалогового окна и прочитать значения, когда диалоговое окно закрывается. Заметим, что Вы не будете модифицировать данные вне диалогового окна, если оно закрыто не успешно. Если пользователь решил отменить диалоговое окно, Вы будете игнорировать все изменения, сделанные в то время, когда диалоговое окно было открыто. К счатью возможности Turbo Vision позволяют сделать это. Ваша программа управляет записью информации в диалоговое окно при его открытии. Когда пользователь заканчивает работу с диалоговым окном, Вашей программе требуется проверить, отменено диалоговое окно или было закрыто нормально. Если оно было отменено, Вы просто работаете без модификации записи. Если диалоговое окно успешно закрыто, Вы можете прочитать запись из диалогового окна в той же форме, в которой она была передана в него. Методы SetData и GetData используются для копирования данных в и из видимого элемента. Каждый видимый элемент имеет методы SetData и GetData. Когда группа (такая как TDialog) инициализируется с помощью вызова SetData, она передает данные дальше, вызывая методы SetData для каждого из его подэлементов.

Примечание: Когда Вы вызываете SetData для группы, Вы передаете ему запись данных, которая содержит данные для каждого видимого элемента в группе. Вам необходимо расположить данные для каждого из видимых элементов в том же порядке, в каком они были вставлены в группу. Вам так же требуется установить правильный размер данных для каждого из видимых элементов. Каждый видимый элемент имеет метод DataSize, который возвращает размер данных видимого элемента. Каждый видимый элемент копирует DataSize данных из этой записи данных, а затем передвигает указатель, чтобы показать следующему видимому элементу, с какого места следует начинать. Если данные видимого подэлемента имеют неверный размер, каждый последующий подэлемент будет копировать неверные данные. Если Вы создаете новый видимый элемент, и добавляете в него поля данных, не забудьте перекрыть DataSize, SetData и GetData, так чтобы они обрабатывали правильные значения. Порядок обработки и размеры данных всецело в Ваших руках. Компилятор не будет возвращать сообщения, если Вы сделаете ошибку. После выполнения диалогового окна, Ваша программа должна вначале убедиться, что диалоговое окно не было отменено, затем вызвать GetData для передачи информации в Вашу программу. Так, в Вашем примере Вы инициализируете по порядку кластер независимых кнопок, метку, кластер зависимых кнопок, метку, строку ввода до 128 символов, метку и две кнопки (OK и Cancel). Таблица 2.1 приводит все требуемые для этого данные.


Таблица 2.1. Данные для элементов управления диалогового окна.

------------------------------------------------------------ Элементы управления Требуемые данные ------------------------------------------------------------ Независимые кнопки Word Метка Нет Зависимые кнопки Word Метка Нет Строка ввода string[128] Метка Нет Кнопка Нет Кнопка Нет ------------------------------------------------------------

Видимые элементы, которые не имеют данных (такие как метки и кнопки), используют метод GetData, который они наследуют от TView и который ничего не делает. Это означает, что когда Вы получаете и устанавливаете данные, Вы можете пропустить метки и кнопки. Таким образом, Вы должны отслеживать только 3 видимых элемента в диалоговом окне: зависимые кнопки, независимые кнопки и строку ввода. Как сказано ранее, каждый элемент хранит свои данные в поле типа Word. Данные входной строки хранятся в строке. Вы можете установить запись данных для диалогового окна в глобальном типе:

DialogData = record CheckBoxData: Word; RadioButtonData: Word; InputLineData: string[128]; end;

Теперь все, что Вам необходимо сделать - это инициализировать запись при запуске программы (например в MyApp.Init) установить данные, когда Вы входите в диалоговое окно и прочитать их, когда диалоговое окно успешно закрыто. Это проще сказать в Паскале, чем по-русски! После того, как Вы объявите тип, Вы объявляете глобальную переменную:

var DemoDialogData: DialogData;

затем добавляете одну строку до выполнения диалогового окна и одну после:

Dialog^.SetData(DemoDialogData); Control := DeskTop^.ExecView(Dialog); if Control <> cmCancel then Dialog^.GetData(DemoDialogData);

и добавляете 6 строк в метод TMyApp.Init, чтобы установить начальные значения для диалогового окна.

{ TVGUID16.PAS }

with DemoDialogData do begin CheckboxData := 1; RadioButtonData := 2; InputLineData := 'Phone home.'; end;

Рис. 2.11. Диалоговое окно с установленными начальными значениями.

+=[ю]======= Demo Dialog Box =============+ | | | Cheeses Consistency | | +----------------+ +--------------+ | | | [ ] HVarti | | [*] Solid | | | | [ ] Tilset | | [ ] Runny | | | | [ ] Jarlsberg | | [ ] Melted | | | +----------------+ +--------------+ | | | | Delivery instructions | | Phone home. | | | | OK m Cancel m | | ^^^^^^^^ ^^^^^^^^ | +==========================================+

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


Установка потока.


Для использования потока Вы должны просто инициализировать его. Точный синтаксис констрактора Init будет изменяться в зависимости от типа используемого потока. Например, если Вы открываете поток DOS, Вам требуется передать имя файла DOS и режим доступа (чтение, запись, чтение/запись) к файлу, содержащему поток. Например, чтобы инициализировать буферизованный поток DOS для загрузки объекта панель экрана в программу, Вам требуется только:

var SaveFile: TBufStream; begin SaveFile.Init('SAMPLE.DSK', stOpen, 1024); .

После того, как Вы инициализировали поток, Вы можете его использовать. TStream - это абстрактный механизм потока и Вы не можете создать экземпляр от него, но все объекты потоков порождены от TStream. Они включают TDosStream, обеспечивающий дисковый В/В, TBufStream, обеспечивающий буферизованный В/В с диска (полезен, если Вы читаете или пишите большое количество небольших кусков данных) и TEmsStream, который пересылает объекты в EMS память (особенно полезен для реализации быстрых ресурсов). Turbo Vision так же реализует индексированные потоки с указателем на место в потоке. Изменяя положение указателя, Вы можете осуществлять прямой доступ к потоку.



Установка поведения.


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



Установка видимого элемента.


До обсуждения, что делает видимый элемент, давайте рассмотрим, как видимые элементы представляются на экране. Положение видимого элемента определяется двумя точками: верхним левым углом (называемым началом) и нижним правым углом. Каждая из этих точек представлена в объекте полем типа TPoint (TPoint описана в следующем разделе). Поле Origin типа TPoint указывает начало видимого элемента, а поле Size представляет нижний правый угол. Заметим, что Origin - это точка в системе координат владельца видимого элемента: если Вы открываете окно на панели экрана, его поле Origin указывает координаты X и Y окна относительно начала панели экрана. С другой стороны, поле Size - это точка относительно начала данного объекта. Оно говорит Вам как далеко отстоит нижний правый угол от начальной точки, но если Вы не знаете где начало видимого элемента расположено внутри другого видимого элемента, Вы не сможете определить где реально находится этот угол.



В случае ошибки.


Наконец, процедура Error определяет что произойдет, когда возникнет ошибка. По умолчанию TStream.Error просто устанавливает 2 поля (Status и ErrorInfo) в потоке. Если Вы хотите выполнить другие действия, например сгенерировать ошибку времени выполнения или вывести ошибку в диалоговое окно, Вам необходимо перекрыть процедуру Error.



Ваша первая программа в Turbo Vision.


Программа Turbo Vision всегда начинается с создания экземпляра объекта, порожденного от TApplication. В следующем примере Вы создадите порожденный от TApplication тип с именем TMyApp и будете перекрывать методы TApplication. От нового типа Вы создадите экземпляр MyApp.

Примечание: До конца этой главы мы часто будем ссылаться к MyApp. Когда Вы пишите собственную программу в Turbo Vision, Вы, вероятно, назовете ее как-то иначе, в соответствии с назначением этой программы. Мы используем MyApp, поскольку это короче, чем сказать "экземпляр объекта, порожденного от TApplication". (В программе существует только 1 объект TApplication.) Начиная со следующего примера, мы создадим программу. Вместо того, чтобы приводить листинг программы каждый раз, мы будем включать только добавляемые или изменяемые части в тексте. Если Вы создаете сами эту программу, Вы должны иметь хорошее представление, что делается в каждом изменении функциональности. Мы так же рекомендуем Вам попробовать модифицировать примеры.

Примечание: Некоторые стадии из создания примеров представлены на Вашем дистрибутивном диске. Имена файлов указаны вместе с кодом примеров и они соответствуют именам, объявленным в операторе program.

Главный блок TVGUID01.PAS (и каждой программы в Turbo Vision) выглядит подобно:

program TFirst;

uses App;

type TMyApp = object(TApplication) end;

var MyApp: TMyApp;

begin MyApp.Init; MyApp.Run; MyApp.Done; end.

Заметим, что Вы еще не добавили никаких новых функций в TMyApp. Обычно Вы никогда не объявляете полностью новый объектный тип без полей или методов. Вы просто объявляете переменную MyApp, как экземпляр типа TApplication. Поскольку Вы будете расширять его позже, когда будете писать программу в Turbo Vision, Вы установите TMyApp для гибкого расширения. По умолчанию TApplication создает экран, как показано на рисунке 2.1.

Рис. 2.1. Экран TApplication по умолчанию.

+--------------------------------------+ | | +--------------------------------------| |**************************************| |**************************************| |**************************************| |**************************************| |**************************************| |**************************************| +--------------------------------------| | Alt-X Exit | +--------------------------------------+

Эта программа делает только одно: она реагирует на Alt-X и завершает программу. Чтобы она делала что-то еще, Вам требуется добавить дополнительные команды в строку статуса и/или в полосу меню. В следующем разделе Вы сделаете это.



Видимые элементы.


Видимый элемент - это любой элемент программы, который виден на экране и все эти элементы являются объектами. В контексте Turbo Vision, если Вы можете увидеть элемент, то он видимый. Поля, рамки окон, полосы скроллинга, полосы меню и диалоговые окна - это все видимые элементы. Видимые элементы могут объединяться для формирования более сложных элементов таких, как окна и диалоговые окна. Эти наборы видимых элементов называются группами и они работают вместе так, как если бы это был один элемент. Концептуально группы могут рассматриваться как видимые элементы. Видимый элемент всегда прямоугольный. Они включают в себя прямоугольники, которые содержат 1 символ или линии высотой в 1 символ или линии шириной в 1 символ. Видимые элементы детально рассматриваются в главе 4.


Отображаемые потомки TObject известны как видимые элементы и они порождаются от TView - непосредственного потомка TObject. Вы должны отличать "видимый" от "отображаемый", поскольку могут быть ситуации, когда видимый элемент полностью или частично скрыт другими видимыми элементами.



Виды событий.


Давайте посмотрим на возможные значения Event.What. Существуют 4 основных базовых класса событий: события от мышки, события от клавиатуры, события сообщений и "пустые" события. Каждый класс имеет определенную маску, так что Ваш объект может быстро определить какой тип события случился, не заботясь о его конкретном виде. Например, вместо того, чтобы проверять на 4 различных вида событий от мышки, Вы можете просто проверить, есть ли флаг события в маске. Вместо

if Event.What and (evMouseDown or evMouseUp or evMouseMove or evMouseAuto) <> 0 then .

Вы можете использовать

if Event.What and evMouse <> 0 then .

Доступны следующие маски: evNothing (для "пустых" событий), evMouse, для событий от мышки; evKeyBoard, для событий от клавиатуры и evMessage для сообщений. Биты маски событий определены на рис.5.5.

Рис. 5.1. Биты поля TEvent.What.

+--------- Event Flags ---------+ msb lsb +-+-+-+-+-+-+-+------------------- evMessage = $FF00 | | | | | | | | +----------- evKeyboard = $0010 | | | | | | | | | +-+-+-+--- evMouse = $000F +++++++++++++++++=+=+=+++++++++++ +=+=+=+=+=+=+++++=+=+=+++++++++++ | | | | | | +--- evMouseDown = $0001 | | | | | +----- evMouseUp = $0002 | | | | +------- evMouseMove = $0004 | | | +--------- evMouseAuto = $0008 | | +----------- evKeyDown = $0010 | +------------------- evCommand = $0100 +--------------------- evBroadcast = $0200



Вина Ваших предков.


Наконец убедитесь, что событие не было обработано в вызове предка объекта. Часто метод HandleEvent порожденного типа вызывает обработчик событий его предка для обработки большинства событий, который может неожиданно обработать одно из событий. Попытайтесь перехватить событие до вызова HandleEvent предка.



Виртуальные методы.


Виртуальные методы используют директиву Virtual в объявлении их прототипов. Виртуальный метод может быть переопределен (перекрыт) потомком, но переопределенный метод так же должен быть виртуальным и его заголовок должен точно соответствовать заголовку оригинального метода. Виртуальные методы не требуют перекрытия, но обычно они рано или поздно перекрываются. Например TView.DataSize.



Внутри HELLO.PAS.


Что делает HELLO, когда Вы выполняете ее? Как она делает все, что Вы видите? Большая часть кода HELLO наследована от предопределенных объектов из Turbo Vision. Наследуется так много, что когда программа выполняется, это может показаться несколько мистическим. Трассировка выполнения с помощью встроенного отладчика не покажет всей картины, поскольку Turbo Vision поставляется в виде откомпилированных модулей. Однако, если у Вас есть время разобраться в том, что здесь делается, точное понимание как делается, необязательно. Для понимания приложений Turbo Vision начните с мысли о том, что приложение Turbo Vision - это совокупность объектов, работающих вместе. Найдите главные объекты и разберитесь, как они работают вместе. Затем посмотрите, как сопутствующие объекты поддерживают главные объекты. Прочитайте и поймите определения объектов до чтения о реализации методов. Важно, чтобы Вы понимали, что содержат объекты и как связаны объекты между собой.



Внутри палитры цветов.


Элементы палитры - это индексы в палитру владельца, а не сами цвета. Если скроллер вставлен в окно, Вы получите нормальный текст, вызывая скроллер с нормальным цветом текста в палитре скроллера, который содержит номер 6. Чтобы преобразовать это в цвет, Вы должны найти 6 элемент в палитре владельца. Рис. 4.19. показывает палитру TWindow:

Рис. 4.19. Отображение палитры скроллера в палитру окна.

+----------------------------- Рамка пассивна | +------------------------- Рамка активна | | +--------------------- Кнопка рамки | | | +----------------- Страница скроллера | | | | +------------- Элемент управления скроллера | | | | | +--------- Нормальный текст скроллера | | | | | | +----- Выбранный текст скроллера | | | | | | | +- Зарезервировано | | | | | | | | 1 2 3 4 5 6 7 8 +---+---+---+---+---+---+---+---+ | 8 | 9 | 10| 11| 12| 13| 14| 15| CBlueWindow +---+---+---+---+---+-+-+---+---+ +-------------------+ +-+-+---+ | 6 | 7 | CScroller +---+---+ | | | +----------------------- Подсвеченный текст +--------------------------- Нормальный текст

6 элемент в палитре TWindow равен 13, это индекс в палитре владельца окна (панели экрана), который преобразуется в индекс в палитру его владельца - программы. TDeskTop имеет палитру nil, что означает, что он не изменяет ничего. Вы можете думать об этом как о "прямой" палитре с первым элементом с номером 1, вторым - с номером 2 и т.д. Программа, которая имеет палитру, содержит значения для всех элементов, которые Вы можете вставить в Turbo Vision. Ее 13 элемент - это $1. Программа - это последяя точка (она не имеет владельца), поэтому отображение останавливается здесь. Сейчас Вы получили $1, что соответствует цвету фона 1 и цвету символа $Е (или 14), что создает желтый символ на синем фоне. И опять, не думайте об этом в терминах желтый-на-синем, а скорее скажите, что Вы хотите, чтобы Ваш текст отображался нормальным цветом для текста окна. Не думайте о палитре как о цветах, это тип характеристик для отображения.



Воплощение Turbo Vision в жизнь.


Мы уже описали программы Turbo Vision, управляемые событиями и кратко определили как Ваша программа должна реагировать на события.



Вопрос: В/В объектов.


Как программист на Паскале Вы знаете, что до того, как Вы сможете выполнять В/В, Вы должны сказать компилятору какой тип данных Вы будете читать или писать в файл. Файл должен быть типированным и тип должен быть определен во время компиляции. Turbo Pascal реализует очень полезное исключение из этого правила: доступ к нетипированному файлу через BlockWrite и BlockRead. Но обход проверки типов создает для программиста определенные сложности, хотя позволяет ему выполнять очень быстрый двоичный В/В. Вторая проблема в том, что Вы не можете использовать файлы прямо с объектами. Turbo Pascal не позволяет Вам создать файл типа объекта. И поскольку объекты могут содержать виртуальные методы, адрес которых определяется во время выполнения, сохранение информации VMT вне программы бессмысленно; чтение такой информации в программу еще более бессмысленно. Вы можете обойти эту проблему. Вы можете скопировать данные из Ваших объектов и сохранить эту информацию в файле, а затем заново построить объекты из этих данных. Но это не элегантное решение и усложняет создание объектов.



Все или ничего.


Атомарная операция - это операция, которая не может быть разбита на более мелкие операции. Или в данном контексте, это операция, которая либо полностью ошибочна, либо полностью успешна. Создание атомарных операций особенно полезно при распределении памяти. Обычно программа распределяет память небольшими кусочками. Например при создании диалогового окна Вы распределяете память под диалоговое окно, а затем под каждый элемент управления. Каждое из этих распределений потенциально может быть неудачным и каждая возможная ошибка требует проверки, можете ли Вы продолжать распределение или должны остановиться. Если любое распределение ошибочно, Вам необходимо освободить память, которая была распределена успешно. В идеале Вы должны делать проверку после каждого распределения. Введите пул надежности.



Встраивание программ в Turbo Vision.


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



Это руководство содержит полное описание


Это руководство содержит полное описание Turbo Vision - новому подходу к разработке прикладных систем. Мы опишем не только что и как может делать Turbo Vision, но и для чего. Если Вы потратите время на то, чтобы понять основные принципы Turbo Vision, Вы обнаружите, что это удобный, сохраняющий время и продуктивный инструмент: Вы сможете создавать разумные интерактивные программы, затрачивая на это меньше времени, чем Вы думаете.

Ввод из потока.


Считать объекты из потока так же просто. Вы делаете это, используя функцию Get:

PSomeObject := SomeStream.Get;

где как и раньше SomeStream - инициализированный поток Turbo Vision, а РSomeObject - указатель на любой тип объекта Turbo Vision. Get просто возвращает указатель на то, что он считал из потока. Сколько данных он считал и какой тип VMT он назначил этим данным определяется не типом PSomeObject, а типом объекта, найденного в потоке. Поэтому, если объект в текущей позиции SomeStream не того же типа, что PSomeObject, Вы получите случайную информацию. Как и Put, Get восстанавливает сложные объекты. Так, если объект, считанный Вами из потока, - это видимый элемент, владеющий подэлементами, подэлементы будут так же загружены.



Выбор.


Обычно выбор, который Вы хотите предложить пользователю в диалоговом окне, это не просто выбор, обрабатываемый индивидуальными кнопками. Turbo Vision обеспечивает несколько полезных стандартных функций управления для выбора ряда опций. Две наиболее полезных - это зависимые и независимые кнопки. Эти 2 функции в основном идентичны с одним исключением, что Вы можете задать несколько независимых, но только одну зависимую кнопку. Причина того, что эти кнопки появляются и ведут себя похоже в том, что они порождаются от одного объекта TCluster. Если Вы не знакомы с концепцией зависимых и независимых кнопок, Вы можете посмотреть меню Options в интегрированной среде Turbo Pascal. Многие диалоговые окна в этом меню используют такие кнопки.



Выбор и активизация видимых элементов.


Внутри любой группы видимых элементов может быть выбран один и только один подэлемент. Например, когда Ваша программа устанавливает полосу меню, панель экрана и строку статуса, панель экрана - выбранный видимый элемент и вся работа будет происходить в нем. Когда Вы открыли на панели экрана несколько окон, выбранное окно это окно с которым Вы работаете в данный момент. Оно также называется активным окном (обычно самое верхнее окно). Внутри активного окна выбранный подэлемент называется активным видимым элементом. Вы можете думать об активном видимом элементе как об элементе на который Вы смотрите или с которым взаимодействуете. (Активный видимый элемент находится в конце цепочки выбранных элементов, которая начинается от программы). В окне редактора активный видимый элемент будет интерьером с текстом внутри него. В диалоговом окне активный элемент это подсвеченный элемент управления. В диаграмме программы на рисунке 4.12 Application это модальный видимый элемент, а DeskTop его выбранный видимый элемент. Внутри панели экрана второе (последнее вставленное) окно выбрано и следовательно активно. Внутри этого окна выбран интерьер скроллинга и поскольку это терминальный видимый элемент (т.е. не является группой), он находится в конце цепочки - является активным видимым элементом. Рис. 4.13 показывает то же дерево видимых элементов с цепочкой активных элементов, выделенных двойной рамкой.

Рис. 4.13. Активная цепочка.

+-------------+ | Application | +--+--+---+---+ +--------+ | +-------+ +---+-----++====+====++-----+------+ | MenuBar DeskTop StatusLine | +---------++==+===+==++------------+ +-----------+ +-----------------+ +----+---+ +====+===+ | Window | | Window | ++-+--+-++ ++=+==+=++ +-----+ | | +-----+ +-----+ | | +-----+ +----+--+ | | +---+------+ +----+--+ | | +===+======+ | Frame | | | | Scroller | | Frame | | | | Scroller | +-------+ | | +----------+ +-------+ | | +==========+ +--+ +--+ +--+ +--+ +---------+--+ +--+---------+ +---------+--+ +--+---------+ | Scroll Bar | | Scroll Bar | | Scroll Bar | | Scroll Bar | +------------+ +------------+ +------------+ +------------+

Кроме всего прочего, информация об активном видимом элементе говорит Вам какой видимый элемент получит информацию от клавиатуры. Для дополнительной информации смотри раздел по активным событиям в главе 5.



Выход.


Нажатие любой кнопки в Hello приведет к исчезанию диалогового окна. Вы можете открыть меню Hello снова и использовать диалоговое окно любое количество раз. Чтобы выйти из программы, Вы можете выбрать элемент Exit в меню Hello или использовать короткую форму Exit: Alt-X. Заметим, что короткая форма представлена как внутри меню Hello, так и в строке статуса внизу экрана.

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



Выход из дилогового окна.


Когда Вы закончили работать с диалоговым окном, Вы вызываете Dispose(D, Done). Вызов Done так же удаляет диалоговое окно с панели экрана. Обычно Вы не вызываете сам Done, поскольку это делается автоматически, когда диалоговое окно закрывается.



Выпадающие меню.


Выберите Hello из полосы меню. Для этого есть 3 способа: - Передвиньте указатель мышки на Hello и нажмите левую кнопку. - Нажмите F10 для перехода курсора в полосу меню, при этом Hello подсвечивается. Нажмите Enter для выбора Hello. - Нажмите Alt-H, где Н - подсвеченный символ в слове Hello. Во всех 3 случаях выпадающее меню появляется под элементом Hello. Это знакомо Вам, как программисту на Turbo Pascal. IDE Turbo Pascal действует таким же образом. Вы видите, что Turbo Vision использует все соглашения интегрированной среды Turbo Pascal, более того, IDE - это программа на Turbo Vision! Появившееся меню показано на рисунке 1.3. В этом меню только 2 элемента, разделенных линией на 2 панели. Hello - это простая программа, в которой в каждой панели только один элемент меню, но в действительности в панели может быть любое число элементов, зависимое только от ограничений экрана.

Рис. 1.3. Меню HELLO.PAS.

+------------------+ |**Greeting.*****| +------------------| | Alt-X Exit | +------------------+

Примечание: "." после элемента меню указывают на то, что элемент вызывает диалоговое окно.

Вы можете выбрать элемент меню с помощью клавиатуры или мышки. Клавиши курсора передвигают полосу подсветки вверх и вниз. Чтобы выбрать подсвеченный элемент с клавиатуры, нажмите Enter, когда будет подсвечен нужный элемент. Более интересен выбор мышкой: Вы нажимаете на полосе подсветки на левую кнопку мышки и передвигаете мышку. До тех пор, пока Вы держите кнопку нажатой, Вы можете передвигать полосу вверх и вниз по списку элементов внутри меню. Вы выбираете один из элементов меню, отпуская кнопку мышки, когда полоса подсветки находится на требуемом элементе меню.



Выполнение HELLO.PAS.


До того, как мы разберем HELLO.PAS детально, давайте загрузим программу, откомпилируем ее и выполним. При выполнении Hello очищает экран и создает панель экрана, как показано на рисунке 1.2. Окна не открываются, а в полосе меню появляется только один элемент: команда Hello. Заметим, что "H" в Hello выделена; и что строка статуса содержит сообщение: Alt-X Exit.

Рис. 1.2. Начальный экран HELLO.PAS.

+--------------------------------------+ | Hello | +--------------------------------------| |**************************************| |**************************************| |**************************************| |**************************************| |**************************************| |**************************************| +--------------------------------------| | Alt-X Exit | +--------------------------------------+

Теперь самое время дать 2 общих правила для программирования любого пользовательского интерфейса: никогда не помещайте пользователя в точку, где он не знает что делать дальше и всегда давайте пользователю способ пройти вперед и вернуться назад. Перед тем, как что-либо сделать, пользователь HELLO имеет 2 ясных выбора: либо выбрать элемент меню Hello, либо нажать Alt-X, чтобы выйти из программы.



Выполнение и отладка.


Поскольку программы Turbo Vision управляются событиями, их код структурирован несколько по другому, чем у обычных программ. Программы, управляемые событиями, отделяют управляющие структуры, которые читают и оценивают ввод пользователя (и другие события) от процедур и функций, которые выполняют действия на основе этого ввода. Конвенциональные программы обычно содержат множество блоков кода, каждый из которых включает получение ввода, решение, какой код получает этот ввод, вызов соответствующих программ для обработки ввода и выполнение этих действий снова. Кроме того код, который заканчивает обработку ввода, должен знать, где получить управление для следующей порции ввода. С другой стороны, программы, управляемые событиями, имеют центральный механизм диспетчеризации событий так, что Ваша программа не должна заботиться о получении ввода и решении что делать с ним. Ваши программы просто ждут, когда центральный диспетчер обработает их ввод. Это важно при отладке Ваших программ: Вы вероятно, измените стратегии отладки, установите точки прерывания в программах обработки событий для проверки сообщений и установите точки прерывания в коде отклика на события для проверки, что он функционирует правильно.

Примечание: Дополнительную информацию по отладке программ Turbo Vision смотри в главе 10.



Выполнение модального диалогового окна.


Как сделать диалоговое окно модальным? Это очень просто. Вместо вставки объекта "диалоговое окно" в панель экрана Вы выполняете его, вызывая функцию DeskTop^.ExecView:

{ TVGUID12.PAS }

procedure TMyApp.NewDialog; var Dialog: PDialog; R: TRect; Control: Word; begin R.Assign(0, 0, 40, 13); R.Move(Random(39), Random(10)); Dialog := New(PDemoDialog, Init(R, 'Demo Dialog')); Control := DeskTop^.ExecView(Dialog); end;

TDialog уже знает как реагировать на событие по клавише ESC (которое преобразуется в команду cmCancel) и событие от клавиши Enter (которое обрабатывается кнопкой диалогового окна по умолчанию TButton). В ответ на команду cmCancel диалоговое окно всегда закрывается. Вызов ExecView вставляет диалоговое окно в группу и делает диалоговое окно модальным. Выполнение происходит в ExecView до тех пор, пока диалоговое окно не закроется или не будет удалено. После этого ExecView удаляет диалоговое окно из группы и осуществляет выход. В данный момент Вы игнорируете значение, возвращаемое функцией ExecView и сохраненное в Control. Вы будете использовать это значение в TVGUID16.



Вывод содержимого буфера.


Turbo Vision предоставляет 2 процедуры для вывода содержимого буфера в видимый элемент. Одна, WriteLine(X, Y, W, H, Buf), была показана в TVGUID07. В TInterior.Draw, WriteLine выводит TDrawBuffer на одной строке. Если 4 параметр, H (высота), больше 1, WriteLine повторяет буфер на последующих строках. Так, если Buf содержит "Hello, World!", то WriteLine(0, 0, 13, 4, Buf) выводит

Hello, World! Hello, World! Hello, World! Hello, World!

Другая процедура WriteBuf(X, Y, W, H, Buf) также выводит прямоугольную область экрана. W и H соответствуют ширине и высоте буфера. Если Buf содержит "ABCDEFGHIJKLMNOP", то WriteBuf(0, 0, 4, 4, Buf) выводит

ABCD EFGH IJKL MNOP

Вы видите, что по сравнению с небуферизованными WriteStr и WriteChar здесь не указывается элемент в палитре цветов. Это связано с тем, что цвет задается когда текст пересылается в буфер - это означает, что текст в буфере может появляться с разными атрибутами. WriteLine и WriteBuf детально объяснены в главе 14.



Вывод в поток.


Вначале рассмотрим процедуру Put. Общий синтаксис метода Put:

SomeStream.Put(PSomeObject);

где SomeStream - это любой объект, порожденный от TStream и инициализированный, а PSomeObject - это указатель на любой объект, порожденный от TObject и зарегистрированный с этим потоком. Это все, что Вы должны сделать. Поток может узнать из VMT PSomeObject тип объекта (предполагая, что тип был зарегистрирован) и, следовательно, знать, какой номер ID записывать и сколько данных записать после него. Однако для Вас, как для программиста на Turbo Vision, будет особенно важно то, что когда Вы записываете в поток группу с подэлементами, подэлементы будут автоматически записываться в поток. Поэтому сохранение сложного объекта будет вовсе не сложным, поскольку выполняется автоматически! Вы можете сохранить все состояние Вашей программы просто записав панель экрана в поток. Когда Вы запустите Вашу программу снова и загрузите панель экрана, программа будет в том же состоянии, что и в точке сохранения панели экрана.



Вызов HandleEvent.


Вы так же можете создать или модифицировать событие, а затем вызвать HandleEvent напрямую. Вы можете сделать 3 типа вызовов: 1. Вы можете иметь видимый элемент, вызывающий HandleEvent равного подэлемента прямо. ("Равные" видимые элементы - это подэлементы с одним владельцем). Сообщение не передается другим видимым элементам. Оно идет прямо к этому HandleEvent, затем управление возвращается к Вам. 2. Вы можете вызвать HandleEvent владельца. Событие будет затем распространяться вниз по цепочке видимых элементов. (Если Вы вызываете HandleEvent из Вашего собственного HandleEvent, Ваш HandleEvent будет вызываться рекурсивно.) Управление передается Вам после обработки события. 3. Вы можете вызвать HandleEvent видимого элемента из другой цепочки видимых элементов. Событие будет передаваться вниз по этой цепочке видимых элементов. Управление передается Вам после обработки события.



Взаимодействие видимых элементов.


Программа Turbo Vision инкапсулирована в объекты и Вы пишите код только внутри объектов. Что, если объектам требуется обмен информацией с другими объектами Вашей программы? В традиционной программе Вы вероятно будете копировать информацию из одной структуры данных в другую. В объектно-ориентированной программе это может быть непросто, поскольку объекты могут не знать, где найти другие объекты. Взаимодействие видимых элементов - это не просто передача данных между частями обычной программы на Паскале. (Хотя 2 части обычной программы на Паскале могут никогда не достичь функциональности двух видимых элементов Turbo Vision). Если Вам необходимо взаимодействие видимых элементов, первый вопрос - это правильно ли Вы разделили задачи между двумя видимыми элементами. Проблема может возникать из-за неправильного проектирования программы. Вероятно 2 видимых элемента должны быть объединены в один видимый элемент или часть одного видимого элемента должна быть перемещена в другой видимый элемент.



Взаимосвязи между видимыми элементами.


Видимые элементы связаны двумя способами: они элементы иерархии объектов Turbo Vision и они элементы дерева видимых элементов. Когда Вы начинаете работать в Turbo Vision, важно помнить это различие. Например, рассмотрим простое диалоговое окно на рис. 4.5. Оно имеет рамку, одну строку текста и одну кнопку, которая закрывает диалоговое окно. В терминах Turbo Vision - это видимый элемент TDialog, который владеет TFrame, TStaticText и TButton.

Рис. 4.5. Простое диалоговое окно.

+=[ю]===== Sample dialog box ===========+ | | | This is a dialog box text message | | | | OK m | | ^^^^^^^^ | +========================================+



Закрытие окна.


Отметка закрывающей кнопки окна генерирует такую же команду cmClose, какую Вы связали с клавишей Alt-F3 и элементом строки статуса. По умолчанию открытие окна (через F4 или выбор в меню File /Open) автоматически разрешает команду cmClose и видимые элементы, которые генерируют ее (а так же другие оконные команды, такие как cmZoom, cmNext). Вам не требуется писать код для того, чтобы закрыть окно. Когда пользователь отметил закрывающую кнопку окна, Turbo Vision сделает все остальное. По умолчанию окно реагирует на команду cmClose вызовом своего дестрактора Done:

Dispose(MyWindow, Done);

Как часть метода окна Done, он вызывает методы Done для всех своих подэлементов. Если Вы сами распределяли дополнительную память в констракторе окна, Вам требуется освободить ее в методе окна Done.



Замечания по структуре.


В данный момент доступен ряд команд, но большинство из них запрещены, а команды cmNewWin и cmFileOpen еще не выполнили никаких действий. Если Ваша первоначальная реакция - одно разочарование, этого не должно быть, Вы сделали многое! В действительности, Вы открыли одно из больших достижений программирования управляемого событиями: Вы отделили функции получения ввода от функций отклика на этот ввод. Традиционная техника программирования требует возвращения в написанный код и добавления кода для открытия окон и т.п. Но Вы не делали этого: Вы получили законченную систему, которая знает, как генерировать команды. Все, что Вам требуется - это написать несколько программ, которые реагируют на эти команды. Это Вы и сделаете в следующем разделе. Оболочка программ Turbo Vision делает следующий шаг по сравнению с традиционным модульным программированием. Вы не только разбиваете Ваш код на функциональные, вновь используемые блоки, но и эти блоки могут быть меньше, более независимыми и более взаимозаменяемыми. Ваша программа сейчас имеет несколько различных способов генерации команды (cmNewWin), чтобы открыть окно: элемент строки статуса, элемент меню и горячая клавиша. Вы видите, как просто сказать Вашей программе открыть окно, когда показана команда. Наиболее важно то, что программа не заботится о том, ни как генерируется команда, ни как создается окно. Эти фукции независимы. Если позднее Вы захотите изменить связки команд - переместить выбор меню, переназначить горячие клавиши - Вам не нужно об этом беспокоиться и даже думать о том, как это будет влиять на остальной код. Т.е. программирование, управляемое событиями, отделяет проектирование пользовательского интерфейса от работы Вашей программы и позволяет различным частям программы функционировать независимо.



Запись события.


До этого момента в этой главе обсуждались теоретические аспекты события. Мы говорили о том, как различные виды событий (мышка, клавиатура, сообщения и "пустые") определяются в поле What события. Мы так же кратко обсудили использование поля Command для событий-команд. Теперь самое время обсудить как выглядит запись события. Модуль DRIVERS.TPU в Turbo Vision определяет тип TEvent как запись с вариантами:

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)); evMessage: ( Command: Word; case Word of 0: (InfoPtr: Pointer); 1: (InfoLong: Longint); 2: (InfoWord: Word); 3: (InfoInt: Integer); 4: (InfoByte: Byte); 5: (InfoChar: Char)); end;

Эта запись с вариантами просматривается по значению поля What. Так, если TEvent.What - это evMouseDown, то TEvent содержит:

Buttons: Byte; Double: Boolean; Where: TPoint;

Если TEvent.What - это evKeyDown, компилятор позволит Вам обратиться к данным как

KeyCode: Word;

или как

CharCode: Char; ScanCode: Byte;

Последний вариант в записи события может хранить значение типа Pointer, LongInt, Word, Integer, Byte или Char. Это поле используется в Turbo Vision различными способами. Видимые элементы могут сами генерировать события и посылать их другим видимым элементам. В этом случае они часто используют поле InfoPtr. Взаимодействие видимых элементов и поля InfoPtr описаны в разделе "Взаимодействие видимых элементов".



Запись в поток.


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

{ TVGUID21.PAS } var GraphicsList: PCollection; GraphicsStream: TBufStream; begin StreamRegistration; . GraphicsStream.Init('GRAPHICS.STM', stCreate, 1024); GraphicsStream.Put(GraphicsList); GraphicsStream.Done; . end.

Будет создаваться дисковый файл, который содержит всю информацию, необходимую для чтения коллекции в память. Когда поток открывается и коллекция считывается (см. TVGUID22.PAS), все скрытые связи между коллекцией и ее элементами и объектами и их таблицами виртуальных методов будут восстановлены. Эта техника используется в IDE Turbo Pascal для сохранения его файла панели экрана. Следующий пример показывает Вам как сделать это. Но вначале Вы должны изучить объекты, выводимые в поток, которые содержат связи с другими объектами.



Записи регистрации.


Определение константы записи регистрации для каждого из наследуемых типов, выполняется последним шагом. Хорошая мысль следовать соглашению Turbo Vision по именованию: используя R в качестве первой буквы.

Примечание: Вспомним, что каждая запись регистрации получает уникальный номер идентификатора объекта (Objtype). Turbo Vision резервирует от 0 до 99 для стандартных объектов. Рекомендуем сохранить ID номера всех объектов в одном месте для избежания дублирования.

const RGraphPoint: TStreamRec = ( ObjType: 150; VmtLink: Ofs(TypeOf(TGraphPoint)^); Load: nil; Store: @TGraphPoint.Store;

RGraphCircle: TStreamRec = ( ObjType: 151; VmtLink: Ofs(TypeOf(TGraphCircle)^); Load: nil; Store: @TGraphCircle.Store;

RGraphRect: TStreamRec = ( ObjType: 152; VmtLink: Ofs(TypeOf(TGraphRect)^); Load: nil; Store: @TGraphRect.Store;

Вам не требуется регистрационная запись для TGraphObject, поскольку это абстрактный тип и никогда не имеет экземпляров и не помещается в коллекцию или поток. Каждый указатель Load записи регистрации устанавливается в nil, поскольку этот пример был создан только для сохранения данных в поток. Методы Load будут определены, а регистрационные записи скорректированы в следующем примере (TVGUID22.PAS).



Зависания.


Ошибки, приводящие к зависаниям, наиболее трудно отслеживать, но они могут быть найдены. Для начала Вы можете попробовать комбинацию точек прерывания, предложенную ранее для локализации места, в котором происходит зависание. Затем посмотрите, не освобождаются ли указатели дважды. Это может произойти когда видимый элемент освобождается своим владельцем, а затем Вы пытаетесь освободить его напрямую. Например:

{ Этот код приводит к зависанию системы } var Bruce, Pizza: PGroup; R: TRect; begin R.Assign(5, 5, 10, 20); Pizza := New(PGroup, Init(R)); R.Assign(10, 10, 20, 20); Bruce := New(PGroup, Init(R)); Bruce^.Insert(Pizza); Dispose(Bruce, Done); Dispose(Pizza, Done); end;

Освобождение группы Bruce так же освобождает подэлементы Pizza. Если Вы попытаетесь освободить Pizza, Ваша программа зависнет. К зависанию может так же приводить чтение данных потока в ошибочный тип объекта и некорректное приведение типа данных из коллекций.



Значения флагов.


В диаграмме, описывающей биты поля Options (рис.4.14 главы 4) msb указывает старший бит, а lsb указывает младший бит. Так например 4-ый бит называется ofFramed. Если бит ofFramed установлен в 1, это означает, что видимый элемент имеет видимую рамку. Если бит равен 0, видимый элемент не имеет рамки. Обычно Вас не интересуют значения флагов, если Вы не собираетесь определить свои и даже в этом случае Вас будет интересовать только то, чтобы Ваши определения были уникальными. Например, 6 старших бит в слове Options не определены в Turbo Vision. Вы можете определить любой из них с необходимым Вам смыслом.



Значения независимых кнопок.


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