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

Абстрактная группа.

TGroup позволяет Вам обрабатывать динамически созданный список связанных интерактивных подэлементов через назначенный видимый элемент, называемый владельцем группы. Каждый видимый элемент имеет поле Owner типа PView, которое указывает на владельца типа TGroup. Указатель со значением nil означает, что видимый элемент не имеет владельца. Поле Next обеспечивает связь со следующим видимым элементом в цепочке видимых элементов. Поскольку группа - это видимый элемент, могут существовать видимые подэлементы, которые образуют группу своих видимых подэлементов и т.д. Состояние цепочки постоянно изменяется в процессе ввода с клавиатуры или отмечания мышкой. Новые группы могут создаваться и видимые подэлементы могут добавляться (вставляться) или удаляться из группы. Во время их существования видимые элементы могут быть скрыты действиями, производимыми над другими подэлементами так, что группе требуется координировать их взаимодействие.

Абстрактные методы.

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

В базовом типе объекта абстрактный метод не имеет определения тела (или тело содержит оператор Abstruct для перехвата неверных вызовов). Абстрактные методы должны быть определены потомками до того, как могут быть использованы. Абстрактные методы - это всегда виртуальные методы. Пример такого метода TStream.Read.

Абстрактные объекты.

Многие типы объектов существуют как "абстрактная" основа, из которой могут порождаться более специализированные полезные типы объектов. Причина создания абстрактных типов частично концептуальная, но в большой степени служит практическим целям сокращения усилий по кодированию. Для примера возьмем типы TRadioButtons и TCheckBoxes. Каждый из них может быть прямо порожден от TView. Однако они разделяют ряд общих свойств: оба представляют набор элементов управления с аналогичной реакцией. Набор зависимых кнопок во многом похож на набор независимых кнопок, внутри которого только одна кнопка может быть выбрана, хотя существует несколько других технических различий. Эта общность включена в абстрактный класс TCluster. TRadioButtons и TCheckBoxes порождены от TCluster со специализированными методами, обеспечивающими их индивидуальность. Бессмысленно создавать экземпляр абстрактного типа. Например экземпляр MyCluster от TCluster не будет иметь полезного метода Draw. Он наследует TView.Darw без перекрытия так, что MyCluster.Draw будет просто выводить пустой прямоугольник умалчиваемого цвета. Если Вы хотите создать кластер элементов управления со свойствами, отличными от зависимых или независимых кнопок, Вы можете породить TMyCluster от TCluster или можно породить Ваш специальный кластер от TRadioButtons или TCheckBoxеs в зависимости от того, какой из них ближе к Вашим требованиям. В любом случае Вы будете добавлять новые поля и добавлять или перекрывать методы с минимальными затратами. Если Вы планируете включить целое семейство новых кластеров, может быть полезным создать промежуточный абстрактный тип объекта.

Активные элементы управления.

Заметим, что когда диалоговое окно открыто, один из элементов управления всегда подсвечен - это активный элемент управления. Активация элемента управления наиболее полезна для направления ввода с клавиатуры. Например, если кнопка активна, пользователь может "нажать" кнопку, нажав пробел. Символы могут быть введены в строку ввода только, если она активна. Пользователь может нажать клавишу Tab для того, чтобы сделать активным другой элемент управления внутри диалогового окна. Метки не могут быть активными, поэтому клавиша Tab проходит мимо них. (Метки обсуждаются позже в этой главе). Вам необходимо, чтобы пользователь мог активировать элементы в диалоговом окне в определенном порядке. Клавиша Tab активирует элементы в том порядке, в каком объекты вставлялись в диалоговое окно. Внутренне, объекты поддерживаются в диалоговом окне в циклически связанном списке с последним вставленным объектом, связываемым с первым объектом. По умолчанию активируется последний вставленный объект. Вы можете активировать другой элемент управления либо используя метод SelectNext диалогового окна, либо прямо вызывая метод Select элемента управления. SelectNext позволяет Вам передвигаться вперед или назад по списку элементов управления. SelectNext(False) передвигает Вас вперед по циклическому списку (в порядке Tab); SelectNext(True) передвигает в обратном направлении.

Активные события.

Активные события это нажатия клавиш (evKeyDown) или команды (evCommand) и передаются вниз по активной цепочке. (Детальное описание активных видимых элементов и активной цепочки приведено в "Выбранные и активные видимые элементы" главы 4). Текущий модальный видимый элемент получает активное событие первым и передает его в выбранный подэлемент. Если этот подэлемент содержит выбранный подэлемент, он передает событие ему. Процесс продолжается до тех пор пока не будет достигнут терминальный видимый элемент: это активный видимый элемент. Активный видимый элемент получает и обрабатывает активное событие. Если активный видимый элемент не знает как обработать какое-то из полученных событий, он передает событие вверх по активной цепочке своему владельцу. Процесс повторяется до тех пор пока событие не будет обработано или снова не достигнет модального видимого элемента. Если модальный видимый элемент не знает как обработать вернувшееся событие, он вызывает EventError. Эта ситуация - ненужное событие. (Неактивные видимые элементы могут обрабатывать активные события. См. раздел "Фаза".) События от клавиатуры иллюстрируют принцип активных событий совершенно ясно. Например, в интегрированной среде Turbo Pascal Вы можете открыть несколько файлов в окнах редактора. Когда Вы нажимаете клавишу, Вы знаете какой файл получит этот символ. Давайте посмотрим как Turbo Vision обеспечивает это. Нажатие клавиши генерирует событие evKeyDown, которое поступает в текущий модальный видимый элемент - объект TApplication. TApplication посылает событие своему выбранному элементу - панели экрана (панель экрана - всегда выбранный элемент TApplication). Панель экрана посылает событие своему выбранному видимому элементу - активному окну (с двойной рамкой). Окно редактора также имеет подэлементы - рамку, интерьер скроллинга и две полосы скроллинга. Из них может быть выбран только интерьер (и следовательно выбран по умолчанию), поэтому событие от клавиатуры приходит в него. Интерьер - редактор не имеет подэлементов и должен решать как обработать символ в событии evKeyDown.

Автоматические поля.

Поле VmtLink - это связь с таблицей виртуальных методов (VMT) объекта. Вы просто назначаете его как смещение типа Вашего объекта:
RSomeObject.VmtLink := Ofs(TypeOf(TSomeObject)^);
Поля Load и Store содержат адреса методов Load и Store Вашего объекта.
RSomeObject.Load := @TSomeObject.Load; RSomeObject.Store := @TSomeObject.Store;
Последнее поле Next назначается в процедуре RegisterType и не требует Вашего вмешательства. Оно предназначено для внутреннего использования в связанном списке регистрационных записей потока.

Битовые маски.

Маска - это просто удобный способ обработки группы флагов вместе. Например, Turbo Vision определяет маски для различных видов событий. Маска evMouse просто содержит все 4 бита, устанавливаемые для различных видов событий от мышки. Поэтому если видимому элементу необходимо проверить событие от мышки, он может сравнить тип события с маской вместо того, чтобы проверять каждый из видов событий от мышки.

Буфер вывода.

Чтобы избежать этого, создайте новый Draw, который включает каждую строку в буфер до ее вывода в окне. TDrawBuffer - это глобальный тип:
TDrawBuffer = array[0MaxViewWidth-1] of Word;
Примечание: MaxViewWidth равен 132 символам.
TDrawBuffer содержит байты с атрибутами и с символами. Новый TInterior.Draw имеет вид:
{ TVGUID07.PAS }
procedure TInterior.Draw; var Color: Byte; Y: Integer; B: TDrawBuffer; begin Color := GetColor(1); for Y := 0 to Size.Y - 1 do begin MoveChar(B, ' ', Color, Size.X); { заполняет строку пробелами } if (Y < LineCount) and (Lines[Y] <> nil) then MoveStr(B, Copy(Lines[Y]^, 1, Size.X), Color); WriteLine(0, Y, Size.X, 1, B); end; end;
Рис. 2.4 показывает TVGUID07 с несколькими открытыми окнами.
Рис. 2.4. Просмотр нескольких файлов.
+-----------------------------------------------------------------+ | File Window | |*****************************************************************| |***********+--- Demo Window 3 ----+******************************| |***********|{*********************|******************************| |***********|{ |******************************| |***********|{ Turbo Pascal 6.0 |******************************| |***********|{ Demo program from |******************************| |***********|{ |******************************| |***********+----------------------+******************************| |+--- Demo Window 1 ---+***+=[ю]Demo Window 5 [ш]=+***************| {********************|***|{*********************|***************| { |***|{ |***************| { Turbo Pascal 6.0 |***|{ Turbo Pascal 6.0 |4 ----+********| { Demo program from |***|{ Demo program from |******|2 ----+*| { |***|{ | |******|*| |+---------------------+***+=====================-+ 6.0 | |*| |*********************************|{ Demo program from | 6.0 |*| |*********************************|{ | from |*| |*********************************+----------------------+ |*| |*******************************************+-------------------+*| |*****************************************************************| |*****************************************************************| |*****************************************************************| |*****************************************************************| | Alt-X Exit F4 New Alt-F3 Close | +-----------------------------------------------------------------+
Draw вначале использует MoveChar для перемещения Size.X пробелов (ширина интерьера) соответствующего цвета в TDrawBuffer. Сейчас каждая строка дополняется пробелами до ширины интерьера. Затем Draw использует MoveStr для копирования текстовой строки в TDrawBuffer. Затем отображает весь буфер через вызов WriteLine.

Буферизованные потоки.

TBufStream реализует буферизованную версию TDosStream. Поля Buffer и BufSize указывают положение и размер буфера. Поля BufPtr и BufEnd определяют текущую и последнюю позицию внутри буфера. Абстрактный метод TStream.Flush определен для выталкивания буфера. Выталкивание означает запись и очистку всех внутренних буферов до закрытия потока.

Буферизованный вывод.

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

Централизация сбора событий.

Одно из наибольших достижений программирования управляемого событиями в том, что Ваш код не должен знать откуда поступают события. Например, объект окно должен только знать, что когда он видит в событии команду cmClose, он должен закрыться. Его не интересует то ли эта команда поступила от отметки его закрывающей кнопки, или из выбора меню, или от горячей клавиши, или пришло сообщение от другого объекта программы. Он даже не беспокоиться о том, предназначалась ли эта команда ему. Он только должен знать как обработать данное событие и обрабатывает его. Ключ к этому "черному ящику" событий - метод GetEvent программы. GetEvent - это единственная часть программы, которая интересуется источником событий. Объекты Вашей программы просто вызывают GetEvent и получают события от мышки, клавиатуры или сгенерированные другими объектами. Если Вы хотите создать новые виды событий (например, чтение символов из последовательного порта) Вы просто перекрываете TApplication.GetEvent в Вашей программе. Как Вы можете увидеть из TProgram.GetEvent в APP.PAS цикл в GetEvent сканирует мышку и клавиатуру, а затем вызывает Idle. Чтобы вставить новый источник событий, Вы можете либо перекрыть Idle для просмотра символов из последовательного порта и генерации событий, основанных на этих символах, либо перекрыть сам GetEvent, чтобы добавить GetComEvent(Event) в цикл, где GetComEvent возвращает запись события, если доступен символ от последовательного порта.

Цепочка активности.

Если Вы начнете с главной программы и проследите все ее выбранные подэлементы, переходя к каждому последующему выбранному подэлементу, Вы дойдете до активного видимого элемента. Цепочка видимых элементов, начиная от объекта TApplication и до активного видимого элемента, называется активной цепочкой. Активная цепочка используется для обработки активных событий, таких как нажатае клавиш. (См. главу 5 для полного объяснения).

Чтение и запись потока.

Базовый объект потоков TStream реализует 3 основных метода: Get, Put и Error. Get и Put примерно соответствуют процедурам Read и Write. Процедура Error вызывается при возникновении ошибки в потоке.

Чтение ресурса.

Получить ресурс из файла ресурса так же просто, как получить объект из потока: Вы просто вызываете функцию Get файла ресурса с ключем требуемого ресурса. Get возвращает указатель на PObject. Ресурс строки статуса, созданные в предыдущем примере, может быть получен:
program MyApp;
uses Objects, Drivers, Views, Menus, Dialogs, App;
var MyRez: TResourceFile;
type PMyApp = ^TMyApp; TMyApp = object(TApplication) constructor Init; procedure InitStatusLine; virtual; end;
constructor TMyApp.Init; var S: PStream; FileName: PathStr; Event: TEvent; const MyRezFileName: PathStr = 'MY.REZ'; begin MyRez.Init(New(PBufStream, Init(MyRezFileName, stOpen, 1024))); if MyRez.Stream^.Status <> 0 then Halt(1); TApplication.Init; end;
procedure TMyApp.InitStatusLine; begin StatusLine := PStatusLine(MyRez.Get('Waldo')); end;
Когда Вы читаете ресурс объекта, Вы должны знать о возможности получения nil указателя. Если индекс имени неверен (т.е. если нет ресурса с таким ключем) Get возвращает nil. Однако после того, как код ресурса будет отлажен, в дальнейшем не должно быть проблем. Вы можете считывать объект ресурса повторно. Вряд ли Вам понадобиться делать это со строкой статуса в нашем примере, но например диалоговое окно может быть считано пользователем много раз во время выполнения программы. Ресурс просто постоянно выдает объект при запросе. Это потенциально может приводить к проблемам с медленным дисковым В/В даже если файл ресурса буферизован. Вы можете увеличить буферизацию или скопировать поток в EMS поток, если EMS инсталлирована.

Чтение текстового файла.

Ваша программа вызывает ReadFile для загрузки текстового файла в массив Lines и DoneFile для освобождения памяти, используемой Lines, после выполнения. В ReadFile глобальный тип PString - это указатель на строку. Turbo Vision так же предоставляет функцию NewStr, которая сохраняет строку в куче и возвращает указатель на нее. Даже хотя NewStr возвращает указатель, не используйте Dispose для ее освобождения. Всегда используйте процедуру DisposeStr для удаления строки из кучи.

Чтение ввода пользователя.

В традиционных программах на Паскале Вы обычно пишете цикл, который читает ввод пользователя с клавиатуры, мышки и от других устройств и Вы принимаете решение на основе этого ввода внутри цикла. Вы будете вызывать процедуры или функции или переходить на этот цикл для того чтобы снова читать ввод пользователя:
repeat B := ReadKey; case B of 'i': InvertArray; 'e': EditArrayParams; 'g': GraphicDisplay; 'q': Quit := true; end; until Quit;
Программа управляемая событиями не очень отличается от обычной. В самом деле, трудно вообразить интерактивную программу, которая работает по другому. Однако, с точки зрения программиста программа управляемая событиями выглядит иначе. В программах на Turbo Vision Вы больше не читаете ввод пользователя поскольку Turbo Vision делает это вместо Вас. Он собирает ввод в записи Паскаля, называемые событиями и передает события соответствующим видимым элементам программы. Это означает, что Вашему коду только требуется знать как обработать соответствующий ввод. Например, если пользователь отмечает мышкой в неактивном окне, Turbo Vision читает ввод мышки, помещает его в запись события и посылает запись события в неактивное окно. Если Вы имеете опыт традиционного программирования Вы можете подумать сейчас: "Хорошо, я не должен читать ввод от пользователя. Я должен изучить как читать запись события об отметке мышкой и как сказать неактивному окну стать активным." В действительности Вы не должны писать так много кода. Видимые элементы сами могут обрабатывать большую часть ввода пользователя. Окно знает как открыться, закрыться, переместиться, стать выбранным, изменить размер и многое другое. Меню знает как открыться, взаимодействовать с пользователем и закрыться. Кнопки знают как нажиматься, как взаимодействовать между собой и как изменять цвет. Полосы скроллинга как функционировать. Неактивное окно может сделать себя активным без какой либо Вашей помощи. Что Вы должны делать как программист? Вам нужно определить новые видимые элементы с новыми функциями, которые должны знать об определенных видах событий заданных Вами. Вы также научите Ваши видимые элементы откликаться на стандартные команды и даже генерировать собственные команды (сообщения) другим видимым элементам. Этот механизм уже есть: все что Вы делаете - это генерируете команды и говорите видимым элементам что нужно сделать когда они увидят их. Как именно выглядят события в Вашей программе и как Turbo Vision обрабатывает их?

Что такое Turbo Vision?

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

Что в этой книге.

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

Что в ресурсе?

До того, как рассматривать детали ресурсов, Вы должны хорошо освоить потоки и коллекции, поскольку механизм ресурса широко использует их. Вы можете использовать ресурсы не зная как они работают, но если Вы собираетесь изменить их, Вам требуется это знать. TResourсeFile содержит отсортированную коллекцию строк и поток. Строки в коллекции - это ключи к объектам в потоке. TResourceFile имеет метод Init, который берет поток и метод Get, который берет строку и возвращает объект.

Что Вам необходимо знать.

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

Что Вы видите?

Все объекты Turbo Vision рисуют себя сами с помощью метода Draw. Если Вы создаете порожденный видимый объект с новым представлением на экране, Вам потребуется перекрыть метод Draw предка и научить новый объекта представлять себя на экране. TInterior порожден от TView и он требует нового метода Draw. Заметим, что новый TInterior.Draw вначале вызывает Draw своего предка, TView, который в этом случае просто очищает прямоугольник видимого объекта. Обычно Вам не требуется делать этого: метод Draw интерьера должен использовать всю свою область, делая вызов TView.Draw ненужным. Если Вы действительно хотите поместить что-то в окно интерьера, Вам не нужно вызывать унаследованный метод Draw вообще. Вызов TView.Draw будет приводить к миганию, поскольку элементы интерьера будут рисоваться более одного раза. В качестве примера Вы можете попробовать перекомпилировать TVGUID05.PAS с закомментированным вызовом TView.Draw. Затем передвиньте и измените размер окна. Станет совершенно ясно, почему видимый элемент должен покрывать всю свою область!
Примечание: Turbo Vision вызывает метод Draw видимого элемента когда пользователь открывает, закрывает, перемещает или изменяет размер видимого элемента. Если Вам требуется, чтобы видимый элемент перерисовал себя сам, вызовите DrawView вместо Draw. DrawView рисует элемент только если он этого требует. Это важно: Вы перекрываете Draw, но никогда не вызываете его прямо; Вы вызываете DrawView, но никогда не перекрываете его!

Цвет видимого элемента.

У всех разное мнение по поводу того, какой цвет "лучше" для экрана компьютера. Поэтому Turbo Vision позволяет Вам изменять цвета видимых элементов на экране. Для этого Turbo Vision предоставляет Вам палитры цветов.

Действие на изменение состояние.

Видимый элемент часто выполняет определенные действия при вызове State, в зависимости от результирующего состояния флагов. Например кнопка просматривает State и изменяет свой цвет на бирюзовый, когда становится активной. Типичный пример SetState для объекта, порожденного от TView.
procedure TButton.SetState(AState: Word; Enable: Boolean); begin TView.SetState(AState, Enable); if AState and (sfSelected + sfActive) <> 0 then DrawView; if AState and sfFocused <> 0 then MakeDefault(Enable); end;
Заметим, что Вы должны вызвать TView.SetState из нового метода SetState. TView.SetState выполняет установку или очистку флагов состояния. Затем Вы можете определить любые действия, основанные на состоянии видимого элемента. TButton проверяет, находится ли он в активном окне для того, чтобы решить, должен ли он рисовать себя. Он так же проверяет, является ли он активным и в этом случае вызывает свой метод MakeDefault, который устанавливает или отменяет активность в зависимости от параметра Enable. Если Вам необходимо выполнить изменения в видимом элементе или программе когда состояние определенного видимого элемента изменяется, Вы можете сделать это, перекрыв SetState этого видимого элемента. Предположим, что Ваша программа включает текстовый редактор и Вы хотите разрешить или запретить все команды редактирования в полосе меню в зависимости от того, открыт редактор или нет. SetState текстового редактора определен:
procedure TEditor.SetState(AState: Word; Enable: Boolean); const EditorCommands = [cmSearch, cmReplace, cmSearchAgain, cmGotoLine, cmFindProc, cmFindError, cmSave, cmSaveAs]; begin TView.SetState(AState, Enable); if AState and sfActive <> 0 then if Enable then EnableCommands(EditorCommands) else DisableCommands(EditorCommands); end;
Примечание: Этот код используется видимым элементом редактора IDE Turbo Pascal, и его поведение должно быть Вам знакомо.
Программист и Turbo Vision часто взаимодействуют, когда состояние изменяется. Предположим, что Вы хотите, чтобы блоковый курсор появился в Вашем текстовом редакторе когда включен режим вставки. Во-первых, режим вставки редактора связан с клавишей, скажем, с клавишей Ins. Когда текстовый редактор активен и клавиша Ins нажата, текстовый редактор получает событие клавиши Ins. Метод HandleEvent текстового редактора откликается на событие Ins переключением внутреннего состояния видимого элемента, говорящегоо том, что режим вставки изменился и вызывая метод BlockCursor. Turbo Vision делает остальное. BlockCursor вызывает SetState видимого элемента для установки состояния sfCursorIns в True.

Делается не то, что ожидалось.

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

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

Когда Вы выбираете элемент Greeting, открывается диалоговое окно, показанное на рисунке 1.4. Диалоговое окно появляется в центре экрана, но Вы можете передвигать его по экрану, установив указатель мышки на верхнюю строку диалогового окна, нажав левую кнопку мышки и передвигая мышку до тех пор, пока Вы держите кнопку мышки. Как только Вы отпустите кнопку, диалоговое окно остановится и будет оставаться в этом месте.
Рис. 1.4. Диалоговое окно Hello, World!
+=[ю]======Hello, World!===============+ | | | Terrific | | --------------+| | OK | | How are you? --------------+| | Lousy | | --------------+| | Cancel | | --------------+| +======================================+
Диалоговое окно имеет заголовок "Hello, World!" и закрывающую кнопку в левом верхнем углу. Если выбрать закрывающую кнопку мышкой, диалоговое окно закрывается и исчезает. Внутри диалогового окна выводится строка "How are you?" Это пример статического текста, который можно прочитать, но который не содержит интерактивных возможностей. Другими словами, статический текст используется для того, чтобы выдать какую-то информацию, но если Вы выберите его, ничего не случится.

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

TDialog, порожденный от TWindow, используется для создания диалоговых окон, обрабатывающих взаимодействие с пользователем. Диалоговые окна обычно содержат элементы управления такие, как кнопки. Родительский метод ExecView используется для сохранения предыдущего контекста, вставки объекта TDialog в группу и перевода диалогового окна в модальный режим. Объект TDialog обрабатывает события, генерируемые пользователем, такие как нажатие кнопок и клавиш. Клавиша Esc интерпретируется как выход (cmCancel). Клавиша Enter интерпретируется как событие cmDefault (обычно означает, что кнопка по умолчанию выбрана). Наконец ExecView восстанавливает предварительно сохраненный контекст.

Динамический размер.

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

Для чего используются ресурсы?

Использование файла ресурса дает ряд преимуществ. Использование ресурсов позволяет Вам настраивать Вашу программу не изменяя код. Например, текст диалоговых окон, метки элементов меню, цвета видимых элементов могут быть получены из ресурса. Вы можете уменьшить код, поместив Init всех Ваших объектов в отдельную программу. Инициализация часто бывает достаточно сложной и содержит вычисления и другие операции, которые Вы можете вынести из Вашего кода. Вам остается только использовать Load для каждого объекта в Вашей программе, но загрузка всегда значительно проще, чем Init. Вы можете уменьшить Ваш код от 8 до 10 процентов, используя ресурс. Использование ресурса так же упрощает поддержку версий Вашей программы, настраиваемой на различные языки. Ваша программа загружает объекты по имени, а язык, на котором они отображают, заключен в них. Если Вы хотите предоставить версии программы с различными возможностями, Вы можете, например, разработать 2 набора меню, один из которых предоставляет доступ ко всем возможностям, а другой предоставляет доступ только к ограниченному набору функций. Для этого Вам не требуется переписывать весь код и Вам не нужно бояться случайно удалить нужную часть кода. Вы можете настраивать программу на полную функциональность предоставлением только нового ресурса вместо замены всей программы. Короче, ресурс изолирует представление объектов Вашей программы и упрощает ее изменение.

Для чего Turbo Vision?

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

Добавление методов Store.

Здесь приведены методы Store. Заметим, что PGraphPoint не требует его, поскольку не добавляет полей при наследовании от PGraphObject.
type PGraphObject = ^TGraphObject; TGraphObject = object(TObject); . procedure Store(var S: TStream); virtual; end;
PGraphCircle = ^TGraphCircle; TGraphCircle = object(TGraphObject) Raduis: Integer; . procedure Store(var S: TStream); virtual; end;
PGraphRect = ^TGraphRect; TGraphRect = object(TGraphObject) Width, Height: Integer; . procedure Store(var S: TStream); virtual; end;
Реализация Store совершенно проста. Каждый объект вызывает наследуемый метод Store, который сохраняет все наследуемые данные. Затем метод Write потока записывает дополнительные данные.
{ TGraphObject не вызывает TObject.Store, поскольку TObjeсt не имеет данных для сохранения } procedure TGraphObject.Store(var S: TStream); begin S.Write(X, SizeOf(X)); S.Write(Y, SizeOf(Y)); end;
procedure TGraphCircle.Store(var S: TStream); begin TGraphObject.Store(S); S.Write(Radius, SizeOf(Radius)); end;
procedure TGraphRect.Store(var S: TStream); begin TGraphObject.Store(S); S.Write(Width, SizeOf(Width)); S.Write(Height, SizeOf(Height)); end;
Заметим, что метод Write из TStream выполняет двоичную запись. Его первый параметр может быть переменной любого типа, но TStream.Write не знает размера этой переменной. Второй параметр предоставляет эту информацию и Вы должны использовать стандартную функцию SizeOf. Таким образом, если Вы решите изменить координатную систему, используя числа с плавающей точкой, Вам не потребуется корректировать методы Store.

Добавление новых цветов.

Вы можете добавить дополнительные цвета к типу объекта окна, который позволит использовать различные цвета при создании новых видимых элементов. Например допустим, Вы решили добавить третий цвет для скроллера для другого типа подсветки как используется для точек прерывания в редакторе IDE. Это может быть сделано наследованием нового типа объекта из существующего TWindow и добавлением к палитре по умолчанию:
type TMyWindow = object(Window) function GetPalette: PPalette; virtual; end;
function TMyWindow.GetPalette: PPalette; const CMyWindow := CBlueWindow + #84; P: string[Length(CMyWindow)] = CMyWindow; begin GetPalette := @P; end;
Примечание: Палитры - это строки, так что Вы можете использовать строковые операции, такие как "+".
Сейчас TMyWindow имеет новый элемент палитры, который содержит новый тип подсветки. CWindow - это строковая константа, содержащая палитру TWindow по умолчанию. Вы должны изменить метод GetPalette для MyScroller чтобы использовать это:
function TMyScroller.GetPalette: PPalette; const CMyScroller = #6#7#9; P: string[Length(CMyScroller)] = CMyScroller; begin GetPalette := @P; end;
Элемент 3 палитры скроллера - это новый цвет подсветки (в данном случае белый на красном). Если Вы используете новую GetPalette используя CMyScroller, который обращается к 9 элементу в палитре владельца, убедитесь, что владелец действительно использует палитру CMyWindow. Если Вы попытаетесь обратиться к 9 элементу в 8- элементной палитре, результат будет непредсказуем.

DosStream Objects

+------------+ | TObject | +-----+------+ +-----+------+ | TStream | +-----+------+ +=====+======+ | TDosStream | +=====+======+ +-----+------+ | TBufStream | +------------+
TDosStream - это специализированный TStream, реализующий небуферизованный поток файла DOS. Констрактор позволяет Вам создать или открыть файл DOS, задав его имя и режим доступа: stCreate, stOpenRead, stOpenWrite или stOpen. Добавляется поле Handle - обработчик традиционного файла DOS, используемый для доступа к открытому файлу. Большинство программ будут использовать буферизованный поток TBufStream, порожденный от TDosStream. TDosStream перекрывает все абстрактные методы TStream, за исключением TStream.Flush.
Поля
Handle: Word; Только чтение Handle - это обработчик файла DOS используемый только для доступа к открытому файлу потока.
Методы
Init constructor Init(FileName: FNameStr; Mode: Word); Создает поток файла DOS с именем FileName и заданным режимом доступа. Если успешно, поле Handle устанавливается в обработчик файла DOS. Ошибка указывается вызовом Error с аргументом stInitError. Аргумент Mode должен принимать одно из значений: stCreate, stOpenRead, stOpenWrite или stOpen. Эти константы объяснены в "Константы потока stXXXX" главы 14.
Done destructor Done; virtual; Перекрывается: Никогда Закрывает и освобождает поток файла DOS
См. так же: TDosStream.Init
GetPos function GetPos: Longint; virtual; Перекрывается: Никогда Возвращает значение текущей позиции в потоке.
См. так же: TDosStream.Seek
GetSize function GetSize: Longint; virtual; Перекрывается: Никогда Возвращает размер потока в байтах.
Read procedure Read(var Buf; Count: Word); virtual; Перекрывается: Никогда Читает Count байт в буфер Buf, начиная с текущей позиции потока.
См. так же: TDosStream.Write, stReadError
Seek procedure Seek(Pos: Longint); virtual; Перекрывается: Никогда Устанавливает текущую позицию в Pos байт от начала потока.
См. так же: TDosStream.GetPos, TDosStream.GetSize
Truncate procedure Truncate; virtual; Перекрывается: Никогда Удаляет все данные текущего потока от текущей позиции до конца потока.
См. так же: TDosStream.GetPos, TDosStream.Seek
Write procedure Write(var Buf; Count: Word); virtual; Пишет Count байт из буфера Buf в поток, начиная с текущей позиции.
См. так же: TDosStream.Read, stWriteError

Другие элементы управления.

Модуль Dialogs предоставляет дополнительные возможности, которые не использовались в этом примере. Однако они используются аналогичным способом: Вы создаете новый экземпляр, вставляете его в диалоговое окно и включаете соответствующие данные в запись данных. Этот раздел кратко описывает функции и их использование. Более детальная информация приведена в главе 13.

Другие элементы.

Поскольку Turbo Vision был спроектирован, чтобы реализовать стандартизованный рациональный подход к конструированию экрана, Ваши программы приобретают зрение и чувства. Это зрение и чувства основаны на годах опыта и тестирования. Рисунок 1.1 показывает набор общих объектов, которые могут появляться как часть программы Turbo Vision. Панель экрана (Desktop) заштрихована фоновым цветом в отличие от остальных элементов на экране. Как и все в Turbo Vision, панель экрана - это объект. Так же видны полоса меню наверху экрана и строка статуса внизу. Слова в полосе меню представляют меню, которые выпадают при выборе этих слов мышкой или при нажатии горячих клавиш.
Рис. 1.1. Объекты Turbo Vision на экране.
+--------------------------------------+ | Полоса меню | +--------------------------------------| |**************************************| |**************************************| |**************************************| |** Панель экрана ********************| |**************************************| |**************************************| +--------------------------------------| | Строка статуса | +--------------------------------------+
Текст, который появляется в строке статуса, обычно выводит сообщения о текущем состоянии программы, показывая доступные горячие клавиши или подсказки для команд, которые доступны пользователю в данный момент. Когда выпадает меню, полоса подсветки пробегает по списку элементов меню при движении мышки или нажатии на клавиши курсора. Когда Вы нажимаете Enter или левую кнопку мышки, выбирается подсвеченный элемент. Выбранный элемент меню посылает команду в определенную часть программы. Ваша программа обычно взаимодействует с пользователем через одно или более окон или диалоговых окон, которые появляются и исчезают на панели экрана в соответствии с командами от мышки или клавиатуры. Turbo Vision предоставляет большой набор окон для ввода и отображения информации. Окна можно сделать со скроллингом, что позволяет выводить в окнах большие объемы данных. Скроллинг окна по информации выполняется передвижением по полосе скроллинга внизу окна, с правой стороны окна или обоим. Полоса скроллинга указывает относительную позицию окна в отображаемых данных. Диалоговые окна часто содержат кнопки - подсвеченные слова - которые могут выбираться мышкой (или переходом через клавишу Tab и нажатием пробела). Отображаемые слова, выбранные мышкой, могут быть установлены для передачи команд в программу.

Другие ошибки.

Конечно не все ошибки связаны с памятью. Например видимый элемент может читать дисковый файл, а файл может быть не найден или разрушен. Этот тип ошибки должен быть указан пользователю. К счастью ValidView может использовать встроенную обработку ошибок, не связанных с памятью, вызывая метод Valid видимого элемента. TView.Valid возвращает True по умолчанию. TGroup.Valid возвращает True только если все подэлементы, принадлежащие группе, возвращают True из их функций Valid. Другими словами, группа правильна, если все подэлементы этой группы правильны. Когда Вы создаете видимый элемент, который может встретить ошибку, не связанную с памятью, Вам необходимо перекрыть Valid для этого видимого элемента так, чтобы он возвращал True только при успешном создании. Valid может использоваться для указания, что видимый элемент не должен использоваться по какой-то причине; например, если видимый элемент не может найти файл. Заметим, что то, ЧТО Valid проверяет и КАК он проверяет зависит от Вас. Типичный метод Valid имеет вид:
function TMyView.Valid(Command: Word): Boolean; begin Valid := True; if Command = cmValid then begin if ErrorEncountered then begin ReportError; Valid := False; end; end; end;
Когда создается видимый элемент, метод Valid должен быть вызван с параметром Command, равным cmValid для проверок любых ошибок, не связанных с памятью, возникших при создании видимого элемента. ValidView(X) вызывает Х.Valid(cmValid) автоматически, а также проверяет пул надежности, так что вызов ValidView перед использованием любого нового видимого элемента - это хорошая идея. Valid так же вызывается при завершении модального состояния с параметром Command в команде, завершающей модальное состояние. (См. главу 4.) Это дает Вам возможность перехватывать такие условия, как несохраненный текст в окне редактора до завершения Вашей программы. ErrorEnсountered может быть и обычно бывает булевской переменной экземпляра объектного типа, который указан в вызове Init.

Другой взгляд на Z-упорядочивание.

Термин Z-упорядочивание ссылается к факту, что подэлементы имеют 3-мерные взаимосвязи. Как Вы уже видели, каждый видимый элемент имеет позицию и размер, определяемые полями Origin и Size. Но видимые элементы и подэлементы могут перекрываться и для того, чтобы Turbo Vision знал какой видимый элемент находится перед другими видимыми элементами, мы добавляем третью координату Z. Так же Z-упорядочивание относится к порядку, в котором Вы встречаете видимые элементы, когда Вы ищете ближайший к Вам. Последний вставленный видимый элемент - это ближайший к Вам. Удобно рассматривать видимые элементы как стеклянные панели в трехмерном пространстве, как показано на рис.4.3.
Рис. 4.3. Трехмерный образ видимых элементов.
+----------------------+ | | | +------------------+---+ | | | | | | | +=#=[ю]=+ | | | | # | TWindow ---ц+---+------------------+ | # | | This is some text | # | TScroller ---ц+---+------------------+ ю | | # | TScrollbar ---ц #ю############### | TFrame ---ц+==========================+
Само окно - это просто стеклянная панель, закрывающая группу видимых элементов. Поскольку все, что Вы видите - это проекция видимых элементов на экран, Вы не видите, какие видимые элементы находятся ближе, чем другие, если они не перекрываются. По умолчанию окно имеет рамку, которая вставляется до любого другого подэлемента. Следовательно это фоновый видимый элемент. При создании интерьера скроллинга 2 полосы скроллинга перекрывают рамку. Для Вас при взгляде сверху они смотрятся как часть рамки, но при взгляде со стороны Вы можете увидеть, что они в действительности лежат выше рамки. Наконец, вставляется скроллер, прикрывая всю область внутри рамки. Текст пишется в скроллере, а не в окне, но Вы можете увидеть его, когда смотрите в окно. При большем масштабе Вы можете увидеть панель экрана как большую стеклянную панель, закрывающую более мелкие элементы, как показано на рис. 4.4.
Рис. 4.4. Трехмерный образ панели экрана.
+----------------------+ | | | +------------------+-------+ | | | | | | +-----+ | | | | |#####| | | TDesktop ---ц+---+--+-----+---------+ | | |#####| | TWindow ---ц | +-----+ | | | TBackground ---ц+--------------------------+
И опять, группа (на этот раз панель экрана) - это панель из стекла. Ее первый подэлемент - это объект TBackGround, который находится на самом низу. Так же видно окно на панели экрана.

Есть ли кто-нибудь?

Конкретный пример. В IDE Turbo Pascal, если пользователь запрашивает открыть окно просмотра, код, который открывает окно просмотра, должен проверить не открыто ли уже окно просмотра. Если нет, он открывает его; если есть, переносит наверх. Передача общего сообщения проста:
AreYouThere := Message(DeskTop, evBroadcast, cmFindWindow, nil);
В методе HandleEvent окна просмотра есть проверка на отклик (очистка события) на команду cmFindWindow:
case Event.Command of . cmFindWindow: ClearEvent(Event); . end;
Вспомним, что ClearEvent не только устанавливает поле What записи события в evNothing, но так же устанавливает поле InfoPtr в @Self. Message читает эти поля и, если событие было обработано, возвращает указатель на объект, обработавший событие-сообщение. В данном случае это окно просмотра. Так за строкой, которая посылала сообщение, мы включим:
if AreYouThere = nil then CreateWatchWindow else AreYouThere^.Select;
Поскольку окно просмотра - это единственный объект, который знает как отвечать на общее сообщение cmFindWindow, Ваш код может быть уверен, что когда он выполнится, будет одно и только одно окно просмотра на вершине всех видимых элементов на панели экрана.

Фаза.

Возникают ситуации когда Вы хотите чтобы видимый элемент отличный от активного обрабатывал активные события (особенно от клавиш). Например, при просмотре текста в скроллингуемом окне Вам может понадобиться использовать клавиши для скроллинга текста, но поскольку текстовое окно это активный видимый элемент, события от клавиш приходят к нему, а не к полосам скроллинга, которые могут скроллинговать видимый элемент. Однако Turbo Vision предоставляет механизм позволяющий видимым элементам отличным от активного элемента видеть и обрабатывать активные события. Хотя передача описанная в разделе "Активные события" абсолютно корректна, существуют два исключения при точном прохожденни активной цепочки. Когда модальный видимый элемент получает для обработки активное событие, передача выполняется в три "фазы": - Событие посылается всем подэлементам (В Z-порядке), у которых установлен флаг ofPreProcess. - Если событие не очищено ни одним из них, это событие посылается в активный видимый элемент. - Если событие все еще не очищено, оно посылается в Z-порядке всем подэлементам с установленным флагом ofPostProcess. Так в предыдущем примере, если полосе скроллинга необходимо видеть клавиши, которые предназначены активному текстовому элементу, полоса скроллинга должна быть инициализирована с установленным флагом ofPreProcess. Если Вы посмотрите на программу TVDEMO09.PAS Вы заметите что полосы скроллинга для видимых элементов интерьера имеют установленными биты ofPostProcess. Если Вы модифицируете код так, чтобы эти биты не устанавливались, скроллинг от клавиатуры будет запрещен. Заметим также что в этом примере нет большой разницы, что Вы установите - ofPreProcess или ofPostProcess. Поскольку активный видимый элемент в этом случае не обрабатывает это событие (сам TScroller ничего не делает с нажатиями клавиш), полосы скроллинга могут видеть эти события как до так и после того, как событие передается в скроллер. Однако лучше использовать в таких случаях ofPostProcess, поскольку он предоставляет большую гибкость. Позже Вы можете добавить в интерьер код, который проверяет нажатие клавиш, но если эти нажатия будут использованы полосой скроллинга, до того как они будут получены активным элементом (ofPreProcess), Ваш интерьер никогда не будет реагировать на них.
Примечание: Хотя Вам может требоваться перехват активных событий до того как активный элемент получает их, хорошая мысль, оставить как можно больше доступных возможностей, поскольку Вы (или кто-то еще) можете наследовать нечто новое от этого объекта в будущем.

Флаг DragMode.

Поле DragMode размером в байт определяет как ведет себя видимый элемент при перемещении. Биты DragMode определены:
Рис. 4.16. Биты флагов DragMode.
+--- DragMode --+ msb lsb +-+-+-+----------- dmLimitAll +++++++++=+=+=+=+ +++++++++=+=+++++ | | | | | +--- dmDragMove | | | | +----- dmDragGrow | | | +----------- dmLimitLoX | | +------------- dmLimitLoY | +--------------- dmLimitHiX +----------------- dmLimitHiY
dmDragMove
Когда этот бит установлен и когда Вы отмечаете вершину рамки окна, Вы можете перемещать окно.
dmDragGrow
Когда этот бит установлен, видимый элемент может быть увеличен.
dmLimitLoX
Если установлен, левая сторона видимого элемента не может выходить за своего владельца.
dmLimitLoY
Если установлен, вершина видимого элемента не может выходить за своего владельца.
dmLimitHiX
Если установлен, правая сторона видимого элемента не может выходить за своего владельца.
dmLimitHiY
Если установлен, нижняя граница видимого элемента не может выходить за своего владельца.
dmLimitAll
Если установлен, ни одна часть видимого элемента не может выходить за своего владельца.

Флаг GrowMode.

Поле видимого элемента GrowMode определяет как изменяется видимый элемент, когда его владелец группы изменяет размер. Биты GrowMode определены следующимм образом:
Рис. 4.15. Биты флагов GrowMode.
+--- GrowMode --+ msb lsb +-+-+-+--- gfGrowAll +=+=+=+=+++++++++ +++=+++++++++++++ +-+-+ | | | | +--- gfGrowLoX | | | | +----- gfGrowLoY Неопределены| | +------- gfGrowHiX | +--------- gfGrowHiY +----------- gfGrowRel
gfGrowLoX
Если установлен, левая сторона видимого элемента будет поддерживать постоянное расстояние от левой стороны его владельца.
gfGrowLoY
Если установлен, вершина видимого элемента будет поддерживать постоянное расстояние от вершины его владельца.
gfGrowHiX
Если установлен, правая сторона видимого элемента будет поддерживать постоянное расстояние от правой стороны его владельца.
gfGrowHiY
Если установлен, нижняя граница видимого элемента будет поддерживать постоянное расстояние от нижней границы его владельца.
gfGrowAll
Если установлен, видимый элемент всегда остается одного размера и будет передвигаться вместе с нижним правым углом владельца.
gfGrowRel
Если установлен, видимый элемент будет поддерживать свой размер относительно размера владельца. Вы должны использовать эту опцию только с TWindow (или с наследниками от TWindow), которые присоединяются к панели экрана. Окна будут поддерживать их относительный размер когда пользователь переключает программу между 25- и 43/50 строчным режимом. Этот флаг не предназначен для использования с видимыми элементами внутри окна.


ofBuffered

Когда этот бит установлен, группа может ускорять свой вывод на экран. Когда группа впервые запрашивает прорисовку, она автоматически сохраняет свой образ в буфере, если этот бит установлен и если доступно достаточное количество памяти. В следующий раз, когда группа запрашивает прорисовку, она копирует образ из буфера на экран вместо прорисовки всех своих подэлементов. Если вызовы New или GetMem приводят к нехватке памяти, монитор памяти Turbo Vision начнет освобождать буфера групп до тех пор, пока запрос не сможет быть выполнен. Если группа имеет буфер, вызов Lock будет останавливать все записи группы на экран до тех пор, пока не будет вызван метод UnLock. Когда UnLock вызывается, буфер группы выводится на экран. Блокирование уменьшает мерцание во время сложных корректировок экрана. Например, панель экрана блокирует себя когда выводит свои подэлементы каскадом или черепицей.

ofTileable

Панель экрана может располагать окна каскадом или черепицей когда они открываются. Если Вы не хотите, чтобы окна располагались черепицей, Вы можете очистить этот бит. Окно останется в той же позиции в то время, когда остальные окна будут автоматически располагаться черепицей. Расположение видимых элементов черепицей или каскадом выполняется в TApplication.HandleEvent очень просто:

cmTile: begin DeskTop^.GetExtent(R); DeskTop^.Tile(R); end; cmCascade: begin DeskTop^.GetExtent(R); DeskTop^.Cascade(R); end;

Если более 2 видимых элементов успешно расположены каскадом, панель экрана не будет делать ничего.

ofCenterX

Когда видимый элемент вставляется в группу, его центр находится в координате Х.

ofCenterY

Когда видимый элемент вставляется в группу, его центр находится в координате Y. Это может быть важно при разработке окон, которые должны хорошо работать в 25 и 43-строчном текстовых режимах.

ofCentered

Центр видимого элемента находится в координатах X и Y, когда он вставляется в группу.

Флаг Options.

Options - это переменная типа слово в каждом видимом элементе. Различные потомки TView имеют различную установку Options по умолчанию. Биты Options определены на рисунке 4.14.
Рис. 4.14. Биты флагов Options.
+-------- TView.Options --------+ msb lsb +-+------------------- ofCentered +=+=+=+=+=+=+++++=+=+=+=+=+=+=+=+ +++=+=+=+=+++++++++++++++++++++++ +----+----+ | | | | | | | | | +--- ofSelectable | | | | | | | | | +----- ofTopSelect Неопределены | | | | | | | +------- ofFirstClick | | | | | | +--------- ofFramed | | | | | +----------- ofPreProcess | | | | +------------- ofPostProcess | | | +--------------- ofBuffered | | +----------------- ofTileable | +------------------- ofCenterX +--------------------- ofCenterY
ofSelectable
Если установлен, пользователь может выбрать видимый элемент мышкой. Если видимый элемент - группа, пользователь может выбрать его мышкой или клавишей Tab. Если Вы поместили на экран чисто информационный элемент, Вам может потребоваться, чтобы пользователь не мог выбрать его. Так например, статические текстовые объекты и рамки окон обычно не выбираемые.
ofTopSelect
Видимый элемент будет передвигаться наверх других подэлементов владельца, если он выбран. Эта опция в основном используется для окон на панели экрана. Вы не должны использовать ее для видимых элементов в группе.
ofFirstClick
Отметка мышкой, которая выбирает видимый элемент, передается этому видимому элементу. Если кнопка отмечена, Вы определенно хотите обработать выбранную кнопку, поэтому кнопка имеет ofFirstClick установленным. Но если пользователь отмечает окно, Вы можете хотеть или не хотеть, чтобы окно откликалось на выбор мышкой.
ofFramed
Если установлен, видимый элемент имеет видимую рамку. Это полезно, если Вы создаете несколько панелей внутри окна.
ofPreProcess
Если установлен, позволяет видимому элементу обрабатывать активные события до того, как активный видимый элемент увидит их. См. раздел "Фаза" в главе 5.
ofPostProcess
Если установлен, позволяет видимому элементу обрабатывать активные события после того, как они были увидены активным видимым элементом при условии, что активный видимый элоемент не очистил событие. См. раздел "Фаза" в главе 5.

Флаг State и SetState.

Видимый элемент так же содержит флаг State, который хранит различные аспекты видимого элемента, такие как его видимость, запрещение и возможность перемещения. Биты флага State определены на рис. 4.17.
Рис.4.17. Биты флага State.
+------ TView.State Flags ------+ msb lsb +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +=+=+=+=+++=+++++++++++++++++++++ | | | | | | | | | | +--- sfVisible = $0001 | | | | | | | | | +----- sfCursorVis = $0002 | | | | | | | | +------- sfCursorIns = $0004 | | | | | | | +--------- sfShadow = $0008 | | | | | | +----------- sfActive = $0010 | | | | | +------------- sfSelected = $0020 | | | | +--------------- sfFocused = $0040 | | | +----------------- sfDragging = $0080 | | +------------------- sfDisabled = $0100 | +--------------------- sfModal = $0200 +------------------------- sfExposed = $0800
Значение каждого из флагов состояния описаны в главе 14 под заголовком "Константы флагов состояния sfXXXX". Этот раздел описывает механизм манипуляции полем State. Turbo Vision изменяет флаг состояния видимого элемента с помощью метода SetState. Если видимый элемент активизирован, активизируется или выбран, Turbo Vision вызывает SetState. Это отличается от способа, которым обрабатываются другие флаги, поскольку они устанавливаются при инициализации и затем не изменяются (например, если окно может изменять размер, оно всегда может изменять размер). Состояние видимого элемента, однако, часто изменяется при его нахождении на экране. Поэтому Turbo Vision предоставляет механизм в SetState, который позволяет Вам не только изменить состояние видимого элемента, но так же реагировать на изменения состояния. SetState получает состояние (AState) и флаг (Еnable), указывающее установлено состояние или очищено. Если Enable - True, то биты в AState устанавливаются в State. Если Enable - False, соответствующие биты State очищаются. Это во многом похоже на работу с любым битовым полем. Отличия появляются, когда Вы хотите, чтобы видимый элемент сделал что-либо, когда Вы изменяете его состояние.

Функция CStrLen Drivers

================================================================= Объявление function CStrLen(S: String): Integer;
Функция Возвращает длину строки S, где S это управляющая строка, использующая символы "~" для указания символов короткого набора. "~" исключаются из длины строки, поскольку они будут появляться на экране. Например, для строки '~B~roccoly', CStrLen возвращает 8.
См. также MoveCStr

Функция CtrlToArrow Drivers

================================================================= Объявление function CtrlToArrow(KeyCode: Word): Word;
Функция Преобразует управляющие WordStar-совместимые коды клавиатуры в соответствующие коды клавиш курсора. Если младший байт KeyCode соответствует одному из значений управляющих клавиш в таблице 14.7, результатом будет соответствующая константа kbXXXX. В противном случае KeyCode возвращается неизмененным.
Таблица 14.7. Преобразование управляющих клавиш.
------------------------------------------------------------ Клавиша Lo(KeyCode) Результат ------------------------------------------------------------ Ctrl-A $01 kbHome Ctrl-D $04 kbRight Ctrl-E $05 kbUp Ctrl-F $06 kbEnd Ctrl-G $07 kbDel Ctrl-S $13 kbLeft Ctrl-V $16 kbIns Ctrl-X $18 kbDown ------------------------------------------------------------

Функция GetAltChar Drivers

================================================================= Объявление function GetAltChar(KeyCode: Word): Char;
Функция Возвращает символ Ch, для которого Alt-Ch вырабатывает двухбайтовый скан-код, данный в аргументе KeyCode. Эта функция дает обратное к GetAltCode отображение.
См. также GetAltCode.

Функция GetAltCode Drivers

================================================================= Объявление function GetAltCode(Ch: Char): Word;
Функция Возвращает двухбайтовый скан-код, соответствующий Alt-Ch. Эта функция делает обратное к GetAltChar отображение.
См. также GetAltChar.

Функция HistoryCount HistList

================================================================= Объявление function HistoryCount(Id: Byte): Word;
Функция Возвращает количество строк в списке истории, соответствующее номеру ID.

Функция HistoryStr HistList

================================================================= Объявление function HistoryStr(Id: Byte; Index: Integer): String;
Функция Возвращает Index строку в списке истории, соответствующую номеру ID.

Функция LongDiv Objects

================================================================= Объявление function LongDiv(X: Longint; Y: Integer): Integer; inline($59/$58/$5A/$F7/$F9);
Функция Функция со встроенным ассемблерным кодом для быстрого деления, возвращающая целое значение X/Y.

Функция LongMul Objects

================================================================= Объявление function LongMul(X, Y: Integer): Longint; inline($5A/$58/$F7/$EA);
Функция Функция со встроенным ассемблерным кодом для быстрого умножениия, возвращающая длинное целое значение X*Y.

Функция LowMemory Memory

================================================================= Объявление function LowMemory: Boolean;
Функция Возвращает True, если памяти мало, в противном случае False. True означает, что вызов распределения памяти достиг пула надежности. Размер пула надежности определяется переменной LowMemSize.
См. также Главу 6, InitMemory, TView.Valid, LowMemSize.

Функция MemAlloc Memory

================================================================= Объявление function MemAlloc(Size: Word): Pointer;
Функция Распределяет Size байт памяти в куче и возвращает указатель на блок. Если блок требуемого размера не может быть распределен, возвращается значение nil. В отличие от стандартных процедур New и GetMem, MemAlloc не позволяет распределять пул надежности. Блок распределенный с помощью MemAlloc может быть освобожден стандартной процедурой FreeMem.
См. также New, GetMem, Dispose, FreeMem, MemAllocSeg.

Функция MemAllocSeg Memory

================================================================= Объявление function MemAllocSeg(Size: Word): Pointer;
Функция Распределяет блок памяти выровненный на границу сегмента. Соответствует MemAlloc, за исключением того, что часть смещения результирующего значения указателя - 0.
См. также MemAlloc

Функция Message Views

================================================================= Объявление function Message(Receiver: PView; What, Command: Word; InfoPtr: Pointer): Pointer;
Функция Устанавливает событие-команду с аргументами What, Command или InfoPtr, затем, если возможно, вызывает Receiver^.HandleEvent для обработки этого события. Message возвращает nil, если Receiver - nil или, если событие не обработано успешно. Если событие успешно обработано (HandleEvent возвращает Event.What как evNothing), функция возвращает Event.InfoPtr. Последний может быть использован для определения, каким видимым элементом обработано событие. Аргумет What обычно устанавливается в evBroadcast. Например, по умолчанию TscrollBar.ScrollDraw посылает следующее сообщение в полосу скроллинга владельца:
Message(Owner, evBroadcast, cmScrollBarChanged, @Self);
Это сообщение гарантирует, что соответствующие видимые элементы перерисуются как только значение полосы скроллинга изменится.
См. также TView.HandleEvent, тип TEvent, константы cmXXXX, константы evXXXX.

Функция NewItem Menus

================================================================= Объявление function NewItem(Name, Param: TMenuStr; KeyCode: Word; Command: Word; AHelpCtx: Word; Next: PMenuItem): PMenuItem;
Функция Распределяет и возвращает указатель на новую запись TMenuItem, которая представляет элемент меню (NewStr используется для распределения полей указателей строк Name и Param). Параметр Name должен быть непустой строкой и параметр Command должен быть ненулевым. Вызовы NewItem, NewLine, NewMenu и NewSubMenu могут быть вложенными для создания полного дерева меню в одном операторе Паскаля; для примеров см. главу 2.
См. также TApplication.InitMenuBar, тип TMenuView, NewLine, NewMenu, NewSubMenu.

Функция NewLine Menus

================================================================= Объявление function NewLine(Next: PMenuItem): PMenuItem;
Функция Распределяет и возвращает указатель на новую запись TMenuItem, которая представляет отдельную строку в окне меню.
См. также TApplication.InitMenuBar, тип TMenuView, NewMenu, NewSubMenu, NewItem.

Функция NewMenu Menus

================================================================= Объявление function NewMenu(Items: PMenuItem): Pmenu;
Функция Распределяет и возвращает указатель на новую запись TMenu. Поля Items и Default записи устанавливаются в значение данное параметром Items.
См. также TApplication.InitMenuBar, тип TMenuView, NewLine, NewSubMenu, NewItem.

Функция NewSItem Dialogs

================================================================= Объявление function NewSItem(Str: String; ANext: PSItem): PSItem;
Функция Распределяет и возвращает указатель на новую запись TSItem. Поля Value и Next записи устанавливаются в NewStr(Str) и ANext соответственно. Функция NewSItem и запись типа TSItem позволяют легко конструировать связанные списки строк; для примера см. главу 4.

Функция NewStatusDef Menus

================================================================= Объявление function NewStatusDef(AMin, AMax: Word; AItems: PStatusItem; ANext: PStatusDef): PStatusDef;
Функция Распределяет и возвращает указатель на новую запись TStatusDef. Запись инициализируется с данными значениями параметров. Вызовы NewStatusDef NewStatusKey могут быть вложенными для создания полных описаний строк статуса в одном операторе Паскаля; для примеров см. главу 2.
См. также TApplication.InitStatusLine, TStatusLine, NewStatusKey.

Функция NewStatusKey Menus

================================================================= Объявление function NewStatusKey(AText: String; AKeyCode: Word; ACommand: Word; ANext: PStatusItem): PStatusItem;
Функция Распределяет и возвращает указатель на новую запись TStatusItem. Запись инициализируется со значениями параметров (NewStr используется для распределения поля указателя Text). Если AText пусто (результатом будет nil в поле Text), элемент статуса скрывается, но будет обеспечивать, однако, отображение из данного KeyCode в Command.
См. также TApplication.InitStatusLine, TStatusLine, NewStatusDef.

Функция NewStr Objects

================================================================= Объявление function NewStr(S: String): PString;
Функция Функция динамической строки. Если S - нулевая, NewStr возвращает nil; в противном случае, распределяются Length(S)+1 байт, содержащие копию S и возвращается указатель на первый байт. Строки создаваемые с помощью NewStr могут быть освобождены с помощью DisposeStr.
См. также DisposeStr.

Функция NewSubMenu Menus

================================================================= Объявление function NewSubMenu(Name: TmenuStr; AHelpCtx: Word; SubMenu: PMenu; Next: PMenuItem): PMenuItem;
Функция Распределяет и возвращает указатель на новую запись TMenuItem, которая представляет подменю (NewStr используется для распределения поля указателя Name).
См. также TApplication.InitMenuBar,TMenuView, NewLine, NewItem.

Функция SystemError Drivers

================================================================= Объявление function SystemError(ErrorCode: Integer; Drive: Byte): Integer;
Функция Функция системной ошибки по умолчанию. Она отображает одно из следующих сообщений об ошибке в строке статуса в зависимости от значения ErrorCode, используя атрибуты цвета, определяемые SysColorAttr или SysMonoAttr.
Таблица 14.32. Сообщения функции SystemError.
----------------------------------------------------------- Код ошибки Сообщение ----------------------------------------------------------- 0 Disk is write-protected in drive X Драйвер X диска защищен от записи 1 Critical disk error on drive X Критическая ошибка диска на драйвере X 2 Disk is not ready in drive X Драйвер X диска не готов 3 Critical disk error on drive X Критическая ошибка диска на драйвере X 4 Data integrity error on drive X Ошибка данных на драйвере X 5 Critical disk error on drive X Критическая ошибка диска на драйвере X 6 Seek error on drive X Ошибка позиционирования на драйвере X 7 Unknown media type in drive X Неизвестный тип носителя в драйвере X 8 Sector not found on drive X Не найден сектор на драйвере X 9 Printer out of paper Нет бумаги на принтере 10 Write fault on drive X Ошибка записи на драйвере X 11 Read fault on drive X Ошибка чтения на драйвере X 12 Hardware failure on drive X Аппаратная неисправность на драйвере X 13 Bad memory image of FAT detected В FAT обнаружен неверный образ памяти 14 Device access error Ошибка доступа к устройству 15 Insert diskette in drive X Вставьте дискету в драйвер X -----------------------------------------------------------
См. также SysColorAttr, SysMonAttr, SysErrorFunc.

Главная программа.

На верхнем уровне абстракции главная программа на Turbo Vision выглядит аналогично Hello:
var HelloWorld: THelloApp; begin HelloWorld.Init; HelloWorld.Run; HelloWorld.Done; end;
Каждый из этих 3 методов требует небольшого пояснения.

Групповые портреты.

Группа - это исключение из правила, что видимые элементы должны знать как рисовать себя, поскольку группа не рисует себя. Скорее TGroup просит свои подэлементы, чтобы они нарисовали себя. Подэлементы вызываются для прорисовки в Z порядке, означающем что первый подэлемент, вставленный в группу, рисуется первым. Таким образом, если подэлементы перекрываются, то вставленный последним рисуется над другими. Подэлементы, принадлежащие группе, должны совместно закрывать всю область, управляемую группой. Например, диалоговое окно - это группа и его подэлементы - рамка, интерьер, элементы управления и статический текст должны полностью накрывать область диалогового окна. Иначе в диалоговом окне будут появляться "дырки" с непредсказуемыми (и неприятными) результатами. Когда видимые подэлементы группы рисуют себя, их вывод автоматически отсекается по границам группы. Поскольку подэлементы отсекаются, когда Вы инициализируете видимый элемент и передаете его в группу, необходимо, чтобы видимый элемент хотя бы частично размещался внутри границ группы. (Вы можете отодвинуть окно с панели экрана только если один угол остается видимым.) Только та часть подэлемента, которая находится внутри границ ее группы будет визуализироваться. Как панель экрана получает видимый фон? Во время ее инициализации панель экрана создает и владеет видимым подэлементом TBackGround, чье назначение заливать весь экран цветом фона. Поскольку фон - первый вставленный подэлемент, он закрывается другими видимыми подэлементами, рисуемыми над ним.

Группы и видимые подэлементы.

Подэлемент - это видимый элемент, который принадлежит другому видимому элементу, т.е. видимый элемент (группа) может передать часть своей области экрана для обработки другому видимому элементу, называемому видимым подэлементом, который будет управлять этой областью. Наилучший пример - TApplication. TApplication - это видимый элемент, который управляет областью экрана - в действительности всем экраном. TApplication - это так же группа, которая владеет 3 элементами: полосой меню, панелью экрана и строкой статуса. Программа передает область экрана каждому из этих подэлементов. Полоса меню получает верхнюю строку, строка статуса - нижнюю строку, а панель экрана - все строки между ними. Рис. 4.2 показывает типичный экран TApplication.
Рис. 4.2. Экран TApplication.
+--------------------------------------+ | Строка меню | +--------------------------------------| |**************************************| |**************************************| |**************************************| |***DeskTop****************************| |**************************************| |**************************************| +--------------------------------------| | Строка статуса | +--------------------------------------+
Заметим, что сама программа не имеет представления экрана - Вы не видите программы. Ее появление полностью определяется ее видимыми элементами.

Группы.

Важность TView явно проявляется из схемы иерархии, показанной на рис. 3.1. Все, что Вы видите в программах на Turbo Vision, порождается от TView. Но некоторые из этих видимых элементов так же важны по другой причине. Они позволяют нескольким объектам действовать вместе.

"Hello, World!" в Turbo Vision.

Традиционный способ демонстрации любого нового языка или инструментария заключается в выводе "Hello, World!". Эта программа обычно состоит из кода, выводящего строку "Hello, World!" на экран и возврата в DOS. Turbo Vision предоставляет другой способ сказать "Hello, World!". Классическая программа "Hello, World!" не интерактивна, а Turbo Vision - это инструмент для создания интерактивных программ. Простейшая программа на Turbo Vision делает гораздо больше, чем Writeln между begin и end. По-сравнению с классической программой "Hello, World!", программа HELLO.PAS на Вашем дистрибутивном диске выполняет: - Заполняет панель экрана полутеневым шаблоном. - Выводит полосу меню и строку статуса наверху и внизу экрана. - Устанавливает обработчик для событий от клавиш и мышки. - Строит объект меню и соединяет его с полосой меню. - Строит диалоговое окно. - Связывает диалоговое окно с меню. - Ожидает Ваших действий через мышку или клавиатуру. В этом списке нет ничего о выводе текста на экран. Текст готовится и ожидает вызова команды. Когда Вы изучаете Turbo Vision, Вам нужно помнить: сущность программирования на Turbo Vision - это проектирование того, что видит пользователь и обучение его что делать, когда получена команда. Оболочка Turbo Vision заботится о создании соответствующего изображения для полученных команд. Вам необходимо думать только о том, что нужно сделать, когда команда от клавиши, мышки или меню поступила в Ваш код. Мышцы Вашей программы - это код, который выполняет требуемую работу в соответствии с командами, введенными пользователем - и этот код содержится в видимых объектах, созданных Вами.

Иерархия объектов.

Один из способов взаимосвязи видимых элементов - это родители и дети в иерархии объектов. Заметьте, что TButton в иерархической диаграмме на рис. 4.6 порожден от типа TView и имеет дополнительные поля и методы, которые делают его кнопкой. TDialog так же порожден от TView (через TGroup и TWindow) и имеет много общего с TButton. Это двоюродные братья в иерархии Turbo Vision.
Рис. 4.6. Иерархия объектов Turbo Vision.
TObject-+-TCollection---TSortedCollection--TStringCollection +-TResourceFile +-TResourceCollection +-TStream-----+-TEmsStream +-TStringList +-TDosStream------TBufStream +-TStrListMaker +-TView-------+-TCluster------+-TCheckBoxes ----- +-TFrame +-TRadioButtons +-TGroup--------+-TDeskTop +-TBackGround +-TProgram----TApplication +-TButton +-TWindow---+-THistoryWindow | ------- +-TDialog +-TStaticText---+-TLabel ------- +-THistory +-TParamText +-TListViewer---+-THistoryViewer +-TInputLine +-TListBox +-TMenuView-----+-TMenuBar +-TScrollBar +-TMenuBox +-TScroller--------TTextDevice--TTerminal +-TStatusLine

Инициализация окна.

Вам необходимо передать в окно Turbo Vision 3 параметра, чтобы оно могло себя инициализировать: его размер и позицию на экране, заголовок и номер окна. Первый параметр TRect - прямоугольный объект в Turbo Vision - определяет размер и позицию окна. Его метод Assign дает его размер и позицию, основанную на верхнем левом и нижнем правом углах. Существует несколько способов назначения или изменения объектов TRect. См. главу 14 "Справочник по глобальным элементам" для полного описания.
Примечание: Объект TRect детально описан в главе 4 "Видимые элементы".
В TVGUID04 R создается от начала DeskTop, затем смещается на случайное расстояние на панели экрана. "Нормальные" программы, вероятно, не будут выполнять такое случайное движение. Это сделано только для примера, чтобы Вы могли открыть несколько окон и чтобы они не размещались в одном месте. Второй параметр инициализации - это строка, которая отображается как заголовок окна. Последний параметр хранится в поле окна Number. Если Number от 1 до 9, он выводится в рамке окна и пользователь может выбрать пронумерованное окно, нажав от Alt-1 до Alt-9. Если Вам не нужно назначать номер окну, просто передайте константу wnNoNumber.

Использование масок.

Так же, как при проверке отдельных бит, Вы можете использовать and для проверки, установлен ли один или более битов маски. Например, для того, чтобы посмотреть, содержит ли запись события событие от мышки, Вы можете проверить:
if Event.What and evMouse <> 0 then .

Использование объектов с потоком.

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

Использование побитовых полей.

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

История.

THistory реализует объект, который работает со строкой ввода и связанным окном списка. Нажимая на символ стрелки, стоящий после строки ввода, пользователь вызывает список предыдущих значений для этой строки ввода и может выбрать любой из них. Это предотвращает от повторного набора. Объекты THistory используются во многих местах интегрированной среды Turbo Pascal. Например, в диалоговом окне File/Open или Search/Find.

Абстрактный тип THistory реализует механизм выбора из списка. 2 дополнительных поля Link и HistoryId дают каждый объект THistory, ассоциированный с TInputLine, и идентификатор списка предыдущих значений в строке ввода. THistory работает в сочетании с THistoryWindow и THistoryViewer.

Итерационные методы.

Вставка и удаление являются не единственными операциями над коллекциями. Часто Вы пишете циклы for для прохода по всем объектам коллекции для отображения данных или выполнения некоторых вычислений. Так же часто необходимо найти первый или последний элемент в коллекции, удовлетворяющий определенному условию. Для этих целей коллекция имеет 3 итерационных метода: ForEach, FirstThat и LastThat. Каждый из них использует указатель на процедуру или функцию как единственный параметр.

Итератор ForEach.

ForEach берет указатель на процедуру. Эта процедура имеет 1 параметр - указатель на элемент, хранящийся в коллекции. ForEach вызывает эту процедуру 1 раз для каждого элемента коллекции в порядке, в котором элементы появляются в коллекции. Процедура PrintAll в TVGUID17 приводит пример итератора ForEach.
procedure PrintAll(C: PCollection);
procedure PrintClient(P : PClient); far; begin with P^ do Writeln(Account^, '':20-Length(Account^), Name^, '':20-Length(Name^), Phone^, ''20-Length(Phone^)); end;
begin Writeln; Writeln; C^.ForEach(@PrintClient); { вызывает PrintClient для каждого элемента из С} end;
Для каждого элемента коллекции, передаваемого как параметр в PrintAll, вызывается вложенная процедура PrintClient. PrintClient просто печатает информацию объекта о клиенте в форматированном виде. Вам необходимо осторожно выбирать процедуры, которые Вы вызываете с итераторами. В этом примере PrintClient должна быть процедурой - она не может быть методом объекта - и она должна быть локальной (вложенной в тот же блок) в программе, которая вызывает ее. Она так же должна быть объявлена как дальняя процедура либо с помощью директивы far, либо с помощью директивы компилятора $F+. Наконец, процедура должна использовать один параметр - указатель на элемент коллекции.

Итераторы LastThat и FirstThat.

В дополнении к возможности применять процедуру к каждому элементу коллекции часто необходимо найти определенный элемент коллекции на основании заданного критерия. Это делают итераторы FirstThat и LastThat. Они просматривают коллекцию в противоположных направлениях до тех пор, пока не найдут элемент, соответствующий критерию булевской функции, переданной как аргумент. FirstThat и LastThat возвращают указатель на первый (или последний) элемент, который соответствует условиям поиска. Рассмотрим предыдущий пример списка клиентов и вообразим, что Вы не можете вспомнить номер клиента или как точно пишется его имя. Однако Вы помните, что это был первый клиент из штата Montana. Поэтому Вы будете искать первое вхождение клиента с кодом штата 406. Процедура, выполняющая этот поиск:
procedure SearchPhone(C: PClientCollection; PhoneToFind: String);
function PhoneMatch(Client: PClient): Boolean; far; begin PhoneMatch := Pos(PhoneToFind, Client^.Phone^) <> 0; end;
var FoundClient: PClient; begin FoundClient := C^.FirstThat(@PhoneMatch); if FoundClient = nil then Writeln('No client met the search requirement') else with FoundClient^ do Writeln('Found client: ', Account^, ' ', Name^, ' ', Phone^); end;
Опять заметим, что PhoneMatch вложенная и использует дальнюю модель вызова. Эта функция возвращает True только если номер телефона клиента и шаблон поиска совпадают. Если в коллекции нет объекта, соответствующего критерию поиска, возвращается указатель nil. Запомните: ForEach вызывает процедуру, определенную пользователем, а FirstThat и LastThat вызывают булевскую функцию, определенную пользователем. Во всех случаях им передается указатель на объект в коллекции.

Эта глава дает Вам возможность

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


Следующий список содержит все побитовые операции:
Установить бит: field := field or flag;
Очистить бит: field := field and not flag;
Проверить, установлен ли флаг: if field and flag = flag then .
Проверить, установлен ли флаг в маске: if flag and mask <> 0 then .

Экземпляры видимых подэлементов.

Вам будет удобно сохранять указатели на подэлементы группы в локальных экземплярах переменных. Например, диалоговое окно часто хранит указатели на объекты элементов управления в мнемонически названных полях для упрощения доступа (такие поля как OKButton или FileInputLine). Когда этот видимый элемент вставляется в дерево видимых элементов, владелец содержит 2 указателя на этот подэлемент, один в поле, а другой в списке подэлементов. Если Вы не разрешаете это, чтение объекта из потока приведет к дублированию экземпляров. Решение - в предоставлении методов GetSubViewPtr и PutSubViewPtr в TGroup. Когда сохраняется поле, которое является подэлементом, вместо того чтобы записать указатель, как это делается с другими переменными, Вы вызываете PutSubViewPtr, который сохраняет ссылку на позицию подэлемента в списке подэлементов группы. Таким образом когда Вы загружаете группу с помощью Load из потока, Вы можете вызвать GetSubViewPtr, который гарантирует, что это поле и список подэлементов указывают на один объект. Приведем короткий пример использования GetSubViewPtr и PutSubViewPtr в простом окне:
type TButtonWindow = object(TWindow) Button: PButton; constructor Load(var S: TStream); procedure Store(var S: TStream); end;
constructor Load(var S: TStream); begin TWindow.Load(S); GetSubViewPtr(S, Button); end;
procedure Store(var S: TStream); begin TWindow.Store(S); PutSubViewPtr(S, Button); end;
Давайте посмотрим чем этолт метод Store отличается от нормального Store. После сохранения окна Вы просто сохраняете ссылку на поле Button вместо сохранения самого поля. Сам объект кнопки сохраняется как подэлемент окна, когда Вы вызвали TWindow.Store. Все что Вы делаете дополнительно к помещению информации в поток это говорите, что Button указывает на этот подэлемент. Метод Load делает то же в обратном порядке, вначале загружая окно и подэлемент кнопки, а затем восстанавливая указатель на этот подэлемент в Button.

Элементы Turbo Vision.

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

Это здесь не получить.

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

Как найти информацию.

Глава 12 "Справочник по модулям" описывает модули Turbo Vision. Он включает список всех типов, констант, переменных, процедур и функций, объявленных в каждом модуле. Глава 14 "Глобальные ссылки" приводит все глобальные константы, переменные, процедуры и функции Turbo Vision. Т.е. если это не объект и не часть объекта, Вы найдете его здесь. Глава 13 "Справочник по объектам" приводит в алфавитном порядке все стандартные типы объектов Turbo Vision, включая все их поля и методы. Запомните, что эта глава описывает только те аспекты каждого объекта, которые принадлежат ему. Большинство объектов имеют поля и методы, наследуемые от других объектов. Так, если Вы хотите найти метод для объекта, вначале проверьте этот объект. Если Вы не найдете метод в этом объекте, проверьте его непосредственного предка. Диаграмма в начале описания каждого объекта объясняет его взаимосвязи с предками и непосредственными потомками.

Как сделать видимый элемент активным?

Видимый элемент можно сделать активным двумя способами, или по умолчанию при его создании, или через действие пользователя. Когда создается группа видимых элементов, владеющий видимый элемент указывает какой из его подэлементов будет активным, вызывая метод Select этого подэлемента. Так устанавливается активность по умолчанию. Пользователю может потребоваться изменить текущий активный видимый элемент. Можно сделать это, отметив мышкой другой видимый элемент. Например, если на панели экрана открыто несколько окон, Вы можете выбрать другое окно просто отметив его. В диалоговом окне Вы можете переместить активность, нажав Tab, который циклически обходит все доступные видимые элементы или отметив мышкой требуемый видимый элемент или нажав горячую клавишу. Заметим что существуют видимые элементы, которые не могут быть выбраны - фон панели экрана, рамки окон и полосы скроллинга. Когда Вы создаете видимый элемент Вы можете указать будет ли этот элемент выбираемым, после чего видимый элемент определяет, остаться ли ему выбираемым. Если Вы отметили рамку окна, рамка не станет активной, поскольку рамка знает что она не может быт активным видимым элементом.

Кластеры.

TCluster - это абстрактный тип, используемый для реализации зависимых и независимых кнопок. Кластер - это группа элементов управления, которые реагируют одинаково. Кластер элементов управления часто ассоциируется с объектами TLabel, позволяя Вам выбирать элемент управления с помощью выбора метки. Дополнительные поля: Value, дающие определенное пользователем значение и Sel, индексирующее выбранный элемент управления этого кластера. Так же представлены методы для рисования текстовых кнопок и отмечающих символов. Для выбора элементов управления в кластере могут использоваться клавиши курсора или мышки. Зависимые кнопки - это специальные кластеры, в которых может быть выбран только один элемент управления. Каждый последующий выбор отменяет текущий элемент. Независимые кнопки - это кластеры, в которых может быть отмечено любое количество элементов управления.

Кнопки.

4 прямоугольника с правой стороны окна - наиболее интересная часть диалогового окна Hello, World! Они называются кнопками и введены для примера элементов управления. Они называются кнопками, поскольку они сходны с кнопками электронных приборов. Каждая кнопка имеет метку, которая указывает, что случится, когда эта кнопка нажата. Вы нажимаете на кнопку, выбрав ее мышкой или сделав кнопку кнопкой по умолчанию (объяснено позже в этом разделе) и нажав Enter. Попытайтесь нажать одну из кнопок мышкой и посмотрите что случится. Тело кнопки передвигается на 1 позицию вправо и ее тень исчезает. Это создает иллюзию, что кнопка была нажата на экране. Когда Вы отпускаете кнопку мышки, выполняется действие, связанное с этой кнопкой. Заметьте, что надпись внутри кнопки Cancel выведена другим цветом, чем остальные кнопки. Отличие в цвете указывает на то, что кнопка Cancel является кнопкой по умолчанию внутри диалогового окна. Если Вы нажмете Enter, когда Cancel по умолчанию, действие будет таким же, как при нажатии кнопки Cancel. (Монохромные системы указывают кнопку по умолчанию символами ">> <<".) Кнопка по умолчанию внутри диалогового окна изменяется нажатием клавиши Tab. Попробуйте использование Tab внутри диалогового окна Hello, World! Цвет кнопки по умолчанию передвигается от одной кнопки к другой при каждом нажатии клавиши Tab. Это позволяет пользователю нажимать кнопку без использования мышки, передвигая умолчание к требуемой кнопке с помощью клавиши Tab и нажимая Enter или пробел, чтобы "нажать" кнопку.

Один из простейших объектов управления - TButton. Он работает во многом аналогично элементу строки статуса: это закрашенная область с текстовой меткой и, если Вы отметите ее, она генерирует команду. Существует так же тень от кнопки, так, что если Вы отметите кнопку, она создает эффект движения. Большинство диалоговых окон имеет, по крайней мере, одну или две кнопки. Наиболее общие кнопки "OK" (означающая "Я все сделал. Вы можете закрыть диалоговое окно и использовать результаты.") и "Cancel" (означающая "Я хочу закрыть диалоговое окно и игнорировать изменения, сделанные в нем"). Кнопка Cancel обычно генерирует ту же команду cmCancel, что и закрывающая кнопка. Модуль Dialogs определяет 5 стандартных диалоговых команд, которые могут быть связаны с TButton: cmOK, cmCancel, cmYes, cmNo, cmDefault. Первые 4 команды так же закрывают диалоговое окно, вызывая метод EndModel из TDialog, который восстанавливает предыдущий модальный видимый элемент в статус модальности. Вы можете так же использовать кнопки для генерации команд, специфичных для Вашей программы.
{ TVGUID13.PAS }
procedure TMyApp.NewDialog; var Dialog: PDialog; R: TRect; Control: Word; begin R.Assign(20, 6, 60, 19); Dialog := New(PDialog, Init(R, 'Demo Dialog')); with Dialog^ do begin R.Assign(15, 10, 25, 12); Insert(New(PButton, Init(R, '~O~K', cmOK, bfDefault))); R.Assign(28, 10, 38, 12); Insert(New(PButton, Init(R, 'Cancel', cmCancel, bfNormal))); end; Control := DeskTop^.ExecView(Dialog); end;
Создание кнопки требует 4 параметров в констракторе Init: 1. Область, закрываемая кнопкой (не забудьте оставить место для тени!). 2. Текст, который появляется в кнопке. 3. Команда, связанная с кнопкой. 4. Флаг типа кнопки. (Нормальная или по умолчанию)
Рис. 2.8. Диалоговое окно с кнопками.
+=[ю]======= Demo Dialog Box =========+ | | | | | | | | | | | | | | | OK m Cancel m | | ^^^^^^^^ ^^^^^^^^ | +=====================================+
Заметим, что Вы не подсвечиваете "С" в "Cancel", поскольку уже определена горячая клавиша (Esc) для отмены диалогового окна. Это освобождает "С" для сокращенного ввода других элементов управления.


Объект TButton - это помеченный прямоугольник, используемый для генерации события с заданной командой при ее "нажатии". Обычно они размещаются внутри (принадлежат) диалоговых окон, предоставляя такие выборы как "OK" или "Cancel". Диалоговое окно - это обычно модальный видимый элемент, который при появлении перехватывает и обрабатывает все события, включая события от его кнопок. Обработчик событий предоставляет несколько способов нажатия кнопки: выбором прямоугольника кнопки мышкой, нажатием короткого символа или выбором кнопки по умолчанию клавишей Enter.

Коллекции и управление памятью.

TCollection может динамически расти от первоначального размера, установленного в Init до максимального размера 16,380 элементов. Максимальный размер коллекции хранится в переменной MaxCollectionSize Turbo Vision. Каждый элемент, который Вы добавляете в коллекцию, требует только 4 байта памяти, поскольку элемент хранится как указатель. Библиотека динамических структур данных не будет полной, если ее не обеспечить средством обнаружения ошибок. Если для инициализиции коллекции недостаточно памяти, возвращается указатель nil. Если при добавлении элемента в TCollection недостаточно памяти, вызывается метод TCollection.Error и генерируется ошибка времени выполнения в куче. Вы можете перекрыть TCollection.Error, чтобы самому выдавать сообщение об ошибке или реализовать механизм восстановления. Вы должны обратить особое внимание на обработку ошибок кучи, поскольку пользователь имеет в программе Turbo Vision гораздо больше возможностей, чем в традиционной программе на Паскале. Если пользователь управляет добавлением объектов в коллекцию (например открывая новые окна на панели экрана), не всегда будет просто предупредить ошибку кучи. Вам может понадобиться предпринять ряд шагов для защиты пользователя от фатальной ошибки времени выполнения либо используя собственные проверки памяти при работе с коллекцией, либо обработчик ошибок времени выполнения.

Коллекции не объектов.

Вы можете так же добавить в коллекцию данные, не являющиеся объектами, но это приведет к другой серьезной проблеме. Коллекции ожидают получить нетипированные указатели на что-либо. Но некоторые методы TCollection предназначены для обработки коллекций экземпляров, порожденных от TObject. Они включают в себя методы доступа к потоку PutItem и GetItem, а так же стандартную процедуру FreeItem. Это означает, что Вы можете сохранить PString в коллекции, но если Вы попытаетесь передать эту коллекцию в поток, Вы получите неудовлетворительные результаты, если не перекроете стандартные методы GetItem и PutItem. Аналогично, когда Вы пытаетесь освободить коллекцию, она освобождает каждый элемент, используя FreeItem. Если Вы хотите использовать в коллекции элементы не типа TObject, Вам необходимо переопределить смысл "элемента" в GetItem, PutItem и FreeItem. В TStringCollection, например, делается именно это. Если Вы работаете с осторожностью, Вы найдете коллекции (и объекты, порожденные от коллекций) быстрыми, гибкими и настраиваемыми структурами данных.

Коллекции ресурсов.

TResourceCollection реализует коллекцию отсортированных индексов ресурсов, используя файлы ресурсов. Методы FreeItem, GetItem, KeyOf, PutItem типа TStringCollection перекрываются для обработки ресурсов.

Коллекции строк.

Многим программам необходимо хранить отсортированные строки. Для этого Turbo Vision предоставляет специальную коллекцию TStringCollection. Заметим, что элементы TStringCollection - не объекты, это указатели на строки Turbo Pascal. Поскольку коллекция строк наследуется от TSortedCollection, дублированные строки не сохраняются. Использовать коллекции строк просто. Просто объявите переменную указателя на коллекцию строк. Распределение коллекции, задание начального размера и приращение при расширении коллекции определены:
{ TVGUIDE19.PAS } var WordList: PCollection; WordRead: String; . begin WordList := New(PStringCollection, Init(10, 5)); .
WordList первоначально хранит 10 строк, а затем увеличивается с приращением 5. Все, что Вы делаете - это вставляете строки в коллекцию. В этом примере слова читаются из текстового файла и вставляются в коллекцию:
repeat . if WordRead <> '' then WordList^.Insert(NewStr(WordRead)); . until WordRead = ''; . Dispose(WordList, Done);
Заметим, что функция NewStr используется для создания копии слова, которое было прочитано, и адрес копии строки передается в коллекцию. Когда используется коллекция, Вы всегда передаете ей управление над собираемыми данными. Она будет тщательно освобождать данные, когда Вы закончите работу. Это будет соответствовать вызову Dispose; он освобождает каждый элемент коллекции, а затем освобождает саму коллекцию WordList.

Коллекции в потоках: полный пример.

В главе 7 "Коллекции" Вы видели как можно сохранять в коллекциях различные, но связанные объекты. К потокам так же применимы полиморфные свойства и они могут использоваться для сохранения целой коллекции на диске для восстановления в другое время или даже другой программы. Посмотрим еще раз TVGUID20.PAS. Что нужно сделать, чтобы эта программа вывела коллекцию в поток? Ответ удивительно прост. Во-первых, начнем с базового объекта TGraphObject и "научим" его как сохранять его данные (X и Y) в потоке. Это делает метод Store. Затем определим новый метод Store для каждого наследника TGraphObject, который добавляет новые поля (TGraphCircle добавляет Radius; TGraphRect добавляет Width и Height). Затем создадим регистрационную запись для каждого типа объекта, который будет сохраняться и зарегистрируем каждый из этих типов. Это все. Все остальное как при обычном вводе/выводе: объявите переменную потока; создайте новый поток; поместите всю коллекцию в поток одним оператором; закройте поток.

Коллекции.

TCollection реализует набор элементов, включая произвольные объекты различных типов. В отличие от массивов, множеств и списков не - ООП языков, коллекция Turbo Vision допускает переменный размер. Collection - это абстрактная база для более специализированных коллекций таких как TSortedCollection. Главное поле - Items - указатель на массив элементов. Кроме индексации, вставки и удаления, TCollection предоставляет несколько итерационных программ. Коллекция может быть просканирована от первого или последнего элемента до нахождения условия, заданного в функции проверки, определенной пользователем. С помощью метода ForEach Вы можете выполнить действие, определенное пользователем для каждого элемента коллекции.

Коллекция строк.

TStringCollection - это простое расширение TSortedCollection для обработки отсортированной коллекции строк Turbo Pascal. Метод FreeItem удаляет данную строку из коллекции. Для записи и чтения коллекции строк из потока предоставлены виртуальные методы PutItem и GetItem.

Команды.

Большинство позиционированных и активных событий транслируются обрабатывающими их объектами в команды. Т.е. объект часто откликается на отметку мышкой или клавишу генерацией события команды. Например, отметив в строке статуса программы на Turbo Vision Вы генерируете позиционное (от мышки) событие. Программа определяет что отметка была позиционирована в области управляемой строкой статуса и передает событие в объект строки статуса StatusLine. StatusLine определяет какой из элементов управления статуса отмечен и читает запись элемента статуса для этого элемента. Этот элемент обычно имеет связанную с ним команду и StatusLine создает запись статуса с полем What, установленным в evCommand и с полем Command, установленным в команду, которая была связана с этим элементом статуса. Затем она очищает событие от мышки, что означает что следующее событие обнаруженное GetEvent будет только что сгенерированное событие команды.

Константа MaxViewWidth Views

================================================================= Объявление MaxViewWidth = 132;
Функция Устанавливает максимальную длину видимого элемента.
См. также поле TView.Size.

Константа mbXXXX Drivers

================================================================= Функция Эти константы могут быть использованы при проверке поля TEvent.Buttons записи события evMouse.
if (Event.What = evMouseDown) and (Event.Button = mbLeftButton) then LeftButtonDown;
Значения Определены следующие константы:
Таблица 14.22. Константы кнопки мышки.
--------------------------------------------------------------- Костанта Значение Назначение --------------------------------------------------------------- mbLeftButton $01 Установлено, если была нажата левая кнопка mbRightButton $02 Установлено, если была нажата правая кнопка ---------------------------------------------------------------
См. также GetMouseEvent.

Константa wnNoNumber Views

================================================================= Объявление wnNoNumber = 0;
Функция Если поле TWindow.Number содержит эту константу, это указывает, что окно не может иметь номера и не может быть выбрано через Alt-номер. Если поле Number между 1 и 9, номер окна отображается и выбор по Alt-номер доступен.
См. также TWindow.Number

Константы apXXXX App

================================================================= Значения Определены следующие константы палитры:
Таблица 14.1. Константы палитры.
------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ apColor 0 Палитра для цветного монитора apBlackWhite 1 Палитра для LCD монитора apMonochrome 2 Палитра для монохромного монитора ------------------------------------------------------------
Функция Константы, начинающиеся с ap, используются для указания, с какой из 3 стандартных палитр будет работать программа на Turbo Vision. Три палитры используются для цветного, черно-белого и монохромного дисплеев.

Константы bfXXXX Dialogs

================================================================= Значения Определены слудующие флаги кнопки:
Таблица 14.2.
------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ bfNormal $00 Нормальная кнопка bfDefault $01 Кнопка по умолчанию bfLeftJust @02 Метка кнопки выровнена влево ------------------------------------------------------------
Функция Комбинация этих значений передается в TButton.Init для определения вновь созданного стиля кнопки. bfNormal указывает на нормальную не умалчиваемую кнопку. bfDefault указывает что кнопка будет кнопкой по умолчанию. Обязанность программиста, обеспечить чтобы кнопка была единственной умалчиваемой кнопкой в TGroup. Значение bfLeftJust может быть добавлено к bfDefault или bfNormal и воздействует на позицию отображаемого текста внутри кнопки: если очищено, то метка центрируется; если установлено, то метка выравнивается влево.
См. также TButton.Flags, TButton.MakeDefault, TButton.Draw

Константы cmXXXX Views

================================================================= Функция Эти константы представляют предопределенные команды Turbo Vision. Они передаются в поле TEvent.Command событий evMessage(evCommand и evBroadcast) и заставляют методы HandleEvent стандартных объектов Turbo Vision выполнять различные задачи. Turbo Vision резервирует значения констант от 0 до 99 и от 256 до 999 для своих целей. Обработчики событий стандартных объектов Turbo Vision реагируют на эти предопределенные константы. Прграммисты могут определить свои собственные константы в диапазонах от 100 до 255 и от 1,000 до 65,535 без конфликтов с предопределенными командами.
Значения Следующие стандартные команды определены в Turbo Vision и используются стандартными объектами Turbo Vision:
Таблица 14.3. Коды стандартных команд.
------------------------------------------------------------------ Команда Значение Назначение ------------------------------------------------------------------ cmValid 0 Передается в TView.Valid для проверки вновь созданных образцов видимых элементов cmQuit 1 Заставляет TProgram.HandleEvent вызывать EndModal (cmQuit), завершая программу. Строка статуса или одно из меню обычно содержат элемент, который переводит kbAltX и cmQuit. cmError 2 Не обрабатывается никаким объектом. Может быть использована для представления нереализованных или неподдерживаемых команд. cmMenu 3 Заставляет TMenuView.HandleEvent вызывать ExecView для процесса выбора меню, в результате чего может быть сгенерирована новая команда с помощью PutEvent. cmClose 4 Обрабатывается TWindow.HandleEvent, если поле InfoPtr записи события установлено в nil или указывает на окно. Если окно модальное, то посредством PutEvent генерируется evCommand со значением из cmCancel. Если окно немодальное, то то вызывается метод Close при условии что окно поддерживает закрытие (смотри флаг wfClose). Отметка на закрывающей кнопке окна генерирует событие evCommand с Command из cmClose и InfoPtr, который указывает на окно. Строка статуса или одно из меню обычно содержит элемент, который переводит kbAltF3 в cmClose. cmZoom 5 Заставляет TWindow.HandleEvent вызывать TWindow.Zoom, если окно поддерживает масштабирование (смотри флаг wfZoom) и если поле InfoPtr записи события установлено в nil или указывает на окно. Отметка на кнопке масштабирования окна или двойная отметка на полосе заголовка окна генерирует событие evCommand с Command из cmZoom и InfoPtr, который указывает на окно. Строка статуса или одно из меню обычно содержит элемент, который переводит kbF5 в cmZoom. cmResize 6 Заставляет TWindow.HandleEvent вызывать TView.DragView, если окно поддерживает изменение размеров (смотри флаги wfMove и wfGrow). Строка статуса или одно из меню обычно содержит элемент, который переводит kbCtrlF5 в cmResize. cmNext 7 Заставляет TDeskTop.HandleEvent сдвигать последнее окно на панели экрана на передний план. Строка статуса или одно из меню обычно содержит элемент, который переводит kbF6 в cmNext.

cmPrev 8 Заставляет TDeskTop. HandleEvent сдвигать первое окно на панели экрана на самый задний план. Строка статуса или одно из меню обычно содержит элемент, который переводит kbShiftF6 в cmPrev. ------------------------------------------------------------------

Следующие стандартные команды используются для определения поведения по умолчанию объектов диалогового окна:

Таблица 14.4. Стандартные команды диалогового окна.

------------------------------------------------------------------ Команда Значение Назначение ------------------------------------------------------------------ cmOK 10 Была нажата кнопка OK cmCancel 11 Диалоговое окно было отменено кнопкой Cancel, закрывающей кнопкой или клавишей Enter cmYes 12 Была нажата кнопка Yes cmNo 13 Была нажата кнопка No cmDefault 14 Была нажата кнопка по умолчанию ------------------------------------------------------------------

События с командами cmOK, cmCancel, cmYes или cmNo завершают модальный диалог TDialog.HandleEvent и возвращают значение команды (вызывая EndModal). Модальный диалог обычно содержит по крайней мере один TButton с одним из этих значений команд. TDialog.HandleEvent будет генерировать команду-событие cmCancel в ответ на событие от клавиатуры kbEsc. Команда cmDefault заставляет TButton.HandleEvent для умалчиваемой кнопки (см. флаг bfDefault) симулировать нажатие кнопки. TDialog.HandleEvent будет генерировать событие команды cmDefault в ответ на событие клавиатуры kbEnter. Определены следующие стандартные команды для использования стандартными видимыми элементами:

Таблица 14.5. Стандартные команды видимых элементов.

------------------------------------------------------------------ Команда Значение Назначение ------------------------------------------------------------------ cmReceivedFocus 50 TView.SetState использует функцию Message cmReleasedFocus 51 для передачи события evBroadcast с одним из этих значений в свой TView.Owner, как только sfFocused изменяется. InfoPtr события указывает на сам видимый элемент. Это информирует любой равный видимый элемент, что видимый элемент получил или освободил активность и что они должны корректировать себя соответственно. Объект Tlabel, например, реагирует на эти команды, включая или выключая свою подсветку. cmCommandSetChanged 52 Метод TProgram.Idle генерирует событие evBroadcast как только он обнаружит изменение в текущем наборе команд (вызывая методы EnableCommands, DesableCommands или SetCommands для TView). Общее сообщение cmCommandSetChanged посылается в HandleEvent каждого видимого элемента иерархии (если только их TView.EventMask специфически не маскируют события evBroadcast). Если изменения в наборе команд затрагивают появление видимого элемента, он должен реагировать на cmCommandSetChanged своей перерисовкой. Объекты TBut ton, TMenuView и TStatusLine, например, реагируют на эту команду, перерисовывая себя. cmScrollBarChanged 53 TScrollBar использует функцию Message для cmScrollBarClicked 54 передачи события evBroadcast с одним из этих значений в свой TView.Owner, как только мышка отмечает на полосе скроллинга. InfoPtr события указывает на полосу скроллинга. Общие сообщения создаются любыми равными видимыми элементами, управляемыми полосой скроллинга, такими как объекты TScroller и TListViewer. cmSelectWindowNum 55 Заставляет TWiondow.HandleEvent вызывать TView.Select, если InfoInt записи события соответствует TWindow.Number. TProgram.HandleEvent реагирует на события от клавиатуры от Alt-1 до Alt-9 общим сообщением cmSelectWindowNum с InfoInt от 1 до 9. cmRecordHistory 60 Заставляет объект THistory "записывать" текущее содержимое объекта TInputLine. TButton посылает общее сообщение cmRecordHistory своему владельцу, когда он выбран, в результате, заставляя "записывать" все объекты THistory в диалоговом окне. ------------------------------------------------------------------

См. также TView.HandleEvent, TCommandSet

Константы coXXXX Objects

================================================================= Функция Константы coXXXX передаются как параметр Code в метод TColection.Error, когда TCollection обнаруживает ошибку во время операции.
Значения Следующие стандартные коды ошибок определены для всех коллекций Turbo Vision:
Таблица 14.6. Коды ошибок коллекции.
------------------------------------------------------------------ Код ошибки Значение Назначение ------------------------------------------------------------------ coIndexError -1 Индекс вышел за диапазон. Параметр Info передает в метод Error содержимое неверного индекса.
coOverflow -2 Переполнение коллекции. TCollection.SetLimit недостаточно для расширения коллекции. Параметр Info передает в метод Error запрашиваемый размер коллекции. ------------------------------------------------------------------
См. также TCollection

Константы dmXXXX Views

================================================================= Значения Биты DragMode определены так:
Рис. 14.1. Флаги режима Drag.
+--- DragMode --+ msb lsb +-+-+-+----------- dmLimitAll = $F0 +++++++++=+=+=+=+ +++++++++=+=+++++ | | | | | +--- dmDragMove = $01 | | | | +----- dmDragGrow = $02 | | | +----------- dmLimitLoX = $10 | | +------------- dmLimitLoY = $20 | +--------------- dmLimitHiX = $40 +----------------- dmLimitHiY = $80
Функция Эти константы используются для компоновки параметра Mode метода TView.DragView. Они указывают разрешены ли движение и/или изменение размера и как интерпретировать параметр Limits. Константы определены так:
Таблица 14.8. Константы режима Drag.
------------------------------------------------------------ Константа Назначение ------------------------------------------------------------ dmDragMove Позволяет видимому элементу перемещаться. dmDragGrow Позволяет видимому элементу изменять размер. dmLimitLoX Левая сторона видимого элемента не может выходить за Limits. dmLimitLoY Верхняя сторона видимого элемента не может выходить за Limits. dmLimitHiX Правая сторона видимого элемента не может выходить за Limits. dmLimitHiY Нижняя сторона видимого элемента не может выходить за Limits. dmLimitAll Никакая часть видимого элемента не может выходить за Limits. ------------------------------------------------------------

Константы evXXXX Drivers

================================================================= Функция Эти мнемоники обозначают типы событий для обработчиков событий Turbo Vision. Константы evXXXX используются в нескольких местах: в поле What записи события, в поле EventMask видимого элемента и в переменных PositionalEvents и FocusedEvents.
Значения Следующие значения флагов событий обозначают стандартные типы событий:
Таблица 14.9. Флаги стандартных событий.
------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ evMouseDown $0001 Кнопка мышки нажата evMouseUp $0002 Кнопка мышки отпущена evMouseMove $0004 Мышка изменила положение evMouseAuto $0008 Периодическое событие до тех пор, пока нажата кнопка мышки evKeyDown $0010 Клавиша нажата evCommand $0100 Событие-команда evBroadcast $0200 Событие-общее сообщение ------------------------------------------------------------
Следующие константы могут использоваться для маскирования типов событий:
Таблица 14.10. Маски стандартных событий.
------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------ evNothing $0000 Событие уже обработано evMouse $000F Событие от мышки evKeyboard $0010 Событие от клавиатуры evMessage $FF00 Событие-сообщение (команда, общее сообщение или определено пользователем). ------------------------------------------------------------
Биты маски события определены так:
Рис. 14.2. Отображение битов маски события.
+------ Флаги события ---------+ msb lsb +-+-+-+-+-+-+-+------------------- evMessage = $FF00 | | | | | | | | +----------- evKeyboard = $0010 | | | | | | | | | +-+-+-+--- evMouse = $000F +++++++++++++++++=+=+=+++++++++++ +=+=+=+=+=+=+++++=+=+=+++++++++++ | | | | | | +--- evMouseDown = $0001 | | | | | +----- evMouseUp = $0002 | | | | +------- evMouseMove = $0004 | | | +--------- evMouseAuto = $0008 | | +----------- evKeyDown = $0010 | +------------------- evCommand = $0100 +--------------------- evBroadcast = $0200
Маски стандартных событий могут быть использованы для быстрого определения, принадлежит ли событие конкретному семейству событий. Например,
if Event.What and evMouse <> 0 then DoMouseEvent;
См. также TEvent, TView.EventMask, GetKeyEvent, GetMouseEvent, методы HandleEvent, PositionalEvents, FocusedEvents.

Константы gfXXXX Views

================================================================= Функция Эти мнемоники используются для установки полей GrowMode во всех объектах TView и порожденных. Биты, установленные в GrowMode, определяют, как видимый элемент будет изменяться в зависимости от изменений размера его владельца.
Значения Биты GrowMode определены как:
Рис. 14.3. Биты режима Grow.
+--- GrowMode --+ msb lsb +-+-+-+--- gfGrowAll = $0F +=+=+=+=+++++++++ +++=+++++++++++++ +-+-+ | | | | +--- gfGrowLoX = $01 | | | | +----- gfGrowLoY = $02 Неопределены | | +------- gfGrowHiX = $04 | +--------- gfGrowHiY = $08 +----------- gfGrowRel = $10
Таблица 14.12. Определения флага режима Grow.
------------------------------------------------------------------ Константа Назначение ------------------------------------------------------------------ gfGrowLoX Если установлен, то левая сторона видимого элемента будет находиться на одном расстоянии от правой стороны владельца. gfGrowLoY Если установлен, то верхняя сторона видимого элемента будет находиться на одном расстоянии от нижней стороны владельца. gfGrowHiX Если установлен, то правая сторона видимого элемента будет находиться на одном расстоянии от правой стороны владельца. gfGrowHiY Если установлен, то нижняя сторона видимого элемента будет находиться на одном расстоянии от нижней стороны владельца. gfGrowAll Если установлен, то видимый элемент будет сдвигаться вместе с правым нижним углом его владельца. gfGrowRel Для использования с объектами TWindow, которые находятся в панели экрана: видимый элемент будет изменять размер относительно размера владельца. Окно будет обрабатываться соответственно размеру владельца, даже когда происходит переключение между режимами 25 и 43/50 строк. ------------------------------------------------------------------ Заметим, что LowX= левая сторона; LowY = верхняя сторона; HiX = правая сторона; HiY = нижняя сторона.
См. также TView.GrowMode

Константы hcXXXX Views

================================================================= Значения Определены следующие константы контекста подсказки:
Таблица 14.13. Константы контекста подсказки.
----------------------------------------- Константа Значение Назначение ----------------------------------------- hcNoContext 0 Контекст не задан hcDragging 1 Объект - перемещаем -----------------------------------------
Функция Значение TView.HelpCtx по умолчанию - hcNoContext, которое указывает, что для видимого элемента нет контекста подсказки. TView.GetHelpCtx возвращает hcDragging, как только видимый элемент становится перемещаемым (это указывается состоянием флага sfDragging). Turbo Vision резервирует для контекста подсказки значения от 0 до 999. Программисты могут определять свои константы в диапазоне от 1,000 до 65,535.
См. также TView.HelpCtx, TStatusLine.Update.

Константы kbXXXX Drivers

================================================================= Функция Два множества констант, начинающихся с "kb" связаны с клавиатурой.
Значения Следующие значения определяют состояние клавиатуры и могут быть использованы при проверке регистров Shift клавиатуры, которое запоминается в байте с абсолютным адресом $40:$17. Например,
var ShiftState: Byte absolute $40:$17; . if ShiftState and kbAltShift <> 0 then AltKeyDown;
Таблица 14.14. Состояние клавиатуры и маски Shift.
------------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------------ kbRightShift $0001 Установлено, если правый Shift нажат kbLeftShift $0002 Установлено, если левый Shift нажат kbCtrlShift $0004 Установлено, если Ctrl нажат kbAltShift $0008 Установлено, если Alt нажат kbScrollState $0010 Установлено, если клавиатура в состоянии ScrollLock kbNumState $0020 Установлено, если клавиатура в состоянии NumLock kbCapsState $0040 Установлено, если клавиатура в состоянии CapsLock kbInsState $0080 Установлено, если клавиатура в состоянии InsLock ------------------------------------------------------------------
Таблица 14.15. Коды Alt-буква.
----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbAltA $1E00 kbAltN $3100 kbAltB $3000 kbAltO $1800 kbAltC $2E00 kbAltP $1900 kbAltD $2000 kbAltQ $1000 kbAltE $1200 kbAltR $1300 kbAltF $2100 kbAltS $1F00 kbAltG $2200 kbAltT $1400 kbAltH $2300 kbAltU $1600 kbAltI $1700 kbAltV $2F00 kbAltJ $2400 kbAltW $1100 kbAltK $2500 kbAltX $2D00 kbAltL $2600 kbAltY $1500 kbAltM $3200 kbAltZ $2C00 -----------------------------------------------------------
Таблица 14.16. Коды специальных клавиш.
----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbAltEqual $8300 kbEnd $4F00 kbAltMinus $8200 kbEnter $1C0D kbAltSpace $0200 kbEsc $011B kbBack $0E08 kbGrayMinus $4A2D kbCtrlBack $0E7F kbHome $4700 kbCtrlDel $0600 kbIns $5200 kbCtrlEnd $7500 kbLeft $4B00 kbCtrlEnter $1C0A kbNoKey $0000 kbCtrlHome $7700 kbPgDn $5100 kbCtrlIns $0400 kbPgUp $4900 kbCtrlLeft $7300 kbrayPlus $4E2B kbCtrlPgDn $7600 kbRight $4D00 kbCtrlPgUp $8400 kbShiftDel $0700 kbCtrlPrtSc $7200 kbShiftIns $0500 kbCtrlRight $7400 kbShiftTab $0F00 kbDel $5300 kbTab $0F09 kbDown $5000 kbUp $4800 -----------------------------------------------------------

Таблица 14.17. Коды Alt-число.

----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbAlt1 $7800 kbAlt6 $7D00 kbAlt2 $7900 kbAlt7 $7E00 kbAlt3 $7A00 kbAlt8 $7F00 kbAlt4 $7B00 kbAlt9 $8000 kbAlt5 $7C00 kbAlt0 $8100 -----------------------------------------------------------

Таблица 14.18. Коды функциональных клавиш.

----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbF1 $3B00 kbF6 $4000 kbF2 $3C00 kbF7 $4100 kbF3 $3D00 kbF8 $4200 kbF4 $3E00 kbF9 $4300 kbF5 $3F00 kbF0 $4400 ----------------------------------------------------------

Таблица 14.19. Коды Shift-функциональная клавиша.

----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbShiftF1 $5400 kbShiftF6 $5900 kbShiftF2 $5500 kbShiftF7 $5A00 kbShiftF3 $5600 kbShiftF8 $5B00 kbShiftF4 $5700 kbShiftF9 $5C00 kbShiftF5 $5800 kbShiftF0 $5D00 -----------------------------------------------------------

Таблица 14.20. Коды Ctrl-функциональная клавиша.

----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbCtrlF1 $5E00 kbCtrlF6 $6300 kbCtrlF2 $5F00 kbCtrlF7 $6400 kbCtrlF3 $6000 kbCtrlF8 $6500 kbCtrlF4 $6100 kbCtrlF9 $6600 kbCtrlF5 $6200 kbCtrlF0 $6700 -----------------------------------------------------------

Таблица 14.21. Коды Alt-функциональная клавиша.

----------------------------------------------------------- Константа Значение Константа Значение ----------------------------------------------------------- kbAltF1 $6800 kbAltF6 $6D00 kbAltF2 $6900 kbAltF7 $6E00 kbAltF3 $6A00 kbAltF8 $6F00 kbAltF4 $6B00 kbAltF9 $7000 kbAltF5 $6C00 kbAltF0 $7100 -----------------------------------------------------------

См. также evKeyDown, GetKeyEvent.

Константы ofXXXX Views

================================================================= Функция Эти мнемоники используются для ссылок на битовые позиции поля TView.Options. Установка позиции бита в 1 указывает, что видимый элемент имеет отдельный атрибут; очистка битовой позиции означает, что атрибут отключен или запрещен. Например,
MyWindow.Options := ofTileable + ofSelectable;
Значения Определены следующие опции флагов:
Таблица 14.23. Опции флагов.
------------------------------------------------------------------- Константа Назначение ------------------------------------------------------------------- ofSelectable Установлен, если видимый элемент выбирает себя автоматически (см. sfSelectable), например, отметкой мышкой в видимом элементе или клавишей Tab в диалоговом окне. ofTopSelect Установлен, если видимый элемент помещается перед всеми другими равными видимыми элементами, когда он выбран. Когда бит ofTopSelect установлен, вызов TView.Select соответствует вызову TView.MakeFirst. Окна (TWindow и его потомки) по умолчанию имеют этот бит установленным, что заставляет их располагаться перед всеми другими окнами на панели экрана, когда они выбираются. См. также TView.Select, TGroup.MakeFirst. ofFirstClick Если очищен, отметка мышкой, которая выбирает видимый элемент, не имеет эффекта. Если установлен, такая отметка мышкой будет работать как обычный отметка мышкой после выбора видимого элемента. Не имеет эффекта, если ofSelectable не установлен. См. также TView.HandleEvent, sfSelect, ofSelectable. ofFramed Установлен, если видимый элемент имеет рамку. TWindow и его потомки имеют TFrame, как свой последний подэлемент. Когда видимый элемент рисует себя, TFrame рисует рамку вокруг любого другого подэлемента, у которого установлен бит ofFrame. См. также TFrame, TWindow. ofPreProcess Установлен, если видимый элемент получает активные события до того, как они были посланы активному элементу. В противном случае очищен. См. также sfFocused, ofPostProcess, TGroup.Phase. ofPostProcess Установлен, если видимый элемент получает активное событие в случае, когда активный элемент не может их обработать. В противном случае очищается. См. также sfFocused, ofPreProcess, TGroup.Phase. ofBuffered Используется только для объектов TGroup. Установлен, если кэш-буфер распределяет доступную память. Буфер группы содержит образ экрана для всей группы, таким образом увеличивая скорость перерисовки. При отсутствии буфера, TGroup.Grow вызывает методы каждого подэлемента DrawView. Если впоследствии New и GetMem не могут получить достаточно памяти, буфера группы будут освобождать память. См. также GetBufMem. ofTileable Установлен, если панель экрана может расположить этот видимый элемент черепицей (или каскадом). Обычно используется только с объектами TWindow. ofCenterX Установлен, если видимый элемент центрируется по оси Х своего владельца при вставке в группу с использованием TGroup.Insert. ofCenterY Установлен, если видимый элемент центрируется по оси Y своего владельца при вставке в группу с использованием TGroup.Insert. ofCentered Установлен, если видимый элемент центрируется по обоим осям своего владельца при вставке в группу с использованием TGroup.Insert. -------------------------------------------------------------------
Биты Options определены:
Рис. 14.4. Флаги битов 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
См. также TView.Options.

Константы sbXXXX Views

================================================================= Функция Эти константы определяют различные области TScrollBar, в которых воспринимется отметка мышкой.
Функция TScrollBar.ScrollStep осуществляет преобразование этих констант в действительные значения шага скроллинга. Хотя она определена, константа sbIndicator никогда не передается в TScrollBar.ScrollStep.
Таблица 14.24. Константы полосы скроллинга.
----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- sbLeftArrow 0 Левая стрелка горизонтальной полосы скроллинга. sbRightArrow 1 Правая стрелка горизонтальной полосы скроллинга. sbPageLeft 2 Левая страничная область горизонтальной полосы скроллинга. sbPageRight 3 Правая страничная область горизонтальной полосы скроллинга. sbUpArrow 4 Стрелка вверх вертикальной полосы скроллинга. sbDownArrow 5 Стрелка вниз вертикальной полосы скроллинга. sbPageUp 6 Верхняя страничная область вертикальной полосы скроллинга. sbPageDown 7 Нижняя страничная область вертикальной полосы скроллинга. sbIndicator 8 Индикатор на полосе скроллинга. -----------------------------------------------------------
Рис. 14.5. Полоса скроллинга.
ч-- sbUpArrow # # ч-- sbPageUp # sbIndicator --------ц ю | # | # | # | # ч-- sbPageDown | # | # щ ч-- sbDownArrow ###############ю###################-+ ш ш ш ш | | | | | sbPageLeft sbPageRight | sbLeftArrow sbRightArrow
Следующие значения могут быть переданы в функцию TWindow.StandardScrollBar:
Таблица 14.25. Константы StandardScrollBar.
----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- sbHorizontal $0000 Полоса скроллинга горизонтальна. sbVertical $0001 Полоса скроллинга вертикальна. sbHandleKeyboard $0002 Полоса скроллинга реагирует на команды клавиатуры. -----------------------------------------------------------
См. также TScrollBar, TScrollBar.TScrollStep.

Константы sfXXXX Views

================================================================= Функция Эти константы используются для доступа к соответствующим битам полей TView.State. Поля TView.State никогда не должны изменяться напрямую; вместо этого Вы должны использовать метод TView.SetState.
Значения Определены следующие флаги состояния:
Таблица 14.26. Константы флагов состояния.
------------------------------------------------------------------- Константа Назначение ------------------------------------------------------------------- sfVisible Установлен, если видимый элемент виден в своем владельце. Видимые элементы по умолчанию sfVisible. Методы TView.Show и TView.Hide могут использоваться для модификации sfVisible. При sfVisible видимый элемент не обязательно видим на экране, поскольку его владелец может быть невидим. Для проверки видимости на экране, проверьте бит sfExposed или вызовите функцию TView.Exposed. sfCursorVis Установлен, если курсор видимого элемента видим, в противном случае очищен. По умолчанию очищен. Методы TView.ShowCursor и TView.HideCursor могут использоваться для модификации sfCursorVis. sfCursorIns Установлен, если курсор видимого элемента - сплошной блок, очищен, если курсор видимого элемента - линия. По умолчанию очищен. Методы TView.BlockCursor и TView.NormalCursor могут использоваться для модификации sfCursorIns. sfShadow Установлен, если видимый элемент имеет тень, в противном случае, очищен. sfActive Установлен, если видимый элемент это активное окно или подэлемент активного окна. sfSelected Установлен, если видимый элемент это текущий выбранный подэлемент внутри своего владельца. Каждый объект TGroup имеет поле Current, которое указывает на текущий выбранный подэлемент (или nil, если подэлементов не выбрано). Может быть только один выбранный подэлемент в TGroup. sfFocused Установлен, если видимый элемент сфокусированный. Видимый элемент - сфокусированный, если он выбран и все владельцы выше его также выбраны, т.е. если видимый элемент находится в цепи образованной указателями Current всех TGroup, начиная с TApplication (самый верхний видимый элемент в иерархии видимых элементов). Последний видимый элемент цепи это конечное назначение для всех сфокусированных событий. sfDragging Установлен, если видимый элемент можно растягивать, в противном случае, очищен. sfDisabled Установлен, если видимый элемент запрещен; очищен, если разрешен. sfModal Установлен, если видимый элемент - модальный. Всегда существует точно один элемент в выполняемой на Turbo Vision программе, обычно, объекты TAppplication или TDialog. Когда видимый элемент начинает выполняться (через вызов ExecView), этот видимый элемент становится модальным. Модальный видимый элемент представляет вершину (корень) активного дерева событий, получая события и управляя ими до тех пор пока не вызван его метод EndModal. Во время этого "локального" цикла событий события передаются нижним подэлементам в дереве видимых подэлементов. События от этих нижних видимых элементов передаются по дереву, но не далее модального видимого элемента. См. также sfSelected, sfFocused, TView.SetState, TView.HandleEvent, TGroup.ExecView. sfExposed Установлен, если у видимого элемента прямой или косвенный владелец - объект TApplication и следовательно он может быть виден на экране. Метод TView.Exposed использует этот флаг при отсечении (клиппинге), определяя какая часть видимого элемента действительно видна на экране. См. также TView.Exposed. -------------------------------------------------------------------
Значения Биты флага состояния определены так:
Рис. 14.6. Биты флага состояния.
+------ TView.State Flags ------+ msb lsb +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +=+=+=+=+++=+++++++++++++++++++++ | | | | | | | | | | +--- sfVisible = $0001 | | | | | | | | | +----- sfCursorVis = $0002 | | | | | | | | +------- sfCursorIns = $0004 | | | | | | | +--------- sfShadow = $0008 | | | | | | +----------- sfActive = $0010 | | | | | +------------- sfSelected = $0020 | | | | +--------------- sfFocused = $0040 | | | +----------------- sfDragging = $0080 | | +------------------- sfDisabled = $0100 | +--------------------- sfModal = $0200 +------------------------- sfExposed = $0800
См. также TView.State.

Константы smXXXX Drivers

================================================================= Функция Эти мнемонические константы используются с SetVideoMode для установки соответствующего значения видеорежима в ScreenMode.
Значения В Turbo Vision определены следующие режимы экрана:
Таблица 14.27. Константы режимов экрана.
----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- smBW80 $0002 Черно-белый режим на цветном smCO80 $0003 Цветной режим smMono $0007 Монохромный режим smFont8x8 $0100 43- или 50-строчный режим -----------------------------------------------------------
См. также SetVideoMode, ScreenMode.

Константы stXXXX Objects

================================================================= Функция Существует два набора констант начинающихся с "st", которые используются потоками Turbo Vision.
Значения Следующие костанты режима используются в TDosStream и TBufStream для определения режима доступа к файлу при открытии файла в потоках Turbo Vision:
Таблица 14.28. Режимы доступа к потоку.
----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- stCreate $3C00 Создать новый файл stOpenRead $3D00 Открыть файл только на чтение stOpenWrite $3D01 Открыть файл только на запись stOpen $3D02 Открыть файл на чтение/запись -----------------------------------------------------------
Следующие значения возвращаются TStream.Error в поле TStream.ErrorInfo, когда возникает ошибка потока:
Таблица 14.29. Коды ошибок потока.
----------------------------------------------------------- Константа Значение Назначение ----------------------------------------------------------- stOk 0 Нет ошибки stError -1 Ошибка доступа stInitError -2 Нельзя инициализировать поток stReadError -3 Чтение за концом потока stWriteError -4 Нельзя расширить поток stGetError -5 Get для незарегистрированного типа объекта stPutError -6 Put для незарегистрированного типа объекта -----------------------------------------------------------
См. также TStream.

Константы wfXXXX Views

================================================================= Функция Эти мнемоники определяют биты в поле Flags объектов TWindow. Если биты установлены, окно будет иметь соответствующие атрибуты: окно может перемещаться, изменять размер, закрываться или масштабироваться.
Значения Флаги окна определены так:
+ TWindow.Flags + | | msb lsb +=+=+=+=+=+=+=+=+ +++=+=+++++++++++ +--+--+ | | | +- wfMove = $01 | | | +--- wfGrow = $02 Неопределены| +----- wfClose = $04 +------- wfZoom = $08
Таблица 14.34. Константы флагов окна.
------------------------------------------------------------------ Константа Значение Назначение ------------------------------------------------------------------ wfMove $01 Окно можно перемещать wfGrow $02 Можно изменять размеры окна соответствующей кнопкой в левом правом углу wfClose $04 Рамка окна имеет закрывающую кнопку wfZoom $08 Рамка окна имеет кнопку масштабирования ------------------------------------------------------------------
Если отдельный бит установлен, соответствующая возможность подключается, в противном случае, эта возможность запрещена.
См. также TWindows.Flags

Константы wpXXXX Views

================================================================= Функция Эти константы определяют три стандартных цвета, отражая их назначение. По умолчанию, объект TWindow имеет палитру wpBlueWindow. По умолчанию, объект TDialog имеет палитру wpGrayWindow.
Значения Три стандартных палитры окна определены:
Таблица 14.35. Стандартные палитры окна.
-------------------------------------------------------------- Константа Значение Назначение -------------------------------------------------------------- wpBlueWindow 0 Желтый на голубом wpCuanWindow 1 Синий на бирюзовом wpGrayWindow 2 Черный на сером --------------------------------------------------------------
См. также TWindow.Palette, TWindow.GetPalette

Константы.

Режимы доступа к потоку.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- stCreate $3C00 Создает новый файл stOpenRead $3D00 Доступ только для чтения stOpenWrite $3D01 Доступ только для записи StOpen $3D02 Доступ для чтения и записи -------------------------------------------------------------
Коды ошибок потока.
------------------------------------------------------------- Код ошибки Значение Назначение ------------------------------------------------------------- stOk 0 Нет ошибки stError -1 Ошибка доступа stInitError -2 Не может инициализировать поток stReadError -3 Чтение за концом потока stWriteError -4 Не может расширить поток stGetError -5 Чтение незарегистрированного типа объекта stPutError -6 Запись незарегистрированного типа объекта -------------------------------------------------------------
Максимальный размер коллекции.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- MaxCollectionSize 16380 Максимальный размер TCollection -------------------------------------------------------------
Коды ошибок коллекции.
------------------------------------------------------------- Код ошибки Значение Назначение ------------------------------------------------------------- coIndexError -1 Индекс вне диапазона coOverflow -2 Переполнение -------------------------------------------------------------

Маски State для TView.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- sfVisible $0001 Видимый элемент виден sfCursorVis $0002 Видимый элемент имеет видимый курсор sfCursorIns $0004 Курсор видимого элемента - блок для режима вставки sfShadow $0008 Видимый элемент имеет тень sfActive $0010 Видимый элемент или его владелец - активное окно sfSelected $0020 Видимый элемент - владелец выбранного видимого элемента sfFocused $0040 Видимый элемент активен sfDragging $0080 Видимый элемент - перемещаемый sfDisabled $0100 Видимый элемент запрещен sfModal $0200 Видимый элемент в модальном состоянии sfExposed $0800 Видимый элемент присоединен к программе -------------------------------------------------------------
Константы модуля Views.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- heNoContext 0 Неопределенный код контекста подсказки heDragging 1 Контекстная подсказка пока объект перемещается MaxViewWidth 132 Максимальная длина видимого элемента в символах wnNoNumber 0 Номер TWindow -------------------------------------------------------------
Маски Option для TView.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- ofSelectable $0001 Видимый элемент может быть выбран ofTopSelect $0002 Выбираемый видимый элемент перемещается на вершину владельца ofFirstClick $0004 Отметка мышкой выбирает и производит действие ofFramed $0008 Видимый элемент имеет видимую рамку ofPreProcess $0010 Видимый элемент встретил активные события раньше активного видимого элемента ofPostProcess $0020 Видимый элемент встретил активные события позже активного видимого элемента ofBuffered $0040 Группа может иметь кэш буфер ofTileable $0080 Видимый элемент может располагаться черепицей на панели экрана ofCenterX $0100 Центр видимого элемента расположен горизонтально внутри владельца ofCenterY $0200 Центр видимого элемента расположен вертикально внутри владельца ofCentered $0300 Центр видимого элемента расположен горизонтально и вертикально внутри владельца -------------------------------------------------------------


Маски GrowMode для TView.

------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- gfGrowLoX $ 01 Левая сторона сответствует правой стороне владельца gfGrowLoY $02 Верх сответствует низу владельца gfGrowHiX $04 Правая сторона сответствует правой стороне владельца gfGrowHiY $08 Низ сответствует низу владельца gfGrowAll $0F Видимый элемент следует нижнему правому углу владельца gfGrowRel $10 Сохраняет относительный размер, когда изменяется размер экрана -------------------------------------------------------------

Маски DragMode для TView.

------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- dmDragMove $01 Видимый элемент может перемещаться dmDragGrow $02 Видимый элемент может изменять размер dmLimitLoX $10 Левая сторона видимого элемента не может выходить за Limits dmLimitLoY $20 Верх видимого элемента не может выходить за Limits dmLimitHiX $40 Правая сторона видимого элемента не может выходить за Limits dmLimitHiY $80 Низ видимого элемента не может выходить за Limits dmLimitAll $F0 Ни одна часть видимого элемента не может выходить за Limits -------------------------------------------------------------

Коды полосы скроллинга.

------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- sbLeftArrow 0 Левая горизонтальная стрелка полосы sbRightArrow 1 Правая горизонтальная стрелка полосы sbPageLeft 2 Левая горизонтальная страничная область полосы sbPageRight 3 Правая горизонтальная страничная область полосы sbUpArrow 4 Вертикальная стрелка вверх полосы sbDownArrow 5 Вертикальная стрелка вниз полосы sbPageUp 6 Вертикальное направление вверх страничной области полосы sbPageDown 7 Вертикальное направление вверх страничной области полосы sbIndicator 8 Индикатор полосы скроллинга -------------------------------------------------------------


Маски флага окна.

------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- wfMove $ 01 Верхняя строка рамки может перемещать окно wfGrow $02 Рамка окна имеет угол изменения размера wfClose $04 Рамка окна имеет закрывающую кнопку wfZoom $08 Рамка окна имеет кнопку масштабирования -------------------------------------------------------------

Элементы палитры TWindow.

------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- wpBlueWindow 0 Текст в окне желтый на синем wpCyanWindow 1 Текст в окне синий на бирюзовом wpGrayWindow 2 Текст в окне черный на сером -------------------------------------------------------------

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

------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- cmReceivedFocus 50 Видимый элемент получает активность cmReleasedFocus 51 Видимый элемент освобождает активность cmCommandSetChanged 52 Множество команд изменилось cmScrollBarChanged 53 Полоса скроллинга изменила значение cmScrollBarClicked 54 Полоса скроллинга была отмечена cmSelectWindowNum 55 Пользователь хочет выбирает окно по номеру cmRecordHistory 56 Список истории может сохранять содержимое строки ввода -------------------------------------------------------------

Переменные.

------------------------------------------------------------- Переменная Тип Начальное Назначение значение ------------------------------------------------------------- MinMinSize TPoint (X: 16; Y: 6) Минимальный размер окна ShadowSize TPoint (X: 2; Y: 1) Размер тени окна ShadowAttr Byte $08 Атрибут окна -------------------------------------------------------------

Функции.

------------------------------------------------------------- Функция Операция ------------------------------------------------------------- Message Пересылает сообщения, определенные пользователем между видимыми элементами -------------------------------------------------------------

Контекстная помощь.

Turbo Vision имеет встроенный инструмент, который помогает Вам реализовать контекстно-ориентированную помощь в Вашей программе. Вы можете назначить номер контекстной подсказки видимому элементу и когда видимый элемент станет активным, номер его подсказки станет текущим номером контекстной подсказки в программе. Чтобы создать глобальную контекстно-ориентированную подсказку, Вы можете реализовать HelpView, который знает номера контекстных подсказок, определенных Вами. Когда вызывается HelpView (обычно нажатием F1 или другой горячей клавиши), он должен спросить своего владельца о текущем контексте подсказки, вызвав метод GetHelpCtx. Затем HelpView может читать и отображать соответствующий текст подсказки. Пример HelpView включен в дистрибутивные диски Turbo Pascal. Контекстно-ориентированная помощь - это, вероятно, одна из последних возможностей, которую Вы будете реализовывать в Вашей программе, поэтому объекты Turbo Vision инициализируются с контекстом hcNoContext по умолчанию, что означает предопределенный контекст, который не изменяет текущего контекста. При необходимости Вы можете разработать номера подсказок, затем вставить правильный номер в соответствующий видимый элемент, вызвав SetHelpCtx сразу после создания видимого элемента. Контекстная подсказка так же используется строкой статуса для определения, какие видимые элементы отображаются. Вспомним, что когда Вы создаете строку статуса, Вы вызываете NewStatusDef, который определяет набор элементов статуса для данного диапазона значений контекстной помощи. Когда новый видимый элемент становится активным, контекст помощи этого элемента определяет, какая строка статуса будет отображаться.

Координаты Turbo Vision.

Метод Turbo Vision, назначающий коодинаты, может отличаться от используемого Вами. Отличие заключается в том, что если большинство координатных систем устанавливает размер в символах на экране, координатная система Turbo Vision указывает расстояние между символами. Например, если R - объект типа TRect, R.Assign(0, 0, 0, 0) назначает прямоугольник без размера - только точка. Наименьший прямоугольник, который может содержать что-либо, создается R.Assign (0, 0, 1, 1). Рис. 4.1 показывает TRect, созданный R.Assign(2, 2, 5, 4).
Рис. 4.1. Координатная система Turbo Vision.
0 1 2 3 4 5 6 7 0+---+---+---+---+---+---+---+ | | | | | | | | 1+---+---+---+---+---+---+---| | | | | | | | | 2+---+---+---+---+---+---+---| | | | R | R | R | | | 3+---+---+---+---+---+---+---| | | | R | R | R | | | 4+---+---+---+---+---+---+---| | | | | | | | | 5+---+---+---+---+---+---+---+
Хотя эта координатная система несколько непривычна, она позволяет вычислять размер прямоугольника намного проще.

Копирование потоков.

TStream имеет метод CopyFrom(S, Count), который копирует Count байт из потока S. CopyFrom может использоваться для копирования всего содержимого потока в другой поток. Если Вы постоянно обращаетесь к дисковым потокам, Вы можете скопировать их в EMS поток для более быстрого доступа:
NewStream := New(TEmsStream, Init(OldStream^.GetSize)); OldStream^.Seek(0); NewStream^.CopyFrom(OldStream, OldStream^.GetSize);

Краткие клавиши и конфликты.

По умолчанию метки, зависимые и независимые кнопки, могут реагировать на короткие клавиши даже когда активен какой-либо другой элемент диалогового окна. Например, когда Ваше диалоговое окно открывается, активны независимые кнопки и курсор находится на первой независимой кнопке. Нажав M для "Melted" Вы немедленно делаете активной зависимую кнопку Melted и включаете ее. Желательно делать короткие клавиши как можно более мнемоническими, хотя доступны только 26 букв и 10 цифр. Это может привести к конфликтам. Например, в Вашем маленьком диалоговом окне имеет смысл установить С как короткий набор для "Cheeses", "Consistenсy" и может существовать "Cheddаr". Во-первых, хотя удобно устанавливать первую букву слова для короткого набора, это не всегда возможно. Вы можете разрешить этот конфликт между "Cheeses" и "Consistency" например сделав О как короткий набор для "Consistency", но это трудно запомнить. Другой способ - изменить метку. Вместо метки "Cheeses" Вы можете пометить это кластер "Kind of Cheese" с К для короткого набора. Это только один из способов избежания конфликтов между короткими клавишами на одном уровне. Однако существует другой подход, который Вы можете использовать для избежания конфликтов, скажем, между меткой и элементом кластера. Короткие клавиши можно сделать локальными внутри элемента диалогового окна. Например, в предыдущем примере, если Вы локализуете короткие клавиши внутри каждого кластера, нажатие М во время активизации независимых кнопок не будет активизировать кнопки "Consistency" или кнопку "Melted". М будет функционировать как короткая клавиша только если Вы с помощью мышки или клавиши Tab перейдете в кластер "Consistency". По умолчанию все короткие клавиши активны во всем диалоговом окне. Если Вы хотите локализовать короткие клавиши, измените поле Options объекта при вставке в диалоговое окно. (Поле Options и бит ofPostProcess объяснены в главе 4.) Например, если Вы хотите сделать короткие клавиши для независимых кнопок локальными, Вы можете добавить дополнительную строку до вставки в диалоговое окно:

R.Assign(3, 3, 18, 6); B := New(PCheckBoxes, Init(R, NewSItem('~H~varti', NewSItem('~T~ilset', NewSItem('~J~arlsberg', nil))) )); B^.Options := B^.Options and not ofPostProcess; Insert(B);

Сейчас короткие клавиши H, T и J действуют только если Вы перейдете в кластер "Cheeses". Однако Alt-H, Alt-T и Alt-J продолжают функционировать как и ранее. Запомните, что метка никогда не активируется. Однако метка должна иметь установленный бит ofPostProcess для того, чтобы работать по короткой клавише (см. главу 5). Установка ofPostProcess означает, что пользователь может быстро вводить информацию в диалоговое окно. Однако пользователь может нажать короткую клавишу, ожидая перейти в одно место, но из-за конфликта перейдет в другое. Аналогично, если пользователь ожидает, что короткие клавиши активны, а они активны только локально, это может привести к тому, что короткая клавиша ничего не делает, когда она нажата вне пределов активной области. Лучший совет, который мы можем дать Вам - активно тестируйте диалоговые окна на наличие конфликтов. Избегайте дублированных коротких клавиш где это возможно и всегда обеспечьте для пользователя ясность, какие опции доступны.

Кто обрабатывает общие сообщения?

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

Кто сохраняет?

Важное предупреждение о потоках: пользователь объекта - это тот объект, который должен записывать этот объект в поток. Это предупреждение подобно тому с которым Вы вероятно сталкивались при использовании традиционного Паскаля: владелец указателя - это тот, кто должен освободить этот указатель. В сложной реальной программе многочисленные объекты часто будут содержать указатель на какую-то структуру. Когда придет время для В/В в поток, Вы должны решить кто владелец структуры; только этот владелец должен посылать эту структуру в поток. Иначе Вы получите в потоке несколько копий одной структуры. Затем когда Вы будете читать поток будет создано несколько экземпляров структуры и каждый отдельный объект теперь будет указывать на собственную копию структуры вместо единственной первоначальной структуры.

Кто сверху?

Используя технику, описанную ранее, Вы так же можете например определить, какое окно является верхним из видимых элементов его типа на панели экрана. Поскольку общее сообщение посылается каждому подэлементу модального видимого элемента в Z-порядке (порядок обратный вставке), самый последний вставленный видимый элемент - это "верхний" видимый элемент на панели экрана. Рассмотрим ситуацию, возникающую в IDE, когда пользователь имеет окно просмотра, открытое на вершине панели экрана во время пошагового выполнения кода в окне редактора. Окно просмотра может быть активным окном (двойная рамка), но курсор выполнения в окне кода требует сохранения трассы выполнимого кода. Если на панели экрана открыто несколько окон редактора, они могут не перекрываться вообще, но IDE должен знать какое из окон редактора предназначено для трассировки. Ответ: конечно самое верхнее окно редактора, которое определено как последнее вставленное. Для того, чтобы определить, какое из окон "верхнее", IDE посылает общее сообщение, отклик на которое знают только окна редактора. Первое окно редактора, которое получает общее сообщение и будет последним вставленным; оно обработает событие, очищая его, и IDE узнает какое окно использовать для трассировки кода, читая результат, возвращенный Message.

Куда идут события.

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

Куда поместить функциональность.

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

Лучший способ для Write.

Хотя Вы можете выполнить процедуру Write в Turbo Vision, это неверный путь. Во-первых, если Вы просто пишете что-нибудь, нет способа предотвратить случайное затирание окна или другого видимого элемента. Во-вторых, Вам требуется писать в локальных координатах текущего видимого элемента и отсекать по его границам. В-третьих, встает вопрос об использовании цвета при выводе. Процедура WriteStr Turbo Vision не только знает как писать в локальных координатах и как отсекать по границам видимого элемента, но так же как использовать палитру цветов видимого элемента. Процедура WriteStr берет координаты X и Y, строку для записи и индекс цвета в качестве параметров. Аналогично WriteStr, процедура WriteChar определена:
WriteChar(X, Y, Ch, Color, Count);
Подобно WriteStr, WriteChar позиционирует свой вывод в координаты (X, Y) внутри видимого элемента и пишет Count копий символа Ch цветом, указываемым элементом Color из палитры видимого элемента. Каждый из этих методов должен вызываться только изнутри метода Draw видимого элемента. Это единственное место, где Вам требуется писать что-либо внутри Turbo Vision.

Маскирование событий.

Каждый видимый элемент имеет битовое поле EventMask, которое используется для определения, какие события будет обрабатывать видимый элемент. Биты EventMask соответствуют битам поля TEvent.What. Если бит для данного вида события установлен, видимый элемент будет принимать этот вид события для обработки. Если бит для данного вида события очищен, видимый элемент будет игнорировать этот вид событий.

Механизм потоков.

Сейчас, когда мы просмотрели использование потоков, давайте посмотрим что делает Turbo Vision с Вашими объектами, когда Вы вводите или выводите их.

Меню.

TMenuView и 2 его потомка TMenuBar и TMenuBox предоставляют базовые объекты для создания выпадающих меню и подменю, вложенных на любой уровень. Вы задаете текстовые строки для выбора меню (возможно подсвечивать буквы для короткого набора) вместе с командами, связанными с каждым выбором. Методы HandleEvent реализуют механизм выбора меню с помощью мышки и клавиатуры (включая короткий набор и горячие клавиши). Выбор меню отображается с помощью объекта TMenuBar, который обычно принадлежит объекту TApplication. Выборы меню отображаются в объектах типа TMenuBox. В большинстве программ Вы не вызываете напрямую объекты меню. Перекрывая TApplication.InitMenuBar соответствующим набором вложенных вызовов New, NewSubMenu, NewItem и NewLine, Turbo Vision строит, отображает и взаимодействует с требуемыми меню.

Метки управляющих элементов.

Конечно, установки управляющих элементов может быть недостаточно. Простое предоставление набора выборов может ничего не говорить пользователю о том, что он выбирает! Turbo Vision предоставляет удобный метод для установки меток управляющих элементов в виде другого управляющего элемента TLabel. TLabel делает больше, чем кажется на первый взгляд. TLabel не только отображает текст, но и связывается с другим видимым элементом. Отметка мышкой метки приводит к активизации связанного видимого элемента. Вы так же можете определить букву сокращенного набора для метки, окружив букву "~". Чтобы пометить независимые кнопки, добавьте следующий код сразу после вставки независимых кнопок в диалоговое окно:
R.Assign(2, 2, 10, 3); Insert(New(PLabel, Init(R, 'Cheeses', B)));
Вы можете сейчас активировать набор независимых кнопок, отметив слово "Cheeses". Это так же предоставляет информацию об элементах в этом окне. Аналогично Вы можете добавить метку к зависимым кнопкам с помощью кода:
{ TVGUID14.PAS } R.Assign(21, 2, 33, 3); Insert(New(PLabel, Init(R, 'Consistency', B)));
Рис. 2.9. Диалоговое окно с метками кластеров.
+=[ю]======= Demo Dialog Box =============+ | | | Cheeses Consistency | | +----------------+ +--------------+ | | | [ ] HVarti | | [*] Solid | | | | [ ] Tilset | | [ ] Runny | | | | [ ] Jarlsberg | | [ ] Melted | | | +----------------+ +--------------+ | | | | | | | | | | OK m Cancel m | | ^^^^^^^^ ^^^^^^^^ | +==========================================+

Метод Done.

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

Метод GetColor.

Отображение цвета палитры выполняется виртуальной функцией GetColor из TView. GetColor поднимается по дереву видимых элементов от рисуемогоо элемента к его владельцу, затем к владельцу владельца и т.д. пока не дойдет до объекта программа. Для каждого объекта в этой цепочке GetColor вызывает GetPalette этого объекта. Результат - цвет атрибута. Палитра видимого элемента содержит смещения в палитре владельца за исключением прикладной программы, чья палитра содержит атрибуты цветов.

Метод Init.

Первый из трех операторов HelloWorld.Init - это необходимый вызов констрактора. Все объекты, содержащие виртуальные методы, должны быть созданы (через вызов их констрактора) до вызовов любых других методов этого объекта. Все констракторы Turbo Vision имеют имя Init. Это удобное соглашение, которым мы рекомендуем пользоваться. HelloWorld.Init устанавливает объекты главной программы для использования. Он очищает экран, устанавливает некоторые значения для важных переменных, заполняет панель экрана и выводит строку статуса и полосу меню. Он вызывает констракторы многих других объектов, некоторые из которых никогда не видны, поскольку они вызываются внутри. Интересно использование встроенного отладчика для трассировки HelloWorld.Init через F8 с последующим просмотром дисплея через Alt -F5. Панель экрана, полоса меню и строка статуса будут появляться, готовя главную программу для использования.

Метод Insert.

Вставка окна в DeskTop автоматически приводит к появлению окна. Метод Insert используется, чтобы дать визуальный контроль над видимым элементом. Когда Вы выполняете
DeskTop^.Insert(Window);
Вы вставляете Window в панель экрана. Вы можете вставить любое число видимых элементов в групповой объект, такой как панель экрана. Группа, в которую Вы вставляете видимый элемент называется видимым элементом - владельцем, а видимый элемент, который Вы вставляете, называется видимым подэлементом. Заметим, что видимый подэлемент сам может быть группой и может иметь свои видимые подэлементы. Например, когда Вы вставляете окно в панель экрана, окно является подэлементом, но окно может владеть рамкой, полосами скроллинга и другими видимыми подэлементами. Этот процесс установления связей между видимыми объектами создает дерево видимых элементов. (Взаимосвязи между видимыми элементами объяснены в главе 4.)

Метод Run.

Почти вся работа программы в Turbo Vision выполняется внутри метода главной программы Run. Мистика начинается, когда Вы смотрите на определение THelloApp для нахождения определения метода Run. Его здесь нет - поскольку Run наследуется от родительского объекта TApplication. Run - это та части, в которой Ваша программа будет, вероятно, тратить большую часть своего времени. Она состоит главным образом из цикла repeat.until, показанном здесь в псевдокоде:
repeat Получить событие; Обработать событие; until Quit;
Это не точный код, а общая схема реализации Run. В сущности программа Turbo Vision циклически выполняет 2 задачи: получение события (где событие - это, в сущности, "сделать что-нибудь") и обработка этого события. Одно из событий вычисляется в некоторый вид команды выхода и цикл завершается.
Примечание: Более детальное описание обработки событий приведено в главе 5.

Метод ValidView.

Поскольку LowMemory проверяется достаточно часто, TApplication имеет метод ValidView, который может вызываться для выполнения необходимой проверки. Используя ValidView, проверка if в последних 8 строках может быть заменена на 2 строки:
DoIt := (ValidView(D) <> nil) and (DeskTop^.ExecView(D) = cmYes;
ValidView возвращает либо указатель на переданный видимый элемент, либо nil, если видимый элемент неверен. Если LowMemory возвращает True, ValidView освобождает видимый элемент и вызывает OutOfMemory.

Методы Load и Store.

Действительное чтение и запись объектов в поток обрабатывается методами Load и Store. Хотя каждый объект должен содержать эти методы для того, чтобы его можно было использовать с потоками, Вы никогда не вызываете их прямо. (Они вызываются из Get и Put). Все, что Вам требуется сделать - это убедиться, что Ваш объект знает как послать себя в поток, когда ему говорят сделать это. Благодаря ООП эта работа очень проста, поскольку большая часть механизма наследуется из объекта предка. Все, что Ваш объект должен сделать - это загрузить или сохранить ту часть, которую Вы добавили; за остальное отвечает вызов метода предка. Например Вы породили новый тип видимого элемента от TWindow, назвав его именем известного сюрреалиста Рене Магритте, который нарисовал много известных картин с окнами:
type TМagritte = object(TWindow) Painted: Boolean; constructor Load(var S: TStream); procedure Draw; procedure Store(var S: TStream); end;
В часть данных было добавлено только одно поле Boolean. Для того, чтобы загрузить объект, Вы просто читаете стандартный TWindow, а затем читаете дополнительный байт, соответствующий полю Boolean. То же самое применимо к сохранению объекта: Вы просто записываете TWindow, а потом записываете еще один байт. Типичные методы Load и Store для порожденных объектов имеют вид:
constructor TМargitte.Load(var S: Stream); begin TWindow.Load(S); S.Read(Painted, SizeOf(Boolean)) end;
procedure TМargitte.Store(var S: Stream); begin TWindow.Store(S); S.Write(Painted, SizeOf(Boolean)) end;
Предупреждение: Вы полностью ответственны за то, что сохраняется столько же данных, сколько и загружается и что данные загружаются в том же порядке, в каком они сохранялись. Компилятор не выдает ошибок. Это может приводить к огромным проблемам, если Вы неаккуратны. Если Вы изменяете поля объектов, убедитесь, что скорректированы и Load и Store.

Методы Turbo Vision.

Методы Turbo Vision могут характеризоваться 4 (возможно перекрывающимися) способами, каждый из которых описан здесь.

Модальные видимые элементы.

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

Модификация механизма событий.

Сердцем текущего модального видимого элемента является цикл типа:
var E: TEvent; begin E.What := evNothing; repeat if E.What <> evNothing then EventError(E); GetEvent(E); HandleEvent(E); until EndState <> Continue; end;

Модификация поведения видимых элементов.

До этого момента Вы видели как ведут себя стандартные видимые элементы по умолчанию. Но иногда Вам потребуется, чтобы видимые элементы выглядели или действовали несколько по-другому и Turbo Vision предоставляет такую возможность. Этот раздел объясняет способы модификации стандартных видимых элементов. Каждый видимый элемент Turbo Vision имеет 4 поля, которые можно использовать для изменения поведения этого элемента. 3 из них описаны здесь: слово Options, байт GrowMode и байт DragMode. Четвертое поле - слово EventMask описано в главе 5. Существует так же слово State, содержащее информацию о текущем состоянии видимого элемента. В отличие от других полей State используется только для чтения. Его значение должно изменяться только методом SetState. Для дополнительных деталей смотри раздел "Флаг State и SetState".

Модуль App.

Модуль App (предоставлен в исходных кодах) обеспечивает элементы оболочки Turbo Vision. 4 очень мощных объектных типа определены в App, включая объекты TApplication и TProgram, которые служат в качестве программ Turbo Vision и объект панели экрана, который управляет большинством элементов в оконных программах.
Типы.
------------------------------------------------------------- Тип Использование ------------------------------------------------------------- TApplication Объект-программа с монитором событий, монитором экрана, обработкой ошибок и управлением памятью TBackGround Цвет фона для панели экрана TDeskTop Групповой объект для окон и диалоговых окон TProgram Абстрактный объект-программа -------------------------------------------------------------
Переменные.
------------------------------------------------------------- Переменная Тип Начальное Назначение значение ------------------------------------------------------------- Application PProgram nil Указатель на текущую программу DeskTop PDeskTop nil Указатель на текущую панель экрана StatusLine PStatusLine nil Указатель на текущую строку статуса MenuBar PMenuView nil Указатель на текущую полосу меню -------------------------------------------------------------

Модуль Dialogs.

Модуль Dialogs определяет большинство элементов наиболее часто используемых при создании диалоговых окон. Это включает сами диалоговые окна (которые являются специализированными окнами) и различные элементы управления, такие как кнопки, метки, зависимые и независимые кнопки, строки ввода и списки истории.
Типы.
------------------------------------------------------------- Тип Использование ------------------------------------------------------------- TButton Нажатия кнопок для генерации команд TCheckBoxes Кластеры с включением и выключением кнопок TCluster Абстракный тип для зависимых и независимых кнопок TDialog Специализированное окно для диалоговых окон THistory Список предыдущих элементов для строки ввода TInputLine Редактор текстового ввода TLabel Метка для кластера или строки ввода TListBox Скроллингуемый список для выбора пользователем TParamText Форматированный статический текст TRadioButtons Кластер или кнопки, только одна из которых может быть нажата TSItem Элементы строк в связанном списке, используемые кластерами TStaticText Простой текст -------------------------------------------------------------
Константы.
Флаги кнопок.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- bfNormal $00 Обычная кнопка bfDefault $01 Кнопка по умолчанию bfLeftJust $02 Кнопка текста может быть выровнена влево -------------------------------------------------------------
Процедуры и функции.
------------------------------------------------------------- Функция Операция ------------------------------------------------------------- NewSItem Создает новый элемент строки для окна списка -------------------------------------------------------------
------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- RegistersDialogs Регистрирует все объекты в модуле Dialogs для использования с потоками -------------------------------------------------------------

Модуль Drivers.

Модуль Drivers содержит все специализированные драйверы Turbo Vision, включая драйверы мышки и клавиатуры, поддержку экрана и систему обработки ошибок с монитором событий для программ, управляемых событиями.
Типы.
------------------------------------------------------------- Тип Использование ------------------------------------------------------------- TEvent Тип записи события TSysErrorFunc Функциональный тип обработчика системных ошибок -------------------------------------------------------------
Константы.
Маски состояния кнопок мышки.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- mbLeftButton $01 Левая кнопка мышки mbRightButton $02 Правая кнопка мышки -------------------------------------------------------------
Коды событий.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- evMouseDown $0001 Кнопка мышки нажата evMouseUp $0002 Кнопка мышки освобождена evMouseMove $0004 Мышка изменила положение evMouseAuto $0008 Автоматический повтор события от мышки evKeyDown $0010 Событие - нажатие клавиши evCommand $0100 Событие - команда evBroadcast $0200 Событие - общее сообщение -------------------------------------------------------------
Маски событий.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- evNothing $0000 Событие очищено evKeyboard $0010 Событие пришло от клавиатуры evMouse $000F Событие пришло от мышки evMessage $FF00 Событие - сообщение или команда -------------------------------------------------------------
Маски клавиатуры.
------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- kbRightShift $0001 Нажат правый Shift kbLeftShift $0002 Нажат левый Shift kbCtrlShift $0004 Нажат Ctrl и Shift kbAltShift $0008 Нажат Alt и Shift kbScrollState $0010 Установлен Scroll lock kbNumState $0020 Установлен Num lock kbCapsState $0040 Установлен Caps lock kbInsState $0080 Включен режим Insert -------------------------------------------------------------

Коды стандартных команд.

------------------------------------------------------------- Команда Значение Назначение ------------------------------------------------------------- cmValid 0 Проверка правильности нового элемента cmQuit 1 Завершение программы cmError 2 Неопределено cmMenu 3 Активность полосы меню cmClose 4 Закрывает текущее окно cmZoom 5 Масштабирует окно cmResize 6 Изменяет размеры окна cmNext 7 Делает активным следующее окно cmPrev 8 Делает активным предыдущее окно -------------------------------------------------------------

Стандартные команды TDialog.

------------------------------------------------------------- Команда Значение Назначение ------------------------------------------------------------- cmOK 10 Нажата кнопка OK cmCanced 11 Нажата кнопка Cancel или Esc cmYes 12 Нажата кнопка Yes cmNo 13 Нажата кнопка No cmDefault 14 Нажата кнопка по умолчанию или Enter -------------------------------------------------------------

Режимы экрана.

------------------------------------------------------------- Константа Значение Назначение ------------------------------------------------------------- smBW80 $0002 Черно-белый режим smCO80 $0003 Цветной режим smMono $0007 Монохромный режим smFont8x8 $0100 Режим 43 или 50 строк (EGA/VGA) -------------------------------------------------------------

Переменные.

Инициализированные переменные.

------------------------------------------------------------- Переменная Тип Начальное Назначение значение ------------------------------------------------------------- ButtonCount Byte 0 Число кнопок мышки MouseEvents Boolean False Указывает на выбор мышкой DoubleDelay Word 8 Максимальное время задержки между двойными нажатиями RepeatDelay Word 8 Задержка между автоматическим повтором события от мышки -------------------------------------------------------------

Неинициализированные переменные.

------------------------------------------------------------- Переменная Тип Назначение ------------------------------------------------------------- MouseIntFlag Byte Только для внутренного использования MouseButtons Byte Какая кнопка была нажата MouseWhere TPoint Позиция курсора мышки StartupMode Word Режим экрана при запуске программы ScreenMode Word Текущий режим экрана ScreenWidth Byte Ширина экрана в колонках ScreenHeight Byte Высота экрана в строках CheckSnow Boolean Определяет "снежность" для CGA HiResScreen Boolean Экран может отображать 43 или 50 строк (EGA/VGA) ScreenBuffer Pointer Указатель на видеобуфер экрана CursorLines Word Начало и окончание строк просмотра для установки типа курсора -------------------------------------------------------------


Переменные обработчика системных ошибок.

------------------------------------------------------------- Переменная Тип Начальное Назначение значение ------------------------------------------------------------- SysErrorFunc SysErrorFunc SystemError Функция, вызываемая монитором системной ошибки при ее возникновении SysColorAttr Word $4E4F Видеоатрибуты для сообщений об ошибках на цветном экране SysMonoAttr Word $7070 Видеоатрибуты для сообщений об ошибках на монохромном экране CtrlBreakHit Boolean False Указывает, нажата ли пользователем Ctrl-Break SaveCtrlBreak Boolean False Статус проверки Ctrl-Break при запуске программы -------------------------------------------------------------

Процедуры и функции.

Процедуры монитора событий.

------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- InitEvents Инициализирует монитор событий DoneEvents Закрывает монитор событий ShowMouse Отображает курсор мышки HideMouse Стирает курсор мышки GetMouseEvent Создает запись события от мышки GetKeyEvent Создает запись события от клавиатуры -------------------------------------------------------------

Процедуры управления экраном.

------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- InitVideo Инициализирует монитор экрана DoneVideo Закрывает монитор экрана SetVideoMode Выбирает режим экрана (цветной, черно-белый, монохромный, высокого разрешения) ClearScreen Очищает экран при любом видео режиме -------------------------------------------------------------

Функция по умолчанию обработчика системной ошибки.

------------------------------------------------------------- Функция Операция ------------------------------------------------------------- SystemError Отображает сообщение об ошибке в нижней строке экрана и подсказки для завершения или повтора -------------------------------------------------------------


Процедуры обработчика системной ошибки.

------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- InitSysError Инициализирует монитор системных ошибок DoneSysError Закрывает монитор системных ошибок -------------------------------------------------------------

Функции поддержки клавиатуры.

------------------------------------------------------------- Функция Операция ------------------------------------------------------------- GetAltChar Возвращает символ от клавиатуры GetAltCode Возвращает скан-код от клавиатуры -------------------------------------------------------------

Процедура форматирования строки.

------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- FormatStr Форматирует строку -------------------------------------------------------------

Процедуры копирования буфера.

------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- MoveBuf Копирует буфер в другой буфер MoveChar Копирует одну или более копий символа в буфер MoveCStr Копирует строку управления в буфер MoveStr Копирует строку в буфер -------------------------------------------------------------

Функция длины строки.

------------------------------------------------------------- Функция Операция ------------------------------------------------------------- CStrLen Возвращает длину строки, игнорируя "~" -------------------------------------------------------------

Инициализация драйвера.

------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- InitDrivers Инициализирует драйверы модуля -------------------------------------------------------------

Модуль HistList.

Модуль HistList содержит все переменные, процедуры и функции необходимые для реализации списков истории.
Переменные.
------------------------------------------------------------- Переменная Тип Начальное Назначение значение ------------------------------------------------------------- HistoryBlock Pointer nil Буфер памяти для всех элементов списка истории HistorySize Word 1024 Размер блока истории HistoryUsed Word 0 Смещение в блоке истории, указывающее число использованных блоков -------------------------------------------------------------

Модуль Memory.

Модуль Memory содержит процедуры монитора памяти Turbo Vision, которые обеспечивают функции управления кучей.
Переменные.
------------------------------------------------------------- Переменная Тип Начальное Назначение значение ------------------------------------------------------------- LowMemSize Word 4096 div 16 Размер пула надежности -------------------------------------------------------------
Процедуры и функции.
------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- InitMemory Инициализирует монитор памяти DoneMemory Закрывает монитор памяти GetBufMem Распределяет кэш-буфер для группы FreeBufMem Удаляет кэш-буфер для группы -------------------------------------------------------------
------------------------------------------------------------- Функция Операция ------------------------------------------------------------- LowMemory Указывает распределен ли буфер надежности MemAlloc Распределяет память с проверкой буфера надежности -------------------------------------------------------------

Модуль Menus.

Модуль Menus обеспечивает все объекты и процедуры для системы меню Turbo Vision, включая выпадающие меню и активные элементы строки статуса.
Типы.
------------------------------------------------------------- Тип Использование ------------------------------------------------------------- TMenu Связанный список записей TMenuItem TMenuBar Связанный с меню горизонтальный заголовок TMenuBox Выпадающие окна меню TMenuItem Запись, связывающая метку текста, горячую клавишу, команду и контекстную подсказку TMenuStr Строковый тип для меток меню TMenuView Абстрактный объектный тип для полосы и окон меню TStatusDef Запись, связывающая контекстных подсказки со списком элементов строки статуса TStatusItem Строка сообщения внизу экрана программы, включающая список записей TStatusDef TStatusLine -------------------------------------------------------------
Процедуры и функции.
Функции TMenuItem.
------------------------------------------------------------- Функция Операция ------------------------------------------------------------- NewItem Создает новый элемент меню NewLine Создает строку окна меню NewSubMenu Создает подменю полосы меню или окна меню -------------------------------------------------------------
Процедуры TMenu.
------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- NewMenu function Распределяет меню в куче DisposeMenu procedure Удаляет меню из кучи -------------------------------------------------------------
Функции TStatusLine.
------------------------------------------------------------- Функция Операция ------------------------------------------------------------- NewStatusDef Определяет диапазон контекстных подсказок и указатель на список элементов статуса NewStatusKey Определяет элемент строки статуса и связывает его с командой и горячей клавишей -------------------------------------------------------------

Модуль Objects.

Модуль Objects содержит основные определения объектов Turbo Vision, включая базовый объект иерархии Turbo Vision TObject, а так же все невидимые элементы Turbo Vision: потоки, коллекции и ресурсы.

Модуль TextView.

Модуль TextView содержит несколько специализированных видимых элементов для отображения текста в окне скроллинга.
Типы.
------------------------------------------------------------- Тип Использование ------------------------------------------------------------- TTerminal TTY подобный текстового устройства TTerminalBuffer Круговой текстовый буфер для TTerminal TTextDevice Абстрактный объект текстового усройства -------------------------------------------------------------
Процедура.
------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- AssignDevice Назначает устройство текстового файла для ввода и/или вывода -------------------------------------------------------------

Модуль Views.

Модуль Views содержит основные компоненты видимых элементов. Это оба абстрактных типа, таких как TView и TGroup и полезные компоненты более сложных групп, таких как рамки окон и полосы скроллинга. Более сложные видимые элементы находятся в модулях Dialogs и TextView.
Типы.
------------------------------------------------------------- Тип Использование ------------------------------------------------------------- TCommandSet Разрешает и запрещает группы команд TDrawBuffer Буфер, используемый для методов отрисовки TFrame Рамка объекта, используемая окнами TGroup Абстрактный объект для сложных видимых элементов TListViewer Базовый тип для окон списков и т.п. TPalette Тип палитры, используемой всеми видимыми элементами TScrollBar Объект определяющий полосу скроллинга TScrollChars Символьные компоненты полосы скроллинга TScroller Базовый объект для скроллинга текста в окнах TTitleStr Строка заголовка, используемая TFrame TVideoBuf Видеобуфер, используемый монитором экрана TView Абстракный объект; основа всех видимых объектов TWindow Базовый объект для окон изменяющих размеры -------------------------------------------------------------

Нахождение активного элемента.

Активный видимый элемент обычно подсвечивается на экране. Например, если Вы открыли на панели экрана несколько окон, активное окно окружено двойной рамкой, а остальные одинарной. Внутри диалогового окна активный элемент управления (а элемент управления это тоже видимый элемент) ярче других, указывая на то, что он будет действовать когда Вы нажмете Enter. Т.е. активный элемент управления также является элементом управления по умолчанию. (На монохромных мониторах Turbo Vision добавляет символы стрелок для указания активного элемента).

Не-объекты в потоке.

Вы можете писать в поток данные, которые не являются объектами, но Вы должны использовать при этом другой подход. Стандартные методы Get и Put требуют, чтобы Вы сохраняли или загружали объект, порожденный от TObject. Если Вы хотите создать поток не-объектов, перейдите прямо на низкоуровневые процедуры Read и Write, каждая из которых читает или пишет заданное число байт в поток. Этот же механизм используется в Get и Put для чтения и записи данных объектов; Вы просто обходите механизм VMT, используемый в Get и Put.

Неиспользованное время.

Другое преимущество центрального местонахождения TApplication. GetEvent в том, что он вызывает метод TApplication.Idle, если нет готовых событий. TApplication.Idle - это пустой метод, который Вы можете перекрыть для того, чтобы выполнять параллельную обработку одновременно с текущим видимым элементом. Например предположим, Вы определили видимый элемент, названный THeapView, который использует метод UpDate для отображения доступной в данный момент памяти кучи. (Пример просмотра кучи включен в демонстрационные программы на Ваших дистрибутивных дисках.) Если Вы перекрываете TApplication.Idle, следующим кодом пользователь сможет увидеть отображение доступной памяти в куче вне зависимости от его нахождения в программе.
procedure TMyApp.Idle; begin HeapViewer.Update; end;

Ненужные события.

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

Несколько видимых элементов в окне.

Давайте продублируем интерьер и создадим окно с двумя скользящими видимыми элементами для текстового файла. Мышка или клавиша Tab автоматически выбирает один из двух интерьеров. Каждый видимый элемент скользит независимо и имеет собственную позицию курсора. Чтобы сделать это, расширьте метод MakeInterior так, чтобы он знал, какая часть окна является активным интерьером (поскольку различные части ведут себя несколько по-разному) и сделайте 2 вызова MakeInterior в TDemoWindow.Init.
{ TVGUID09.PAS }
{ Не забудьте изменить объявление MakeInterior } procedure TDemoWindow.MakeInterior(Bounds: TRect; Left: Boolean); var Interior: PInterior; R: TRect; begin Interior := New(PInterior, Init(Bounds, StandartScrollBar(sbHorizontal), StandartScrollBar(sbVertical))); if Left then Interior^.GrowMode := gfGrowHiY else Interior^.GrowMode := gfGrowHiX + gfGrowHiY; Insert(Interior); end;
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Word); var S: string[3]; R: TRect; begin Str(WindowNo, S); TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber); GetExtent(Bounds); R.Assign(Bounds.A.X, Bounds.A.Y, Bounds.B.X div 2 + 1, Bounds.B.Y); MakeInterior(R, True); R.Assign(Bounds.B.X div 2, Bounds.A.Y, Bounds.B.X, Bounds.B.Y); MakeInterior(R,False); end;
Рис. 2.6. Окно с несколькими панелями.
+-----------------------------------------------------------+ |***********************************************************| |*+=[ю]================ Demo Window 1 ================[ш]=+*| |*| | while not Eof(F) and (LineCountш*| |*|var | begin #*| |*| LineCount: Integer;| Readln(F, S); #*| |*| Lines: array[0Max| Lines[LineCount] := NewStr(S)#*| |*| | Inc(LineCount); #*| |*|type | end; #*| |*| TMyApp = object(TAp| Close(F); #*| |*| procedure HandleE|end; #*| |*| procedure InitMen| ю*| |*| procedure InitSta|procedure DoneFile; #*| |*| procedure NewWind|var #*| |*| end; | I: Integer; #*| |*| |begin щ*| |*+=====================+=<ю############################>-+*| |***********************************************************| +-----------------------------------------------------------+

Заметим, что Вы изменили форму и содержимое MakeInterior. Вместо объявления двух статических полос скроллинга и передачи их в метод Init, Вы просто включили вызовы StandardScrollBar в качестве параметров Init. Предыдущая форма несколько яснее, но эта более эффективно. Если Вы уменьшите окна в TVGUID09.PAS, Вы заметите, что вертикальная полоса скроллинга будет перекрыта левым интерьером видимого элемента, если Вы передвините правую сторону окна слишком близко к левой. Чтобы предотвратить это, Вы можете установить нижнюю допустимую границу на уменьшение окна. Вы делаете это, перекрывая метод SizeLimits в TWindow.

{ TVGUID10.PAS }

{ Не забудьте добавить SizeLimits в TDemoWindow. Это виртуальный метод} procedure TDemoWindow.SizeLimits(var Min, Max: TPoint); var R: TRect; begin TWindow.SizeLimits(Min, Max); GetExtent(R); Min.X := R.B.X div 2; end;

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

Невидимые элементы.

Семейство невидимых элементов, порожденное от TObject, содержит потоки, файлы ресурсов, коллекции и списки строк.

Невидимые объекты.

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

Номера ID объектов.

Поле ObjType - это единственная часть записи, которую Вы должны знать. Каждый новый тип, определенный Вами, будет требовать своего собственного уникального номера типа. Turbo Vision резервирует регистрационные номера от 0 до 99 для стандартных объектов. Вы можете использовать регистрационные номера от 100 до 65,535.
Примечание: Вы ответственны за создание и поддержку библиотеки номеров ID для всех новых объектов, которые используются в потоках В/В и должны сделать ID доступными для пользователей Ваших модулей. Как и константы команд, номера, назначаемые Вами могут быть абсолютно произвольными, главное, чтобы они были уникальными.

Нормальные кнопки и по умолчанию.

Когда Вы создаете кнопку, Вы устанавливаете ее флаг bfNormal или bfDefault. Большинство кнопок bfNormal. Кнопка, помеченная как bfDefault, будет кнопкой по умолчанию, т.е. она "нажимается", когда Вы нажимаете клавишу Enter. Turbo Vision не проверяет, используете ли Вы только одну кнопку по умолчанию - за это отвечаете Вы. Если Вы назначите более, чем одну кнопку по умолчанию, результат будет непредсказуемым. Обычно кнопка "OK" в диалоговом окне - это кнопка по умолчанию и пользователь просто нажимает Enter, чтобы закрыть диалоговое окно и использовать сделанные изменения.

Новые понятия.

Turbo Vision - это объединение видимых элементов, событий и невидимых объектов.

Новый взгляд на разработку программ.

Вы, вероятно, использовали библиотеки процедур и функций и ранее, а на первый взгляд Turbo Vision выглядит во многом как обычные библиотеки. Кроме того, библиотеки могут быть разработаны для поддержки меню, окон, мышки и т.д. Но под внешним сходством кроется существенное различие. Во-первых, не забывайте, что Вы сейчас работаете с объектами. В традиционном структурном программировании, когда инструмент, такой как монитор меню не полностью Вас удовлетворяет, Вы модифицируете исходный код инструмента, если он есть. Изменение исходного кода - это шаг, который труден для возврата, если Вы не фиксируете точно, как выглядел оригинальный код. Более того, измененный исходный код (особенно исходный код, написанный кем-либо другим) - это прекрасный путь внести новые ошибки в систему. С Turbo Vision Вы никогда не модифицируете исходный код. Вы "изменяете" Turbo Vision РАСШИРЯЯ его. TApplication остается неизменной внутри APP.TPU. Вы добавляете к нему, порождая новые типы объектов, и изменяете так, как Вам требуется, перекрывая унаследованные методы методами, которые Вы пишите для новых объектов. Кроме того, Turbo Vision - это иерархия, а не разрозненный набор инструментов. Если Вы используете любой из них, Вы должны использовать ВСЕ из них. Здесь дается представление каждого компонента Turbo Vision и как они работают вместе. Эти рекомендации лежат в основании принципов разработки на Turbo Vision: полностью используйте объектно-ориентированную технику и используйте все элементы Turbo Vision в Вашей программе. Это означает играть по "правилам" Turbo Vision и использовать его типы объектов. Мы создали Turbo Vision, чтобы уберечь Вас от большого количества ненужной повторяющейся работы и предоставить Вам оболочку прикладных программ.

Объект диалоговое окно.

Другим важным объектом, используемым в Hello, является диалоговое окно. Поскольку диалоговое окно не выполняет ничего специального, Hello использует экземпляр объекта TDialog. Не требуется порождать специального объекта из TDialog. Сам TDialog не содержит интерактивных элементов. Это ничего более, чем оболочка; Вы предоставляете поля или элементы управления, взаимодействующие с пользователем. THelloApp.GreetingBox строится на основе TDialog, вставляя 4 кнопки, которые являются видимыми элементами Turbo Vision. (Вспомним, что все элементы программы, которые выводят что-либо на экран, должны быть видимыми элементами Turbo Vision!) Это обычная ситуация при использовании диалоговых окон. Обычно Вы просто вставляете элементы управления, которые необходимы в диалоговом окне. Все остальное, что должно быть в диалоговом окне (включая обработчик событий) встроено в TDialog.

Объект TSample Модуль объекта

+---------+ | TObject | +----+----+ +====+====+ | TSample | +====+====+ +------+------+ | TDescendant | +-------------+
Поля
Этот раздел приводит список всех полей объекта. Кроме объявления поля и объяснения его использования приводится назначение "только чтение" и "чтение/запись". Поля "только на чтение" - это поля, которые устанавливаются и поддерживаются методами объектов и которые не должны использоваться в левой части оператора присваивания.
AField AField: SomeType; Только чтение AField - это поле, которое содержит некоторую информацию об этом объекте. Этот текст объясняет как оно функционирует, что это означает и как Вам его использовать. См. так же: Связанные поля, методы, объекты, глобальные функции и т.д.
AnotherField AnotherField: Word; Чтение/Запись Это поле содержит информацию подобную информации для поля AField.
Методы
Этот раздел приводит все методы, которые либо определены в этом объекте, либо перекрывают унаследованные методы. Для виртуальных методов указывается, как часто требуется перекрывать метод: никогда, редко, иногда, часто или всегда.
Init constructor Init(AParameter: SomeType); Init создает новый экземпляр объекта, устанавливая поле AField в АParameter.
Zilch procedure Zilch; virtual; Перекрывается: Иногда Процедура Zilch выполняет некоторые действия. См. так же TSomethingElse.Zilch

Объекты коллекции.

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

Объекты скроллинга.

Объект TScroller это видимый объект для скроллинга, который действует как ворота в другой больший "фоновый" видимый элемент. Скроллинг возникает в ответ на ввод с клавиатуры или действия в связанных объектах TScrollBar. Скроллеры имеют два поля, HScrollId и VScrollId, идентифицирующих управление горизонтальной и вертикальной полосами скроллинга. Поле Delta в TScroller определяет смещение скроллинга по X и Y вместе с полями в связанных полосах скроллинга. Объекты TScrollBar обеспечивают вертикальное или горизонтальное управление. Ключевые поля: Value - позиция индикатора полосы скроллинга, PgStep - смещение скроллинга, требуемое в ответ на нажатие мышки или клавиш PgUp, PgDn; ArrStep - смещение скроллинга, требуемое в ответ на нажатие мышки или клавиш курсора. Скроллер и его полосы скроллинга обычно принадлежат объекту TWindow, что приводит к сложному набору обрабатываемых событий. Например, изменение размера окна должно приводить к соответствующей перерисовке скроллером. Значения полосы скроллинга должны так же изменяться и перерисовываться.

Объекты вообще.

Вспомним, что каждый объект (кроме базового объекта TObject и двух специальных объектов TPoint и TRect) наследует поля и методы родительского объекта. Порожденные Вами объекты будут так же наследовать поля и методы предка. Многие стандартные объекты имеют абстрактные методы, которые должны быть перекрыты в порожденном объекте. Другие методы виртуальные, что означает, что обычно Вам необходимо перекрыть их. Существуют так же методы, которые выполняют полезное действие, если они не были перекрыты.

Оболочка оконной программы.

Turbo Vision - это оболочка оконной программы, управляемой событиями. Здесь нет ни грамма мяса, только сильный гибкий скелет. Вы наращиваете мышцы на скелет, используя расширенные возможности объектно-ориентированного программирования Turbo Pascal. Turbo Vision предоставляет Вам прикладной объект TApplication и Вы создаете порожденный объект от TApplication - назовем его MyApplication, который действует как Ваше приложение. Затем Вы добавляете в MyApplication все, что Вам требуется для необходимой работы. На очень высоком уровне это все, что нужно сделать. Весь блок begin.end Вашей программы выглядит:
begin MyApplication.Init; { начальная установка } MyApplication.Run; { выполнение } MyApplication.Done; { закрытие } end;

Обработка nil указателей на объект.

Вы можете записать nil объект в поток. Однако, когда Вы делаете это, в поток записывается слово со значением 0. При чтении ID = 0, поток возвращает nil указатель, поэтому 0 зарезервирован и не может использоваться как ID номер объекта.

Обработка ошибок потока.

TStream имеет метод Error(Code, Info), который вызывается, когда поток обнаруживает ошибку. Error просто устанавливает поле Status в одну из констант, приведенную в разделе "Константы stXXXX" главы 14. Поле ErrorInfo за исключением ситуации, когда Status равен stGetError или stPutError, неопределено. Если Status - stGetError, поле ErrorInfo содержит номер ID незарегистрированного типа в потоке. Если Status - stPutError, поле ErrorInfo содержит смещение VMT для типа, который Вы пытаетесь поместить в поток. Вы можете перекрыть TStream.Error для создания любой обработки ошибок, включая ошибки времени выполнения.

Обработка событий.

После того, как Вы определили команду и установили элемент управления, который генерирует ее - например, элемент меню или кнопка диалового окна - Вам нужно научить Ваш видимый элемент, как реагировать, когда возникает эта команда. Каждый видимый элемент наследует метод HandleEvent, который уже знает, как реагировать на большую часть ввода пользователя. Если Вы хотите, чтобы видимый элемент делал что-то специфическое для Вашей программы, Вам необходимо перекрыть HandleEvent и научить новый HandleEvent двум вещам - как откликаться на определенные Вами команды и как откликаться на события от мышки и клавиатуры нужным Вам образом. Метод HandleEvent определяет поведение видимого элемента. Два видимых элемента с идентичными методами HandleEvent будут одинаково откликаться на события. Когда Вы порождаете новый тип видимого элемента, Вы обычно хотите, чтобы его поведение более или менее соответствовало его предку с некоторыми изменениями. Наиболее простой способ достичь этого - вызвать HandleEvent предка в методе HandleEvent нового объекта. Общий вид HandleEvent наследника:
procedure NewDescendant.HandleEvent(var Event: TEvent); begin {Код, изменяющий или ограничивающий унаследованное поведение} Parent.HandleEvent(Event); {Код, выполняющий дополнительные функции} end;
где Parent - тип предка. Другими словами, если Вы хотите, чтобы новый объект обрабатывал события не так, как это делал его предок, Вы должны перехватить определенные события до передачи события в метод HandleEvent предка. Если Вы хотите, чтобы Ваш новый объект вел себя также, как его предок, но с дополнительными функциями, Вы должны добавить код после вызова процедуры HandleEvent предка.

Общие события.

Общие события это обычно общие сообщения или пользовательские сообщения. Общие события не направляются как позиционированные или активные события. По определению обшие события не знают своего назначения и посылаются всем видимым подэлементам текущего модального видимого элемента. Текущий модальный видимый элемент получает событие и начинает передавать его подэлементам в Z-порядке. Если любой из этих пдэлементов - группа, он также передает событие своим подэлементам и также в Z-порядке. Процесс продолжается до тех пор пока все видимые элементы принадлежащие (прямо или косвенно) модальному видимому элементу не получат сообщения. Общие сообщения обычно используются для взаимодействия видимых элементов. Например, когда Вы отмечаете полосу скроллинга в просмотре файла, полоса скроллинга должна сказать видимому элементу просмотра, что он должен показать другую часть себя. Это значит что когда видимый элемент выдает общее сообщение "Я изменился!", другие видимые элементы, включая текст, будут получать сообщение и реагировать на него. Дополнительные детали смотри в разделе "Межэлементное взаимодействие". Примечание: Общие сообщения могут быть направлены объекту функцией Message.

Обзор видимых элементов.

Видимый элемент - это любой объект, который может быть нарисован (отображен) в прямоугольной части экрана. Тип видимого объекта должен наследоваться от TView. Сам TView - это абстрактный объект, представляющий пустую область экрана. Имея TView в качестве предка каждый порожденный видимый элемент имеет по крайней мере прямоугольную часть экрана и минимальный виртуальный метод Draw. При программировании в Turbo Vision Вы будете использовать более специализированные потомки от TView, но функциональность TView распространяется на весь Turbo Vision и Вам необходимо понимать его свойства.

Очистить бит.

Очистить бит так же просто, как и установить. Вы просто используете другую операцию. Лучший способ сделать это - использовать комбинацию двух побитовых операций and и not. Например, чтобы очистить бит dmLimitLoX в поле DragMode метки АLabel используйте
ALabel.DragMode := ALabel.DragMode and not dmLimitLoX;
Как и при установке Вы можете очистить несколько бит в одной операции.

Очистка событий.

Когда метод Handle видимого элемента обработал событие, он заканчивает этот процесс вызовом метода ClearEvent. ClearEvent устанавливает поле Event.What равным evNothing и Event.InfoPtr в @Self, что указывает на очищенное событие. Если это событие будет передано другому объекту, то он должен игнорировать "пустое" событие.

Одна из многих.

Давайте добавим набор зависимых кнопок в диалоговое окно, чтобы Вы могли сравнить их с независимыми кнопками. Следующий код устанавливает набор из 3 зависимых кнопок:
+--------------+ | [*] Solid | | [ ] Runny | | [ ] Melted | +--------------+
R.Assign( , , , ); B := New(PRadioButtons, Init(R, NewSItem('~S~olid', NewSItem('~R~unny', NewSItem('~M~elted', nil))) )); Insert(B);
Главное отличие между независимыми и зависимыми кнопками в том, что Вы можете выбрать только одну зависимую кнопку в группе и что первый элемент в списке зависимых кнопок выбран по умолчанию. Поскольку Вам не требуется знать состояние каждой зависимой кнопки (только одна может быть выбрана, так, что Вам требуется знать только какая именно), данные о зависимых кнопках не побитовые. Это означает, что Вы можете использовать более 16 зависимых кнопок, но поскольку данные хранятся в слове, Вы ограничены 65,536 зависимыми кнопками на один кластер. Значение 0 указывает, что выбрана первая зависимая кнопка, 1 - вторая и т.д.

Окна.

Объекты TWindow, с помощью ассоциированных объектов TFrame - это прямоугольники с рамкой, которую Вы можете перемещать, изменять ее размеры и удалять, используя методы, унаследованные от TView. Поле Frame указывает на объект TFrame этого окна. Объект ТWindow так же может изменять размер и закрываться, используя свои методы. TWindow обрабатывает клавиши Tab и Shift-Tab для выбора следующего или предыдущего видимого подэлемента в окне. Обработчик событий TWindow обрабатывает команды закрытия и изменения размера. Пронумерованные окна могут быть выбраны горячими клавишами Alt-n.

Окно списка.

TListBox наследуется от TListViewer. Он владеет TCollection, который должен быть указателями на строки. TListBox поддерживает только одну полосу скроллинга. Пример окна списка - список выбора файлов в интегрированной среде Turbo Pascal или список файлов, используемый TFileDialog в STDDLG.PAS. При получении или установке данных окна списка удобно использовать тип записи TListBoxRec, который хранит указатель на список строк и слово, указывающее на текущий выбранный элемент списка.

Опять итераторы.

Метод ForEach проходит по всей коллекции и передает каждый элемент в предоставленную Вами процедуру. Продолжая предыдущий пример, процедура PrintWord получает указатель на отображаемую строку. Заметьте, что PrintWord вложенная (или локальная) процедура. Print использует метод ForEach для передачи каждого элемента коллекции в процедуру PrintWord.
procedure Print(C: PCollection);
procedure PrintWord(P : PString); far; begin Writeln(P^); end;
begin { Print } Writeln; Writeln; C^.ForEach(@PrintWord); end;
Вызов PrintWord выглядит привычно. Это просто процедура, которая берет указатель на строку и передает его значение в Writeln. Заметим директиву far в объявлении PrintWord. PrintWord не может быть методом - она должна быть процедурой. (Процедура CallDraw в TVGUID20.PAS показывает как вызвать метод в вызове итератора). Она так же должна быть вложенной процедурой. Вы можете использовать более одной процедуры, такой как PrintWord, но каждая должна быть вложена в Print и должна быть дальней процедурой.

Определение команд.

Turbo Vision имеет ряд предопределенных команд и Вы можете определить еще больше своих. Когда Вы создаете новый видимый элемент, Вы также создаете команду, которая используется для вызова этого видимого элемента. Команды могут быть названы произвольно, но по соглашениям Turbo Vision идентификатор команды должен начинаться с "cm". Механизм создания команд прост - Вы только создаете константу:
const cmConfuseTheCat = 100;
Turbo Vision резервирует команды от 0 до 99 и от 256 до 999 для собственного использования. Ваша программа может использовать под команды номера от 100 до 255 и от 1000 до 65535. Причина того что Вы имеете два диапазона для команд только в том что команды от 0 до 255 могут быть запрещены. Turbo Vision резервирует некоторые команды, которые могут быть запрещены и некоторые команды которые не могут быть запрещены для своих стандартных команд и внутренней работы. Вы имеете полный контроль над оставшимися командами.
Таблица 5.1. Диапазоны команд Turbo Vision.
------------------------------------------------ Диапазон Зарезервировано Может быть запрещено ------------------------------------------------ 099 Да Да 100255 Нет Да 256999 Да Нет 100065535 Нет Нет ------------------------------------------------

Основные потребители.

Функция Valid так же может обрабатывать "основных потребителей", т.е. видимые элементы, которые распределяют память больше, чем размер пула надежности, как например при чтении всего файла в память. Основные потребители должны проверять LowMemory сами вместо того, чтобы ожидать когда они закончат все создание, а после этого позволят ValidView сделать это за них. Если основной потребитель доходит до нехватки памяти в процессе своего создания, он устанавливает свой флаг, который указывает, что встретилась ошибка (как например флаг ErrorEncountered в предыдущем примере) и больше не пытается распределить память. Этот флаг будет проверяться в Valid и видимый элемент будет вызывать Application^.OutOfMemory и возвращать False из вызова Valid. Очевидно, что делать предположение о работе Ваших констракторов - это не лучший вариант, но это единственный способ управлять создание видимых элементов, которые превышают размер пула надежности. Программа FILEVIEW.PAS демонстрирует использование этой техники для реализации надежного просмотра файла.

Открытие окон.

Используемые объекты: TRect, TView, TWindow, TGroup, TScroller, TScrollBar. Если Вы программист, Вы можете сразу перейти на этот раздел, как только Вы откроете книгу. Кроме того, что может быть более важно для написания оконных программ, чем создание окон? Это было бы так, если бы Turbo Vision была набором традиционных библиотечных программ. В этом случае переход на этот раздел и попытка начать работать была бы хорошей идеей. Но Turbo Vision - не традиционная библиотека. Если Вы читали предыдущие разделы, Вы уже знаете об этом. Для того, чтобы программировать в Turbo Vision необходимо выполнить некоторые действия до того, как создавать окна. Вам необходимо понимать, что такое окно Turbo Vision (а это объект!) и чем оно отличается от окон, которые Вы использовали раньше. Когда Вы сделаете это, Вы продвинитесь вперед гораздо дальше, чем Вы можете вообразить. Поэтому, если Вы открыли книгу в этом месте, Вам необходимо вернуться к предыдущим разделам и прочитать их.

Откуда приходят события.

Как сказано в главе 1, главный цикл обработки в TApplication, метод Run вызывает TGroup.Execute, которая основана на цикле:
var E: TEvent; E.What := evNothing; { указывает что нет событий } repeat if E.What <> evNothing then EventError(E); GetEvent(E); { упаковывает запись события } HandleEvent(E); { направляет событие в нужное место } until EndState <> Continue;
По существу GetEvent смотрит вокруг и проверяет, не случилось ли что либо, что должно быть событием. Если случилось, GetEvent создает соответствующую запись события. Затем HandleEvent направляет событие в соответствующие видимые элементы. Если событие не обработано (и не очищено) за время пока оно не вернется в этот цикл, то вызывается EventError, чтобы указать на ненужное событие. По умолчанию EventError ничего не делает.

Отладка программ на Turbo Vision.

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

Отсортированные коллекции.

TSortedCollection реализует коллекцию, отсортированную по ключу. Сортировка определена через виртуальный абстрактный метод Compare. Следовательно Ваш порожденный тип может задавать требуемую упорядоченность для коллекции объектов любого типа. Метод Insert добавляет элементы, поддерживая это упорядочение и ключи могут быть быстро найдены методом двоичного поиска Search.

Иногда Вам необходимо иметь Ваши данные в определенном порядке. Turbo Vision обеспечивает специальный тип коллекции, который позволяет Вам упорядочить Ваши данные любым способом: TSortedCollection. TSortedCollection порожден от TCollection и автоматически сортирует получаемые объекты. Он так же автоматически проверяет коллекцию, когда добавляется новый элемент и отвергает дублированные элементы. TSortedCollection - это абстрактный тип. Чтобы использовать его, Вы должны вначале решить, какой тип данных Вы будете помещать в коллекцию и определить 2 метода, соответствующие способу сортировки. Чтобы сделать это, Вам нужно породить новый тип коллекции от TSortedCollection. В нашем случае назовем его TClientCollection. Ваш TClientCollection уже знает как делать всю работу над коллекцией. Он может вставить новые записи клиентов и удалить существующие, поскольку наследует все основы поведения от TCollection. Вам необходимо только научить TClientCollection, какое поле использовать как ключ сортировки и как сравнивать двух клиентов и определять, какой из них находится перед другим в коллекции. Вы делаете это, перекрывая методы KeyOf и Compare и реализуя их как показано здесь:
PClientCollection = ^TClientCollection; TClientCollection = object(TSortedCollection) function KeyOf(Item: Pointer): Pointer; virtual; function Compare(Key1, Key2: Pointer): Integer; virtual; end;
function TClientCollection.KeyOf(Item: Pointer): Pointer; begin KeyOf := PClient(Item)^.Name; end;
function TClientCollection.Compare(Key1, Key2: Pointer): Integer; begin {необходимо использовать приведение типа для ключей, поскольку они - нетипированные указатели } if PString(Key1)^ = PString(Key2)^ then Compare := 0 else if PString(Key1)^ < PString(Key2)^ then Compare := -1 else Compare := 1; end;
KeyOf определяет, какое поля или поля должны использоваться как ключ сортировки. В нашем случае - это поле Name клиента. Compare берет 2 ключа сортировки и определяет какой из них должен стоять первым. Compare возвращает -1, 0 или 1 взависимости от того, является ли Key1 меньше, равным или больше Key2. Этот пример использует алфавитную сортировку строк ключей. Заметим, что поскольку ключи, возвращаемые KeyOf и передаваемые Compare - нетипированные указатели, Вам необходимо выполнить приведение типа в PString до ссылки на них. Это все, что Вы должны определить! Сейчас, если Вы переопределите ClientList как PClientCollection вместо PCollection (изменив объявление var и вызов New), Вы распечатаете Ваших клиентов в алфавитном порядке.
{ TVGUID18.PAS } var ClientList: PClientCollection; . begin ClientList := New(PClientCollection, Init(50, 10)); . end;
Заметьте как просто сделать распечатку списка клиентов, отсортированного по номерам, а не по имени. Вам необходимо просто изменить метод KeyOf на возврат поля ACount вместо поля Name.

Ответ: потоки.

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

Палитры цветов.

Когда видимый элемент в Turbo Vision рисует себя, он запрашивает прорисовку не определенным цветом, а цветом, заданным позицией в его палитре (палитры для всех стандартных видимых элементов описаны в главе 13). Например, палитра TScroller имеет вид:
CScroller = #6#7;
Палитра цветов в действительности хранится в строке, что позволяет определять ее в качестве гибких массивов с переменной длиной. Так, CScroller - это двухсимвольная строка, содержащая 2 элемента палитры. Палитра TScroller определена:
{ Палитра } { 1 = Нормальный } { 2 = Подсвеченный }
Но удобнее рассмотреть ее в виде:
Рис. 4.18. Палитра по умолчанию для TScroller.
1 2 +---+---+ CScroller | 6 | 7 | +---+---+ | | | +--------- Подсвеченный текст +------------- Нормальный текст
Это означает, что известно как отображать по крайней мере 2 типа текста объекта скроллер: нормальный и подсвеченный. Цвет по умолчанию определяется элементами палитры. Когда отображается нормальный текст, метод Draw должен вызвать GetColor(1) означающий, что он хочет выбрать цвет, указанный первым элементом палитры. Чтобы показать подсвеченный текст, будет вызываться GetColor(2). (GetColor - это метод TView). Если Вы хотите отображать цветами по умолчанию, это все, что Вам необходимо знать. Палитра устанавливается так, что любая комбинация объектов должна создавать хорошие цвета.

Панель экрана, полоса меню и строка статуса.

Используемые объекты: TView, TMenuView, TMenuBar, TMenuBox, TStatusLine, TGroup, TDeskTop. Панель экрана, полоса меню и строка статуса в TFirst создаются методами InitDeskTop, InitMenuBar и InitStatusLine из TApplication. Эти 3 метода вызываются в TApplication.Init и Вам никогда не нужно вызывать их напрямую. Вместо этого метод Init Вашей программы будет вызывать TApplication.Init в первой строке. Например
procedure TMyApp.Init; begin TApplication.Init; { код инициализации для Вашей программы } end;
Заметим, что Вам необходимо добавить некоторые модули Turbo Vision в оператор uses Вашей программы. Для того, чтобы использовать меню, строку статуса и определения стандартных клавиш, Вам необходимо кроме App использовать Objects, Menus и Drivers. (Объекты и их модули описаны в главе 12.) Если Ваша программа не требует какой-либо специальной инициализации, Вы просто используете унаследованный метод Init. Поскольку Init и методы InitDeskTop, InitMenuBar и InitStatusLine виртуальные, вызов унаследованного Init вызывает соответствующие методы InitStatusLine и InitMenuBar. Вы увидите это в TVGUID02.PAS. InitDeskTop, InitMenuBar и InitStatusLine устанавливают зхначения глобальных переменных DeskTop, MenuBar и StatusLine соответственно. Давайте посмотрим каждую из них.

Панель экрана.

Панель экрана - это исключительно важный объект, но он требует от Вас очень небольших действий. Вы не должны перекрывать унаследованный метод инициализации. Пусть TApplication.InitDeskTop обрабатывает его. DeskTop принадлежит MyApp и когда MyApp устанавливает новый видимый элемент в ответ на ввод пользователя, она должна подключить новый элемент пользователя к DeskTop. Панель экрана знает как управлять видимыми элемента.

TDeskTop - это нормальный фоновый видимый элемент, обеспечивающий привычную панель экрана пользователям, обычно окруженную полосой меню и строкой статуса. Обычно TApplication владелец группы, содержащей объекты TDeskTop, TMenuBar и TStatusLine. Другие видимые элементы, такие как окна и диалоговые окна, создаются, отображаются и манипулируются на панели экрана в ответ на действия пользователя (события от мышки и клавиатуры). Большая часть работы программы происходит внутри панели экрана.

Передача событий.

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

Перекрытие цветов по умолчанию.

Очевидный способ изменить цвета - это изменить палитру. Если Вам не нравится цвет нормального текста скроллера, Вы можете захотеть изменить элемент 1 (нормальный текст) в палитре скроллера, например с 6 на 5. Нормальный текст скроллера отображается в элемент окна для элемента управления полосы скроллера (по умолчанию синий-на-бирюзовом). Запомните: 5 - это не цвет! Все, что Вы сделали - это сказали скроллеру, что его нормальный текст должен выглядеть так же, как полосы скроллинга вокруг него! Что делать, если Вы не хотите желтый-на-синем? Измените элемент палитры для нормального текста окна в TApplication. Поскольку это последняя не nil палитра, элементы в палитре программы определяют цвета, которые будут появляться во всех видимых элементах окна, т.е. цвета не являются абсолютными, а определяются палитрами владельца. Это имеет смысл: вероятно Вы хотите, чтобы Ваши окна выглядели одинаково. Вероятно Вы не захотите указывать каждому отдельному окну какого цвета оно должно быть. Если Вы захотите изменить его позже (или разрешить пользователю настраивать цвета), Вам придется изменить элементы для каждого окна. Так же скроллер или другой интерьер не должен беспокоиться о его цветах, если он вставляется в какое-то окно, отличное от того, в какое Вы хотели вставить его первоначально. Например, если Вы поместили скроллер в диалоговое окно вместо окна, он не будет (по умолчанию) того же цвета, а вместо этого будет цвета нормального текста в диалоговом окне. Чтобы изменить палитру видимого элемента, перекройте метод GetPalette. Чтобы создать новый тип объекта скроллера, который рисует себя цветом рамки окна вместо цвета нормального текста, объявление и реализация объекта будут включать:
type TMyScroller = object(TScroller) function GetPalette: PPalette; virtual; end;
function TMyScroller.GetPalette: PPalette; const CMyScroller = #1#7; PMyScroller: string[Length(CMyScroller)] = CMyScroller; begin GetPalette := @PMyScroller; end;
Заметим, что константа палитры - это строковая константа, поскольку Turbo Vision использует тип String для представления палитры. Это позволяет более просто манипулировать палитрой, поскольку все строковые функции могут использоваться с палитрами.
Примечание: Типы TPalette и String полностью взаимозаменяемы.

Перекрытие GetEvent.

GetEvent текущего модального видимого элемента вызывает GetEvent владельца и так далее проходя весь путь по дереву видимых элементов до TApplication.GetEvent, который ищет следующее реальное событие. Поскольку Turbo Vision всегда использует TApplication.GetEvent для поиска событий, Вы можете модифицировать события всей Вашей программы, перекрывая только один метод. Например, для реализации клавиатурных макро Вы можете просматривать события, возвращаемые GetEvent, перехватывать определенные нажатия клавиш и развертывать их в макро. С точки зрения остальной программы поток событий будет приходить прямо от пользователя.
procedure TMyApp.GetEvent(var Event: TEvent); begin TApplication.GetEvent(Event); end;

Переменная Application App

================================================================= Объявление Application: PApplicaton = nil;
Функция Переменная Application устанавливается в @Self в начале TProgram.Init (вызывается в TApplication.Init) и очищается в nil в конце TProgram.Done (вызывается в TApplication.Done). Поэтому, во время выполнения программы на Turbo Vision, Application указывает на объект-программу.
См. также TProgram.Init

Переменная AppPalette App

================================================================= Объявление AppPalette: Integer = apColor;
Функция Выбирает одну из 3 доступных в программе палитр (apColor, apBlackWhite, apMonochrome). AppPalette инициализируется TProgram.InitScreen в зависимости от текущего режима экрана и используется TProgram.GetPalette для возврата палитры. Вы можете перекрыть TProgram.InitScreen, чтобы изменить выбор палитры по умолчанию.
См. также TProgram.InitScreen, константы apXXXX

Переменная ButtonCount Drivers

================================================================= Объявление ButtonCount: Byte = 0;
Функция ButtonCount хранит число кнопок мышки или 0, если мышка не инсталлирована. Вы можете использовать эту переменную для определения доступна ли поддержка мышки. Значение устанавливается в иницилизационном коде Drivers и не может быть изменено.

Переменная CheckSnow Drivers

================================================================= Объявление CheckSnow: Boolean;
Функция CheckSnow выполняет функцию одноименного флага стандартного модуля Turbo Pascal - Crt. Проверка снега, замедляющая вывод на экран, требуется только для некоторых старых адаптеров CGA.
См. также InitVideo

Переменная CtrlBreakHit Drivers

================================================================= Объявление CtrlBreakHit: Boolean = False;
Функция Драйвер обработки прерываний от клавиатуры Turbo Vision всегда устанавливает ее в True, когда нажата Ctrl-Break. Это позволяет программам на Turbo Vision перехватывать и реагировать на Ctrl-Break. Флаг может быть очищен в любое время установкой его в False.
См. также SaveCtrlBreak

Переменная CursorLines Drivers

================================================================= Объявление CursorLines: Word;
Функция Уставливает начальную и конечную строки курсора с помощью InitVideo. Формат предполагает функцию 1 прерывания BIOS $10 для установки типа курсора.
См. также InitVideo, TView.ShowCursor, TView.HideCursor, TView.BlockCursor, Tview.NormalCursor

Переменная DeskTop App

================================================================= Объявление DeskTop: PDeskTop = nil;
Функция Сохраняет указатель на TDeskTop программы. Переменная DeskTop инициализируется TProgram.InitDeskTop, которая вызывается TProgram.Init. Окна и диалоговые окна обычно вставляются (TGroup.Insert) или выполняются (TGroup.ExecView) на DeskTop.

Переменная DoubleDelay Drivers

================================================================= Объявление DoubleDelay: Word = 8;
Функция Определяет временной интевал (в 1/18.2 секундах) между нажатиями кнопки мышки для порядка различия двойного нажатия и двух отдельных нажатий. Используется GetMouseEvent для генерации события Double, если нажатия произошли в этом временном интервале.
См. также TEvent.Double, GetMouseEvent

Переменная EmsCurHandle Objects

================================================================= Объявление EmsCurhandle: Word = $FFFF;
Функция Содержит текущий обработчик EMS, отображенный TEmsStream в нулевую физическую страницу EMS. TEmsStream избегает дорогих вызовов переотображения EMS подкачкой состояния EMS. Если Ваша программа использует EMS для других целей, установите EmsCurHandle и EmsCurPage в $FFFF перед использованием TEmsStream - это будет вынуждать TEmsStream восстанавливать свое отображение.
См. также TEmsStream.Handle

Переменная EmsCurPage Objects

================================================================= Объявление EmsCurpage: Word = $FFFF;
Функция Содержит текущий номер логической страницы EMS, отображенной TEmsStream в нулевую физическую страницу EMS. TEmsStream избегает дорогих вызовов переотображения EMS подкачкой состояния EMS. Если Ваша программа использует EMS для других целей, установите EmsCurHandle и EmsCurPage в $FFFF перед использованием TEmsStream - это будет вынуждать TEmsStream восстанавливать свое отображение.
См. также TEmsStream.Page

Переменная FocusedEvents Views

================================================================= Оъявление FocusedEvents: Word = evKeyboard + evCommand;
Функция Определяет классы событий как сфокусированные события. Переменные FocusedEvents и PositionalEvents используются TGroup.HandleEvent для определения, как соотносятся события к подэлементам группы. Если класс события не содержится в FocusedEvents или PositionalEvents, то оно интерпретируется как общее событие.
См. также Переменные PositionalEvents, TGroup.HandleEvent, TEvent, константы evXXXX.

Переменная HiResScreen Drivers

================================================================= Объявление HiResScreen: Boolean;
Функция Устанавливается в True с помощью InitVideo, если экран поддерживает режим 43/50 строк (EGA/VGA); в противном случае устанавливается в False.
См. также InitVideo

Переменная HistoryBlock HistList

================================================================= Объявление HistoryBlock: Pointer = nil;
Функция Указывает на буфер, вызывающий блок истории и используемый для хранения строк истории. Размер блока определяется посредством HistorySize. Указатель устанавливается в nil до тех пор пока не будет установлен с помощью InitHistory. Его значение нельзя изменить.
См. также процедуру InitHistory, переменную HistorySize.

Переменная HistorySize HistList

================================================================= Объявление HistorySize: Word = 1024;
Функция Задает размер блока истории, используемый администратором списка истории для хранения значений, введенных в строках ввода. Размер фиксируется посредством InitHistory при запуске программы. По умолчанию размер блока равен 1К, но может быть изменен перед вызовом InitHistory. Значение нельзя изменять после вызова InitHistory.
См. также процедуру InitHistory, переменную HistoryBlock.

Переменная HistoryUsed HistList

================================================================= Объявление HistoryUsed: Word = 0;
Функция Используется внутри администратором списка истории для указания на смещение внутри блока истории. Это значение нельзя изменить.

Переменная MaxBufMem Memory

================================================================= Объявление MaxBufMem: Word = 65536 div 16;
Функция Указывает максимальный объем памяти в 16-байтовых параграфах, которая может быть распределена для кэш-буферов.
См. также GetBufMem, FreeBufMem.

Переменная MaxCollectionSize Objects

================================================================= Объявление MaxCollectionSize = 65520 div SizeOf(Pointer);
Функция Определяет максимальное число элементов, которые может содержать коллекция, по существу это число указателей, которое помещается в сегмент памяти в 64К.

Переменная MenuBar App

================================================================= Объявление MenuBar: PMenuView = nil;
Функция Сохраняет указатель на полосу меню программы (наследник TMenuView). Переменная MenuBar инициализируется с помощью TProgram.InitMenuBar, которая вызывается через TProgram.Init. Значение nil указывает, что программа не имеет полосы меню.

Переменная MinWinSize Views

================================================================= Объявление MInWinSize: TPoint = (X: 16; Y: 6);
Функция Определяет минимальный размер TWindow или его потомков. Значение возвращается в параметре Min при вызове TWindow.SizeLimits. Любые изменения в MinWinSize будут воздействовать на все окна, если только метод SizeLimits окна не перекрыт.
См. также TWindow.SizeLimits

Переменная MouseButtons Drivers

================================================================= Объявление MouseButtons: Byte;
Функция Содержит текущее состояние кнопок мышки. MouseButtons корректируется обработчиком прерываний мышки как только кнопка нажата или отпущена. Константы mbXXXX могут быть использованы для проверки MouseButtons.
См. также константы mbXXX.

Переменная MouseEvents Drivers

================================================================= Объявление MouseEvents: Boolean = False;
Функция Устанавливается в True, если мышка инсталлирована и обнаружена InitEvents; в противном случае, устанавливается в False. Если False, то все процедуры событий от мышки обходятся.
См. также GetMouseEvent.

Переменная MouseIntFlag Drivers

================================================================= Объявление MouseIntFlag: Byte;
Функция Используется внутри драйвера мышки Turbo Vision и видимыми элементами. Устанавливается как только возникает событие от мышки.

Переменная MouseWhere Drivers

================================================================= Объявление MouseWhere: TPoint;
Функция Содержит текущую позицию мышки в глобальных координатах. MouseWhere корректируется обработчиком прерываний мышки как только мышка сдвигается. Используйте процедуру MakeLocal для преобразования к локальным (относительно окна) координатам. MouseWhere передается в обработчики событий вместе с другими данными мышки.
См. также GetMouseEvent, методы GetEvent, MakeLocal

Переменная PositionalEvents Views

================================================================= Объявление PositionalEvents:Word = evMouse;
Функция Определяет классы событий как позиционированные события. Переменные FocusedEvents и PositionalEvents используются TGroup.HandleEvent, чтобы установить соответствие события подэлементам группы. Если класс события не принадлежит FocusedEvents или PositionalEvents, то оно интерпретируется как общее событие.
См. также TGroup.HandleEvent, тип TEvent, константы события evXXXX, переменная Focused Events.

Переменная RepeatDelay Drivers

================================================================= Объявление RepeatDelay = 8;
Функция Определяет число квантов времени (1/18.2 часть секунды), которое должно быть известно перед генерацией событий evMouseAuto. Временной интервал между событиями evMouseAuto всегда составляет один квант.
См. также DoubleDelay, GetMouseEvent, константы evXXXX.

Переменная SaveCtrlBreak Drivers

================================================================= Объявление SaveCtrlBreak: Boolean = False;
Функция Процедура InitSysError сохраняет состояние Ctrl-Break DOS, проверяя эту переменную перед запрещением проверки Ctrl-Break DOS. DoneSysError восстанавливает Ctrl-Break DOS, проверяя значение, сохраненное в этой переменной.
См. также InitSysError, DoneSysError

Переменная ScreenBuffer Drivers

================================================================= Объявление ScreenBuffer: Pointer;
Функция Указатель на буфер экрана.
См. также InitVideo.

Переменная ScreenHeight Drivers

================================================================= Объявление ScreenHeight: Byte;
Функция Устанавливается InitVideo и SetVideoMode в высоту экрана в строках для текущего экрана.
См. также InitVideo, SetVideoMode, ScreenWidth.

Переменная ScreenMode Drivers

================================================================= Объявление ScreenMode: Word;
Функция Хранит текущий видеорежим. Изначально устанавливается инициализационным кодом модуля Drivers, ScreenMode может быть изменена использованием SetVideoMode. Значения ScreenMode обычно устанавливаются использованием мнемоник режима экрана smXXXX.
См. также InitVideo, SetVideoMode, smXXXX.

Переменная ScreenWidth Drivers

================================================================= Объявление ScreenWidth: Byte;
Функция Устанавливается InitVideo в ширину экрана (число символов с строке).
См. также InitVideo.

Переменная ShadowAttr Views

================================================================= Объявление ShadowAttr: Byte = $80;
Функция Эта переменная управляет цветом тени, доступной видимым элементам с установленным битом sfShadow. Тень это обычно разреженная серая область, отображаемая прямо от краев видимого элемента с иллюзией 3-D.
См. также ShadowSize.

Переменная ShadowSize Views

================================================================= Объявление ShadowSize: TPoint = (X: 2; Y: 1);
Функция Это значение управляет размером тени, кторая доступна с установленным битом sfShadow. Тень это обычно разреженная серая область, отображаемая прямо от краев видимого элемента с иллюзией 3-D. По умолчанию, размер тени - 2 по оси X и 1 по Y. TProgram.InitScreen инициализирует ShadowSize: если режим экрана равен smMono, ShadowSize устанавливается в (0, 0). Иначе ShadowSize устанавливается в (2, 1), если только не установлен smFont8x8 (43- или 50-строчный режим), в этом случае устанавливается в (1, 1).
См. также TProgram.InitScreen, ShadowAttr.

Переменная ShowMarkers Drivers

================================================================= Объявление ShowMarkers: Boolean;
Функция Используется для указания будут ли индикаторы размещаться вокруг активных элементов управления. TProgram.InitScreen устанавливает ShowMarkers в True, если монохромный видеорежим, иначе в False. Однако значение может быть установлено, при необходимости, в цветной или черно-белый режим.
См. также TProgram.InitScreen, переменная SpecialChars.

Переменная SpecialChars Views

================================================================= Объявление SpecialChars: array[05] of Char = (#175, #174, #26, #27, ' ', ' ');
Функция Определяет символы индикатора используемые для подсветки активного видимого элемента в монохромном видеорежиме. Эти символы отображаются, если переменная ShowMarkers - True.
См. также переменную ShowMarkers.

Переменная StartupMode Drivers

================================================================= Объявление StartupMode: Word;
Функция Программа InitVideo сохраняет текущий режим экрана в этой переменной до переключения в режим экрана заданный в ScreenMode. DoneVideo восстанавливает режим экрана в значение запомненное в StartupMode.
См. также InitVideo, DoneVideo, ScreenMode.

Переменная StatusLine App

================================================================= Объявление StatusLine: PStatusLine = nil;
Функция Сохраняет указатель на строку статуса программы. Переменная StatusLine инициализируется в TProgram.InitStatusLine, вызываемой из TProgram.Init. Значение nil указывает, что в программе нет строки статуса.
См. также InitStatusLine.

Переменная StreamError Objects

================================================================= Объявление StreamError: Pointer = nil;
Функция Если не nil, StreamError указывает на процедуру, которая вызывается методом Error потока при возникновении ошибки. Процедура должна быть дальней и использовать var параметр типа TStream, т.е. иметь объявление:
procedure MyStreamErrorProc(var S: TStream); far;
StreamError позволяет Вам глобально перекрыть всю обработку ошибок потока. Чтобы изменит обработку ошибок для определенного типа потока, Вы должны перекрыть метод Error этого потока.

Переменная SysColorAttr Drivers

================================================================= Объявление SysColorAttr: Word = $4E4F;
Функция Цвет по умолчанию используется для вывода сообщений об ошибках обработчиком системных ошибок. На монохромных системах SysMonoAttr используется вместо SysColorAttr. Сообщения об ошибках с опцией отменить/ восстановить отображаются в строке статуса. Предыдущая строка статуса сохраняется и восстанавливается, когда условия разрешены.
См. также SystemError, SysMonoAttr.

Переменная SysErrActive Drivers

================================================================= Объявление SysErrActive: Boolean = False;
Функция Указывает, активен ли обработчик системных ошибок в данный момент. Устанавливается в True через InitSysError.

Переменная SysErrorFunc Drivers

=================================================================
Объявление SysErrorFunc: TSysErrorFunc = SystemError;
Функция SysErrorFunc - это функция системной ошибки типа TSysErrorFunc. Функция системной ошибки вызывается при возникновении критической ошибки DOS или когда требуется смена диска на компьютере с одним гибким диском. ErrorCode - это значение от 0 до 15, как определено в таблице 14.30, а Drive - это номер устройства (0=А, 1=В и т.д.) для дисковых ошибок. По умолчанию функция системной ошибки - это SystemError. Вы можете установить свою функцию системной ошибки, назначая ее в SysErrorFunc. Функции системных ошибок не могут перекрываться.
Таблица 14.30. Коды функции системной ошибки.
----------------------------------------------------------- Код ошибки Значение ----------------------------------------------------------- 012 Коды критических ошибок DOS 13 Плохой образ таблицы распределения файлов 14 Ошибка доступа к устройству 15 Указание смены диска -----------------------------------------------------------
Возвращаемые значения функции:
Таблица 14.31. Значения, возвращаемые функцией системной ошибки.
----------------------------------------------------------- Возвращаемое значение Назначение ----------------------------------------------------------- 0 Пользователь запросил повтор 1 Пользователь запросил отмену -----------------------------------------------------------
См. также функцию SystemError, тип TSysErrorFunc, процедуру InitSysError.

Переменная SysMonoAttr Drivers

================================================================= Объявление SysMonoAttr: Word = $7070;
Функция Атрибут по умолчанию используется для вывода сообщений об ошибках обработчиком системных ошибок. На цветных системах SysColorAttr используется вместо SysMonoAttr. Сообщения об ошибках с опцией отменить/ восстановить отображаются в строке статуса. Предыдущая строка статуса сохраняется и восстанавливается, когда условия разрешены.
См. также SystemError, SysColorAttr.

Переменные.

------------------------------------------------------------- Переменная Тип Начальное Назначение значение ------------------------------------------------------------- EmsCurHandle Word $FFFF Текущий обработчик EMS EmsCurPage Word $FFFF Текущая страница EMS -------------------------------------------------------------

Переосмысление проекта.

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

Пересылка текста в буфер.

Turbo Vision предоставляет 4 глобальных процедуры для пересылки текста в TDrawBuffer: MoveStr, которую Вы только что видели, и MoveChar, MoveCStr и MoveBuf, которые пересылают символы, управляющие строки (строки с "~" для элементов меню и статуса) и другие буфера в буфер, соответственно. Эти процедуры объяснены детально в главе 14.

Побитовые операции.

Turbo Pascal предоставляет ряд полезных операций для манипуляции битами. Вместо детального объяснения каждой из операций, этот раздел просто говорит что Вы должны сделать, чтобы выполнить работу.

Подэлементы и дерево видимых элементов.

Как сказано раньше, видимый элемент TApplication владеет и управляет тремя подэлементами, созданными им. Вы можете представить эту взаимосвязь как формирование дерева видимых элементов. Application - это ствол, а MenuBar, DeskTop и StatusLine формируют ветви, как показано на рис. 4.8.
Рис. 4.8. Основное дерево видимых элементов Turbo Vision.
+-------------+ | Application | +--+--+---+---+ +--------+ | +-------+ +---+-----++----+----++-----+------+ | MenuBar DeskTop StatusLine | +---------++---------++------------+
Запомните, что взаимосвязи, показанные на рис. 4.8. - это не иерархия объектов, а модель структуры данных. Связи отражают принадлежность, а не наследование. В типичной программе, когда пользователь отмечает мышкой или использует клавиатуру, он создает новые видимые элементы. Эти видимые элементы будут появляться на панели экрана, формируя новые ветви дерева. Важно понимать взаимосвязи между владельцами и подэлементами и как появление и поведение видимого элемента зависит от того, кто владеет видимым элементом. Рассмотрим пример. Пусть пользователь отмечает элемент меню, который вызывает окно просмотра файла. Окно просмотра файла будет видимым элементом. Turbo Vision создает окно и присоединяет его к панели экрана. Окно будет владеть рядом подэлементов: TFrame - рамка окна, TScroller - содержит массив текста и TScrollBar. Когда окно вызывается, оно создает, владеет и управляет подэлементами. К Вашей растущей программе подключены новые видимые элементы, как показано на рис. 4.9.
Рис. 4.9. Панель экрана с просмотром файлов.
+------------------------------------------------+ | Строка меню | +------------------------------------------------| |************************************************| |**+=[ю]=== File Viewer Window ==1=[]=+ ********| |**| ********| |**| # ********| |**| File text # ********| |**| # ********| |**| ю ********| |**| # ********| |**| ********| |**+==========#ю###############======+ ********| |************************************************| +------------------------------------------------| | Строка статусa | +------------------------------------------------+

Дерево видимых элементов становится более сложным, как показано на рис. 4.10.

Рис. 4.10. Дерево видимых элементов с просмотром файла.

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

Теперь предположим, что пользователь отметил тот же элемент меню и создал другое окно просмотра файлов. Turbo Vision создает второе окно и присоединяет его к панели экрана, как показано на рис. 4.11.

Рис. 4.11. Панель экрана с просмотром файла.

+----------------------------------------------------+ | Строка меню | +----------------------------------------------------| |****************************************************| |**+======= File Viewer Window ==1=====+*************| |**| *************| |**| +=[ю]=== File Viewer Window ==2=[]=+***| |**| File te| ***| |**| | #***| |**| | File text #***| |**| | #***| |**| | ю***| |**+=========| #***| |************| ***| |************+==========#ю###############======+***| |****************************************************| +----------------------------------------------------| | Строка статусa | +----------------------------------------------------+

Дерево видимых элементов становится еще более сложным, как показано на рис. 4.12.

Рис. 4.12. Дерево видимых элементов с просмотром файла.

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


Как Вы увидите в главе 5, управление программы проходит по дереву видимых элементов. В предыдущем примере предположим, что Вы отметили полосу скроллинга в окне просмотра файла. Как сделать, чтобы это действие обрабатывалось в нужном месте? Программа Application видит отметку мышкой, обнаруживает, что она находится в области, управляемой панелью экрана и передает ее в объект "панель экрана". Панель экрана видит, что отметка внутри области, управляемой просмотром файла и передает ее в этот видимый элемент. Просмотр файла видит, что отметка была в полосе скроллинга и позволяет видимому элементу "полоса скроллинга" обработать отметку, генерируя соответствующий отклик. Действительный механизм этой обработки не важен в данный момент. Сейчас важно понять как связаны видимые элементы. Вне зависимости от сложности структуры, все видимые элементы связаны с объектом Вашей программы. (Обработка событий объяснена в главе 5). Если пользователь отметил закрывающую кнопку во втором просмотре файла, или элемент меню Close Window, второй просмотр файла закрывается. Turbo Vision отключает его в дереве видимых элементов и уничтожает. Окно будет освобождать все подэлементы, а затем уничтожает себя. Вероятно пользователь будет удалять видимые элементы, пока не достигнет начальной позиции и укажет, что он закочил работу нажав Alt-X или выбрав Exit из меню. TApplication удаляет свои подэлементы, а затем удаляет себя.

Поиск элемента.

Отсортированные коллекции (и следовательно коллекции строк) имеют метод Search, который возвращает индекс элемента с заданным ключем. Как Вам найти элемент в неотсортированной коллекции? Или как найти элемент, когда критерий поиска не включает ключ? Конечно необходимо использовать FirstThat и LastThat. Вы просто определяете булевскую функцию с нужным критерием поиска и вызываете FirstThat.

Появление видимых элементов.

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

Поле Phase.

Каждая группа имеет поле Phase, которое принимает три значения: phFocused, phPreProcess и phPostProcess. Проверяя флаг Phase владельца, видимый элемент может сказать, будет ли обрабатываться событие активное событие до, во время или после передачи. Это иногда необходимо, т.к. некоторые видимые элементы ожидают различные события или реагируют на одинаковые события по разному, в зависимости от фазы. Рассмотрим случай простого диалогового окна, которое содержит строку ввода и клавишу с меткой "All right" с коротким набором "A". С управляющими элементами обычного диалогового окна Вы в действительности не имеете дело с фазой. Большинство элементов управления имеют ofPostProcess установленным по умолчанию, поэтому нажатия клавиш (активные события) будут передаваться им, позволяя перехватывать активность, если была нажата короткая клавиша. Нажатие "А" передает активность кнопке "All right". Теперь предположим что активна строка ввода, так что нажатия клавиш обрабатываются и вставляются строкой ввода. Нажатие клавиши "А" вставляет "А" в строку ввода и кнопка никогда не увидит это событие, поскольку активный видимый элемент обработал ее. Если вы зададите предварительную обработку клавиши "А" для кнопки, она сможет перехватывать короткую клавишу до того как ее обработает активный видимый элемент. К сожалению это не даст Вам набрать букву "А" в строке ввода! Решение очень просто: сделайте проверку в кнопке для различных коротких клавиш до и после того как активный элемент обработает событие. По умолчанию кнопка просматривает свою короткую клавишу в форме Alt-буква до процесса и в форме буквы после процесса. Вот почему Вы можете использовать короткий набор Alt-буква в диалоговом окне, но можете обрабатывать обычные буквы только когда активный элемент управления не "ест" клавиши. Это просто сделать. По умолчанию кнопки имеют установленные ofPreProcess и ofPostProcess, так что видят активные события и до и после активного видимого элемента, но внутри метода HandleEvent кнопка проверяет некоторые клавиши только если активный элемент управления уже видел событие:
evKeyDown: { это часть оператора case } begin C := HotKey(Title^); if (Event.KeyCode = GetAltCode(C)) or (Owner^.Phase = phPostProcess) and (C <> #0) and (upcase(Event.CharCode) = C) or (State and sfFocused <> 0) and (Event.CharCode = ' ') then begin PressButton; ClearEvent(Event); end; end;

Полиморфизм.

Второе свойство массивов, которое может стать ограничением для Вашей программы в том, что каждый элемент массива должен быть одного типа и этот тип определяется во время компиляции. Коллекции обходят это ограничение, используя нетипированные указатели. Это не только быстро и эффективно, но и позволяет коллекции содержать объекты (и даже не объекты) различных типов и размеров. Так же как поток, коллекция не должна ничего знать об обрабатываемых объектах. Она только хранит их и выдает по запросу.

Полиморфные коллекции.

Вы видите, что коллекции могут хранить любой тип данных динамически и что они содержат методы, помогающие Вам эффективно обращаться к данным коллекции. В действительности TCollection определяете 23 метода. Когда Вы используете коллекции в Ваших программах, Вы удивитесь скорости их работы. Они спроектированы для обеспечения гибкости и реализованы на удивление быстрыми. Сейчас Вы увидите реальную мощь коллекций: элементы могут обрабатываться полиморфно. Это означает, что Вы можете делать больше, чем просто сохранять тип объекта в коллекции; Вы можете хранить множество различных типов объектов из любого места в иерархии объектов. В примерах, которые мы рассматривали до сих пор, все элементы коллекции были одного типа. Но коллекции могут хранить любые объекты, порожденные от TObject и Вы можете свободно смешивать эти объекты. Обычно Вам необходимо иметь объекты с определенным сходством. Как пример рассмотрим программу, которая помещает 3 различных графических объекта в коллекцию. Затем итератор ForEach используется для прохода по коллекции и отображения каждого объекта. Этот пример использует модуль Graph и драйверы BGI, поэтому выо время компиляции GRAPH.TPU должен быть в текущем справочнике или в справочниках модулей (Options/Directories/Unit Directory). При выполнении программы перейдите в справочник, содержащий драйверы .BGI или модифицируйте вызов InitGraph, чтобы указать их расположение (например C:\TP\BGI). Вначале определим объект абстрактного предка.
{ TVGUID20.PAS } type PGraphObject = ^TGraphObject; TGraphObject = object(TObject) X,Y: Integer; constructor Init; procedure Draw; virtual; end;
Вы видите из этого объявления, что каждый графический объект может инициализироваться (Init) и отображаться на графическом экране (Draw). Теперь определим точку, окружность и прямоугольник, наследуя их от общего предка:
PGraphPoint = ^TGraphPoint; TGraphPoint = object(TGraphObject) constructor Init; procedure Draw; virtual; end;
PGraphCircle = ^TGraphCircle; TGraphCircle = object(TGraphObject) Radius: Integer; constructor Init; procedure Draw; virtual; end;

PGraphRect = ^TGraphRect; TGraphRect = object(TGraphObject) Width, Height: Integer; constructor Init; procedure Draw; virtual; end;

Эти 3 объекта наследуют поля X и Y от PGraphObject, но имеют различные размеры. PGraphCircle добавляет Radius, а PGraphRect добавляет Width и Height. Следующий код создает коллекцию:

. List := New(PCollection, Init(10, 5));

for I := 1 to 20 do begin case I mod 3 of 0: P := New(PGraphPoint, Init); 1: P := New(PGraphCircle, Init); 2: P := New(PGraphRect, Init); end; List^.Insert(P); end; .

Как Вы видите, цикл for вставляет 20 графических объектов в коллекцию List. Все, что Вы знаете, это то, что каждый объект в List - какого-то из типов от TGraphObject. После того, как они вставлены в коллекцию, неважно какой из элементов окружность, точка и прямоугольник. Благодаря полиморфизму Вам не нужно знать сколько данных содержит каждый объект и какой код (Draw) ему требуется. Просто пройдем по коллекции, используя метод итератора и каждый объект отобразит себя сам:

procedure DrawAll(C: PCollection);

procedure CallDraw(P : PGraphObject); far; begin P^.Draw; end;

begin { DrawAll } C^.ForEach(@CallDraw); end;

var GraphicsList: PCollection; begin . DrawAll(GraphicsList); . end.

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

Поля Turbo Vision.

Если Вы возьмете 3 объекта TView, TGroup и TWindow, то увидите наследование их полей и как растет функциональность при движении вниз по иерархии (вспомним, что дерево объектов растет вниз от корня).
Таблица 3.1. Наследование полей видимых элементов.
--------------------------------------------- Поля TView Поля TGroup Поля TWindow --------------------------------------------- Owner Owner Owner Next Next Next Origin Origin Origin Size Size Size Cursor Cursor Cursor GrowMode GrowMode GrowMode DragMode DragMode DragMode HelpCtx HelpCtx HelpCtx State State State Options Options Options EventMask EventMask EventMask Buffer Buffer Phase Phase Current Current Last Last Flags Title Number ZoomRect Palette Frame ---------------------------------------------
Заметим, что TGroup наследует все поля TView и добавляет поля, которые необходимы для операций над группой, такие как указатели на текущий и последний видимые элементы в группе. TWindow наследует все поля TGroup и добавляет поля, требуемые для операций над окном, такие как заголовок и номер окна. Для того, чтобы полностью понять TWindow Вам необходимо помнить, что окно - это группа (group) и видимый элемент (view).

Полоса меню.

Переменная полосы меню MenuBar инициализируется вложенными вызовами стандартных функций NewMenu, NewSubMenu, NewItem и NewLine. После того, как Вы инициализируете меню, Ваша работа закончена. Полоса меню знает как обработать ввод пользователя без Вашей помощи. Инициализируем простую полосу меню с одним элементом, содержащем один выбор:
## File ############# +----------------+** |**Open F3*******|#* +----------------+#* **##################* *********************
const cmFileOpen = 200; { определение новой команды } procedure TMyApp.InitMenuBar; var R: TRect; begin GetExtent(R); R.B.Y := R.A.Y + 1; MenuBar := New(PMenuBar, Init(R, NewMenu( { создать полосу с меню } NewSubMenu('~F~ile', hcNoContext, NewMenu( { определить меню } NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext, { элемент } nil)), { больше нет элементов } nil) { больше нет подменю } ))); { конец полосы } end;
Меню, создаваемое этим кодом, называется 'File' и элемент меню называется 'Open'. "~" делает F символом короткого ввода в 'File', а O - символом короткого ввода 'Open'; клавиша F3 устанавливается как горячая клавиша для 'Open'. Все видимые элементы Turbo Vision могут иметь номер контекстной подсказки, связанный с ними. Номер позволяет просто реализовать контекстно-ориентированную справочную систему в Вашей программе. По умолчанию видимые элементы имеют контекст hcNoContext - это специальный контекст, который не изменяет текущий контекст. Номера контекстов подсказки появляются при инициализации полосы меню, поскольку из-за вложенной структуры этих объектов добавить номера позднее будет трудно. Когда Вы готовы добавить контекст подсказки в полосу меню, Вы можете подставить свои значения для hcNoContext в коде Init. Чтобы добавить второй элемент в меню 'File', Вы просто вкладываете другую функцию NewItem:
## File ############# +----------------+** |**Open F3*******|#* | New F4 |#* +----------------+#* **##################* *********************
MenuBar := New(PMenuBar, Init(R, NewMenu( NewSubMenu('~F~ile', hcNoContext, NewMenu( NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext, NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext, nil))), nil) )));

Чтобы добавить второе меню, Вы вкладываете другую функцию NewSubMenu:

## File Window########### ********+---------------+** ********|**Next F6******|#* ********| Zoom F5 |#* ********+---------------+#* **********################* ***************************

MenuBar := New(PMenuBar, Init(hcNoContext, NewMenu( NewSubMenu('~F~ile', hcNoContext, NewMenu( NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext, NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext, nil))), NewSubMenu('~W~indow', hcNoContext, NewMenu( NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext, NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext, nil)), nil))) { закрывающая скобка для меню } )));

Вы связали 2 стандартных команды Turbo Vision cmNext и cmZoom с элементами меню и горячими клавишами. Чтобы добавить горизонтальную линию между выборами в меню, вставьте вызов NewLine между вызовами NewItem:

## File Window###### +----------------+** |**Open F3*******|#* | New F4 |#* +----------------+#* | Exit Alt-X |#* +----------------+#* **##################* *********************

{ находится в TVGUID03.PAS } MenuBar := New(PMenuBar, Init(hcNoContext, NewMenu( NewSubMenu('~F~ile', hcNoContext, NewMenu( NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext, NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext, NewLine( NewItem('E~x~it', 'Alt-X', kbAltX, cmNewWin, hcNoContext, nil))))), NewSubMenu('~W~indow', hcNoContext, NewMenu( NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext, NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext, nil))), nil)) )));

Вы можете заметить, что версия TVGUID03.PAS на Вашем диске так же добавляет клавишу статуса в строку статуса, связывая клавишу F10 с командой cmMenu. cmMenu - это стандартная команда Turbo Vision, которая помогает пользователям использовать полосу меню без мышки. В этом случае клавиша F10 активирует полосу меню, позволяя выбрать меню и элементы меню, используя клавиши курсора. Вы можете так же заметить, что элемент статуса имеет пустую строку в качестве текста и для него ничего не появляется на экране. Хотя можно предупредить пользователей, что F10 будет активировать меню, они, скорее всего, не будут указывать этот элемент мышкой. Отметить полосу меню гораздо более удобно.

Получение группы.

Как подэлементы присоединяются к группе? Этот процесс называется вставкой. Видимые подэлементы создаются и затем вставляются в группу. В предыдущем примере констрактор TApplication.Init создает 3 объекта и вставляет их в программу:
InitDeskTop; InitStatusLine; InitMenuBar; if DeskTop <> nil then Insert(DeskTop); if StatusLine <> nil then Insert(StatusLine); if MenuBar <> nil then Insert(MenuBar);
В данном случае TApplication делит свою область на 3 части и передает каждую из них подэлементам. Это упрощает видимое представление, поскольку видимые подэлементы не перекрываются. Однако одним из наибольших достижений оконной среды является возможность иметь множество перекрывающихся окон на панели экрана. Группы (включая панель экрана) знают как обрабатывать перекрывающиеся подэлементы. Группа хранит порядок вставки подэлементов. Этот порядок соответствует порядку Z. Как Вы увидите, Z-упорядочивание определяет порядок, в котором подэлементы рисуются и порядок, в котором события передаются в них.

Получение TPoint.

Тип TPoint крайне прост. Он содержит только 2 поля X и Y - коодинаты точки. Он не имеет методов. Turbo Vision использует объект TPoint, чтобы позволить видимому элементу указать координаты одним полем.

Получение TRect.

TPoint редко напрямую используется в Turbo Vision. Поскольку каждый видимый элемент имеет и начало и размер, обычно они обрабатываются в объекте TRect совместно. TRect имеет 2 поля А и В каждое типа TPoint. Когда заданы границы видимого элемента, эти границы передаются в констрактор TRect. TRect и TView предоставляют полезные методы для манипуляции размером видимого элемента. Например, если Вы хотите создать видимый элемент, который заполняется только внутри окна, Вы можете получить размер окна, сократить его и назначить новому внутреннему видимому элементу.
procedure ThisWindow.MakeInside; var R: TRect; Inside: PInsideView; begin GetExtent(R); { установить R в размер ThisWindow} RR.Grow(-1, -1); { сократить прямоугольник на 1 } Inside := New(PInsideView, Init(R)); { создать внутренний видимый элемент} Insert(Inside); { вставить новый видимый элемент в окно } end;
GetExtent - это метод TView, который устанавливает аргумент TRect в координаты прямоугольника, покрывающего весь видимый элемент. Grow - это метод TRect, который увеличивает (а с отрицательными параметрами уменьшает) горизонтальный и вертикальный размеры прямоугольника.

Порождение.

Вы можете легко породить объектный тип из существующего.
PNewScrollBar = ^TNewScrollBar; TNewScrollBar = object(TScrollBar) end;
Вы еще не имеете экземпляров этого объектного типа. До объявления объектов TNewScrollBar Вам необходимо определить новые методы или перекрыть некоторые методы TScrollBar и, возможно, добавить некоторые новые поля; иначе не существует причин для создания нового типа объекта. Новые или измененные методы и поля добавляют функциональность к TScrollBar. Ваш новый метод Init будет определять значения по умолчанию для Ваших новых объектов.

Порожденные типы и экземпляры объектов.

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

Посредники.

Если программа спроектирована правильно и видимые элементы требуют взаимодействия между собой, один из способов - создать промежуточный видимый элемент. Например, предположим, что Вы имеете объект электронной таблицы и объект текстового процессора и хотите иметь возможность вставлять что-либо из электронной таблицы в текстовый процессор и наоборот. В программе Turbo Vision Вы можете выполнить это прямым взаимодействием видимых элементов. Но предположим, что позже Вам понадобится добавить к этой группе объектов, скажем, базу данных и вставлять в и из базы данных. В этом случае Вам потребуется дублировать связь, установленную Вами между первыми двумя объектами на все 3 объекта. Лучшее решение - это установить промежуточный видимый элемент. В этом случае, скажем, "карман". Объект должен знать только как копировать что-либо в этот карман и как вставить что-либо из кармана. Вне зависимости от того, сколько новых объектов Вы добавите в группу, взаимодействие никогда не станет более сложным, чем сейчас.

Потоки DOS.

TDosStream - это специализированный поток, реализующий небуферизованный поток файла DOS. Поле Handle соответствует обычному обработчику файла DOS. Констрактор Init создает поток DOS с заданным именем файла и режимом доступа. TDosStream определяет все абстрактные методы TStream, за исключением Flush, который требуется только для буферизованных потоков.

Потоки EMS.

Наиболее специализированный поток TEmsStream реализует поток в EMS памяти. Новые поля содержат обработчик EMS, число страниц, размер потока и текущую позицию внутри потока.

Потоки являются полиморфными.

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

Потоки.

Поток - это обобщенный объект для обработки ввода и вывода. В традиционных устройствах и файлах В/В для обработки выбора и преобразования различных типов данных должны быть предоставлены отдельные наборы функций. Используя потоки Turbo Vision, Вы можете создавать полиморфные методы В/В такие как Read и Write, которые знают как обрабатывать содержимое их потоков. TStream - это базовый абстрактный объект, обеспечивающий полиморфный В/В на и из устройства памяти. TStream предоставляет поле Status, указывающее на режим доступа (только на чтение, только на запись, чтение/запись), а поле ErrorInfo возвращает ошибки В/В. Предоставлено 7 виртуальных методов: Flush, GetPos, GetSize, Read, Seek, Truncate и Write. Они должны быть перекрыты для порождения специализированных типов потоков. Вы увидите, что Turbo Vision использует эту стратегию для порождения TDosStream, TEmsStream и TBufStream. Существуют так же методы CopyFrom, Error, Get, ReadStr, Reset, WriteStr. Типы объектов должны быть зарегистрированы, используя RegisterType до того, как их можно использовать с потоками. Стандартные типы объектов Turbo Vision уже зарегистрированы (см. процедуру RegisterType в главе 14).

Поведение окна.

Давайте попробуем поработать с Вашей программой. Она уже имеет ряд возможностей. Она знает как открыть, закрыть, выбрать, переместить и изменить размеры множества окон на панели экрана. Неплохо для менее, чем ста строк кода! После того, как TMyApp инициализирует окно, он вставляет его в панель экрана. Как Вы помните, DeskTop - это группа, что означает, что его назначение - владеть и управлять видимыми подэлементами, такими как Ваше окно. Если Вы откомпилировали и выполнили код, Вы заметите, что Вы можете изменять размер, перемещать и закрывать новое окно. Ваш ввод от мышки преобразуется в серию событий и направляется из панели экрана в новое окно, которое знает, как обработать их. Если Вы сохранили вызов cmNewWin, на панели экрана будет появляться несколько окон с уникальными номерами. Эти окна могут изменять размеры, выбираться и перемещаться. Рис. 2.2 показывает панель экрана, на котором открыто несколько окон.
Рис. 2.2. TVGUID04 с несколькими открытыми окнами.
+-----------------------------------------------------------------+ | File Window | |*****************************************************************| |*********************+-- Demo Window 3----+**********************| |*********************| +-- Demo Window 7--+*****| |*********************| | |*****| |*********************| | |*****| |*********************| +-- Demo Window 8--+ |*****| |*********************| | | |*****| |*********************+--| | |*****| |+-- Demo Window 1--+** | |---------------+*****| |** | | |***************| |** | | |***************| +-- Demo Window 4--+------------------+ |***************| | |****| +-- Demo Window 6--+Window 2--+*| | |****| | | |*| |+----| |****+--| | |*| |*****| +=[ю]= Demo Window 9=[ш]=+ | |*| |*****| | | | |*| |*****+------------------| | | |*| |************************| |--+----------+*| |************************| |***************| |************************| |***************| |************************+=======================-+***************| |*****************************************************************| | Alt-X Exit F4 New Alt-F3 Close | +-----------------------------------------------------------------+
TWindow - это группа, которая первоначально владеет одним видимым элементом TFrame. Пользователь отмечает кнопки на рамке для перемещения, изменения размера или закрытия окна. Рамка отображает заголовок, который был получен во время инициализации окна и он рисуется фоновым цветом окна, таким как TBackGround панели экрана. Все это происходит без написания Вашего кода.

Позиционированные события.

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

Прикладной объект.

Краеугольным объектом любой программы является объект TApplication. В действительности, Вы никогда не создаете экземпляра объекта типа TApplication. TApplication - это абстрактный тип объекта. Он ничего не делает. Вы используете TApplication, создавая порожденные типы от TApplication, которые содержат Ваш программный код. В HELLO определяется порожденный тип объекта THelloApp:
PHelloApp = ^THelloApp; THelloApp = object(TApplication) procedure GreetingBox; procedure HandleEvent(var Event: TEvent); virtual; procedure InitMenuBar; virtual; procedure InitStatusLine; virtual; end;
Как показано здесь, полезно определить тип указателя на каждый тип, определяемого Вами объекта, поскольку большая часть работы над объектами производится через указатели. Полиморфизм главным образом работает через указатели. THelloApp содержит гораздо больше, чем эти 4 метода; порожденный объект наследует все от его предка. В определении THelloApp Вы определяете, чем новый объект отличается от его предка TApplication. Все, что Вы не переопределяете, наследуется в неизменном виде от TApplication. 4 метода, определенные в THelloApp, завершают "большую картину" Вашего приложения: - Как прикладным функциям указывается, что событие произошло и как они отвечают на них. Вы должны определить метод HadleEvent для выполнения этого требования. Метод HandleEvent, определенный в TApplication, работает с общими событиями, которые возникают внутри любой программы, но Вы должны обеспечить обработку событий, специфичных для Вашей программы. - Метод InitMenuBar устанавливает меню для полосы меню Вашей программы. TApplication содержит полосу меню, но не сами меню; если Вам необходимы меню, Вы просто определяете метод для определения меню. Вас может удивить, почему код InitMenuBar не является частью констрактора THelloApp. Может быть и так, но большие возможности предоставляет выбор из нескольких меню для начального меню. Лучше вывести это за пределы констрактора, оставляя внутри констрактора только те вещи, которые необходимо выполнять всегда при каждом выполнении программы. - Метод InitStatusLine устанавливает текст строки статуса внизу экрана. Этот текст обычно отображает сообщение о текущем состоянии программы, показывая доступные горячие клавиши или напоминая пользователю о некоторых действиях. - Метод GreetingBox вызывает диалоговое окно в ответ на элемент меню Greeting. GreetingBox вызывается из метода HandleEvent в ответ на событие, переключаемое выбором элемента меню Greeting. В более сложных программах Вы можете использовать различные методы в ответ на каждый элемент меню, определенный в начальном меню. Короче, методы из THelloApp обеспечивают все, что должны выполнять объекты главной программы: установку программы, выполнение действий в ответ на события и методы реализующие отклики на отдельные события. Именно эти 3 вещи Вы должны добавить к TApplication при создании порожденного типа объекта.

Прикладные программы.

TApplication предоставляет объект заготовки программы для Ваших программ на Turbo Vision. Он является потомком от TGroup (через TProgram). Обычно он владеет видимыми подэлементами TMenuBar, TDeskTop и TStatusLine. TApplication имеет методы для создания и вставки этих трех подэлементов. Ключевой метод TApplication - это TApplication.Run, который выполняет код программы.

Примитивные типы объектов.

Turbo Vision предоставляет 3 простых типа объекта, которые используются другими объектами или используются как основа иерархии более сложных объектов. TPoint и TRect используются всеми видимыми объектами в иерархии Turbo Vision. TОbjеct - основа иерархии. Заметим, что объекты этих типов не являются прямо отображаемыми. TPoint - это просто объект позиции на экране (X, Y). TRect просто содержит верхнюю левую и нижнюю правую границы прямоугольника и несколько невизуализирующих сервисных методов.

Принадлежность.

Другой способ взаимосвязи видимых элементов - дерево видимых элементов. В диаграмме дерева видимых элементов (рис. 4.7.) TDialog владеет типом TButton. Здесь взаимосвязь не между иерархическими типами объектов (TDialog не является предком TButton!), а между экземплярами объектов, между владельцем и подэлементами.
Рис. 4.7. Дерево видимых элементов простого диалогового окна.
+----------+ | TDialog | +-+---+---++ +-------+ | +-------+ +---+----++-----+---++------+------+ | TFrame TButton TStaticText | +--------++---------++-------------+
Вам необходимо, чтобы TButton взаимодействовал с его владельцем в дереве элементов (TDialog) и TButton будет рисовать атрибуты, наследованные от своего предка (TView). Не путайте эти взаимосвязи. Выполнение программы на Turbo Vision подобно дереву с созданием экземпляров видимых элементов и владением другими видимыми элементами. Когда программа открывает и закрывает окна, дерево видимых элементов растет и уменьшается при вставке и удалении экземпляров объектов. С другой стороны иерархия объектов только растет, когда Вы производите новый тип объекта от стандартного объекта.

Природа событий.

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

Прямой доступ к потокам.

До сих пор мы использовали потоки как последовательные устройства: Вы выводили объекты в конец потока и считывали их обратно в том же порядке. Turbo Vision предоставляет Вам дополнительные возможности. Он позволяет Вам интерпретировать поток как виртуальное устройство с прямым доступом. В дополнение к Get и Put, которые соответствуют Read и Write для файла, потоки предоставляют возможности аналогичные файловым Seek, FilePos, FileSize и Truncate. - Процедура Seek передвигает указатель текущего потока на заданную позицию (в байтах лот начала потока) как стандартная процедура Seek Turbo Pascal. - Функция GetPos обратна процедуре Seek. Она возвращает LongInt с текущей позицией в потоке. - Функция GetSize возвращает размер потока в байтах. - Процедура Truncate удаляет все данные после текущей позиции потока, делая текущую позицию последней в потоке. Чтобы можно было использовать эти программы, прямой доступ к потоку требует создания вне потока индекса, содержащего начальные позиции каждого объекта в потоке. Коллекция идеальна для этой цели и в действительности используется в Turbo Vision с файлами ресурсов (ресурсы обсуждаются в главе 9). Если Вы хотите использовать прямой доступ к потоку, Вы можете использовать файл ресурса.

Процедура Abstract Objects

================================================================= Объявление procedure Abstract;
Функция Вызов этой процедуры завершает программу с ошибкой времени выполнения 211. При реализации абстрактных типов объекта, используйте вызовы Abstract в тех виртуальных методах, которые должны быть перекрыты в порожденных типах. Это предотвратит любые попытки использования экземпляров абстрактного типа.
См. также "Абстрактные методы" в главе 3.

Процедура AssignDevice TextView

================================================================= Объявление procedure AssignDevice(var T: Text; Screen: PTextDevice);
Функция Связывает текстовый файл с TTextDevice. AssignDevice работает аналогично стандартной процедуре Assign за исключением того, что указывается не имя файла. Вместо этого, текстовый файл связывается с TTextDevice данным в Screen (запоминая Screen в первых 4 байтах поля UserData в TextRec(T). Последовательность операций В/В для текстового файла будет читать и писать из TTextDevice, используя виртуальные методы StrRead и StrWrite. Поскольку TTextDevice это абстрактный тип, параметр Screen обычно указывает на образец TTerminal, который реализует полную функциональность видимого элемента TTY подобного скроллинга.
См. также TTextDevice; TextRec

Процедура ClearHistory HistList

================================================================= Объявление procedure ClearHistory;
Функция Удаляет все строки из всех списков истории.

Процедура ClearScreen Drivers

================================================================= Объявление procedure ClearScreen;
Функция Очищает экран. ClearScreen предполагает, что вначале был вызван InitVideo. Вам редко потребуется использовать эту процедуру, как это объяснено в описанни InitVideo.
См. также InitVideo

Процедура DisposeMenu Menus

================================================================= Объявление procedure DisposeMenu(Menu: PMenu);
Функция Освобождает все элементы указанных меню (и все их подменю).
См. также Тип TMenu

Процедура DisposeStr Objects

================================================================= Объявление procedure DisposeStr(P:String);
Функция Освобождает строки, распределенные в куче с помощью функции NewStr.
См. также NewStr

Процедура DoneEvents Drivers

================================================================= Объявление procedure DoneEvents;
Функция Завершает монитор событий Turbo Vision, отключая обработчик прерываний мышки. Вызывается автоматически при вызове TApplication.Done.
См. также TApplication.Done, InitEvents

Процедура DoneHistory Drivers

================================================================= Объявление procedure DoneHistory;
Функция Освобождает блок истории, распределенный InitHistory. Вызывается автоматически при вызове TApplication.Done.
См. также Процедура InitHistory, TApplication.Done

Процедура DoneMemory Memory

================================================================= Объявление procedure DoneMemory;
Функция Завершает монитор памяти Turbo Vision, освобождая все буфера, распределенные через GetBufMem. Вызывается автоматически при вызове TApplication.Done.
См. также TApplication.Done, InitMemory

Процедура DoneSysError Drivers

================================================================= Объявление procedure DoneSysError;
Функция Завершает обработчик системных ошибок Turbo Vision, восстанавливая вектора прерываний 09H, 1BH, 21H, 23H, 24H и восстанавливая состояние Ctrl-Break в DOS. Вызывается автоматически при вызове TApplication.Done.
См. также TApplication.Done, InitSysError

Процедура DoneVideo Drivers

================================================================= Объявление procedure DoneVideo;
Функция Завершает монитор экрана Turbo Vision, восстанавливая начальный режим экрана (StartupMode), очищая экран и восстанавливая курсор Вызывается автоматически при вызове TApplication.Done.
См. также TApplication.Done, InitVideo, переменная StartupMode

Процедура FormatStr Drivers

================================================================= Объявление procedure FormatStr(var Result: String; Format: String; var Params);
Функция Процедура форматирования строки, которая работает подобно функции языка Си vsprintf. Format включает спецификаторы формата, а Params содержит список параметров. FormatStr выполняет форматированный вывод строки в Result. Параметр Format может содержать любое число спецификаторов формата, для отображения параметров в Params. Формат спецификаторов - %[-][nnn]X, где - % указывает начало спецификатора формата; - [-] необязательный знак минуса, указывающий, что параметр будет выровнен влево (по умолчанию параметры при отображении выравниваются вправо); - [nnn] - необязательный десятичный спецификатор длины в диапазоне 0-255 (0 указывает на отсутствие длины, а не нуль означает, что выводится поле в nnn символов); - Х - символ формата: - 's' означает, что параметр указывает на строку; - 'd' означает десятичное представление LongInt параметра; - 'c' означает, что младший байт параметра - символ; - 'x' означает шестнадцатиричное представление параметра LongInt. - '#'устанавливает индекс параметра в nnn.
Например, если параметр указывает на строку, содержащую 'spiny', следующая таблица показывает спецификаторы и их результаты при печати:
Таблица 14.11. Спецификаторы формата и их результаты.
----------------------------------------- Спецификатор Результат ----------------------------------------- %6s ' spiny' %-6s 'spiny' %3s 'iny' %-3s 'spi' %06s '0spiny' %-06s 'spiny0' ----------------------------------------
Params - это нетипированный var параметр, содержащий параметры с соответствующимим спецификаторами формата в Format. Params должен быть массивом из LongInt или указателей или записью, содержащей LongInt или указатели. Например, для вывода строки сообщения об ошибке
Error in file [file name] at line [line number]
Вы должны послать следующую строку в Format:
'Error in file %s at line %d'.
Params должен содержать указатель на строку имени файла и Longint, представляющая число строк в файле. Это может быть сделано двумя способами: в массиве или в записи. Следующий пример показывает два типа объявлений и присвоений переменных, оба создают допустимые значения, передаваемые как Params в FormatStr.

type ErrMsgRec = record FileName: PString; LineNo: Longint; end;

ErrMsgArray = array[01] of Longint;

const TemplateMsg = 'Error in file %s at line %d';

var MyFileName: FNameStr; OopsRec: ErrMsgRec; DarnArray: ErrMsgArray; TestStr: String;

begin MyFileName := 'WARTHOG.ASM';

with OopsRec do begin FileName := @MyFileName; LineTo := 42; end; FormatStr(TestStr, TemplateMsg, OopsRec); Writeln(TestStr);

DarnArray[0] := Longint(@MyFileName); DarnArray[1] := 24; FormatStr(TestStr, TemplateMsg, DarnArray); Writeln(TestStr); end;

См. также Функцию SystemError, объект TParamText.

Процедура FreeBufMem Memory

================================================================= Объявление procedure FreeBufMem(P: Pointer);
Функция Освобождает кэш-буфер, ссылаемый указателем Р.
См. также GetBufMem, DoneMemory.

Процедура GetBufMem Memory

================================================================= Объявление procedure GetBufMem(var P: Pointer; Size: Word);
Функция Распределяет кэш-буфер для Size байт и запоминает указатель на него в Р. Если нет памяти для кэш-буфера запрашиваемого размера, Р устанавливается в nil. Кэш- буфер отличается от обычных блоков кучи (распределяемых с помощью New, GetMem или MemAlloc), в которых они могут размещаться или освобождаться монитором памяти в любое время. Указатель, передаваемый в GetBufMem, становится указателем на кэш-буфер и он (и только он) корректируется, когда буфер перемещается монитором памяти. Если монитор памяти решает освободить буфер, он устанавливает этот указатель в nil. Кэш-буфер может быть освобожден через вызов FreeBufMem. Кэш-буфера будут занимать любое нераспределенное пространство кучи между HeapPtr и HeapEnd, включая область, установленную для пула надежности программы.
Turbo Vision использует кэш-буфера для подкачки содержимого объектов TGroup (таких, как окна, диалоговые окна и панель экрана), как только эти объекты устанавливают флаг ofBuffered - это значительно повышает производительность операций перерисовки.
См. также FreeBuffMem, InitMemory, TGroup.Draw.

Процедура GetKeyEvent Drivers

================================================================= Объявление procedure GetKeyEvent(var Event: TEvent);
Функция Проверяет, доступно ли событие от клавиатуры вызовом прерывания BIOS INT 16H. Если клавиша была нажата, Event.What устанавливается в evKeyDown и Event.KeyCode устанавливается в cкан-код клавиши. В противном случае, Event.What устанавливается в evNothing. GetKeyEvent вызывается из TProgram.GetEvent.
См. также TProgramm.GetEvent, константы evXXXX, TView.HandleEvent.

Процедура GetMouseEvent Drivers

================================================================= Объявление procedure GetMouseEvent(var Event: TEvent);
Функция Проверяет, доступно ли событие от мышки из очереди событий от мышки, поддерживаемой обработчиком событий Turbo Vision. Если происходит событие от мышки, Event.What устанавливается в evMouseDown, evMouseUp, evMouseMove или evMouseAuto; Event.Buttons устанавливается в mbLeftButton или mbRightButton; Event.Double устанавливается в True или False; Event. Where устанавливается в позицию мышки в глобальных координатах (соответствующих координатной системе TApplication). Если события от мышки недоступны, Event.What устанавливается в evNothing. GetMouseEvent вызывается из TProgram.GetEvent.
См. также TProgram.GetEvent, события evXXXX, методы HandleEvent.

Процедура HideMouse Drivers

================================================================= Объявление procedure HideMouse;
Функция Курсор мышки изначально видим после вызова InitEvents. HideMouse прячет мышку и увеличивает внутренний "счетчик мышки" в драйвере мышки. ShowMouse будет уменьшать этот счетчик и показывать курсор мышки, когда счетчик становится равен 0. Таким образом, вызовы HideMouse и ShowMouse могут быть вложенными, но всегда должны быть сбалансированы.
См. также InitEvents, DoneEvents, ShowMouse

Процедура HistoryAdd HistList

================================================================= Объявление procedure HistoryAdd(Id: Byte; var Str: String);
Функция Добавляет строку Str в список истории, указываемый с помощью Id.

Процедура InitEvents Drivers

================================================================= Объявление procedure InitEvents;
Функция Инициализирует монитор событий Turbo Vision, подключая обработчик прерываний мышки и показывая мышку. Вызывается автоматически TApplication.Init.
См. также DoneEvents.

Процедура InitHistory HistList

================================================================= Объявление InitHistory;
Функция Вызывается с помощью TApplication.Init для распределения блока памяти в куче, используемом монитором списка истории. Размер блока определяется переменной HistorySize. После вызова InitHistory переменная HistoryBlock указывает на начало блока.
См. также TProgram.Init, процедуру DoneHistory.

Процедура InitMemory Memory

================================================================= Объявление procedure InitMemory;
Функция Инициализирует монитор памяти Turbo Vision, инсталлируя функцию объявления кучи в HeapError. Вызывается автоматически посредством TApplication.Init.
См. также DoneMemory.

Процедура InitSysError Drivers

================================================================= Объявление procedure InitSysError;
Функция Инициализирует обработчик системных ошибок Turbo Vision, переопределяя вектора прерываний 09H, 1BH,21H, 23H, 24H и очищая состояние Ctrl-Break в DOS. Вызывается автоматически посредством TApplication.Init.
См. также DoneSysError.

Процедура InitVideo Drivers

================================================================= Объявление procedure InitVideo;
Функция Инициализирует монитор экрана Turbo Vision. Сохраняет текущий режим экрана в StartupMode и переключает экран в режим, указанный в ScreenMode. Переменные ScreenWidth, ScreenHeight, HiResScreen, CheckSnow, ScreenBuffer и CursorLines корректируются соответственно. Режим экрана позднее может быть изменен использованием SetVideoMode. InitVideo вызывается автоматически посредством TApplication.Init.
См. также DoneVideo, SetVideoMode, smXXXX.

Процедура MoveBuf Objects

================================================================= Объявление procedure MoveBuf(var Dest; var Source; Attr: Byte; Count: Word);
Функция Копирует текст в буфер для использования с TView.WriteBuf или TView.WriteLine. Dest должен быть TDrawBuffer (или эквивалентным массивом слов) и Source должен быть массивом байт. Count байт копируются из Source в младшие байты соответствующих слов в Dest. Старшие байты слов в Dest устанавливаются в Attr или остаются неизменными, если Attr - 0.
См. также тип TDrawBuffer, MoveChar, MoveCStr, MoveStr.

Процедура MoveChar Objects

================================================================= Объявление procedure MoveChar(var Dest; C: Char; Attr: Byte; Count: Word);
Функция Копирует символы в буфер для использования с TView.WriteBuf или TView.WriteLine. Dest должен быть TDrawBuffer (или эквивалентным массивом слов). Младшие байты первых Count слов Dest устанавливаются в С или остаются неизменными, если Ord(C) - 0. Старшие байты слов устанавливаются в Attr или остаются неизменными, если Attr - 0.
См. также тип TDrawBuffer, MoveBuf, MoveCStr, MoveStr.

Процедура MoveCStr Objects

================================================================= Объявление procedure MoveCStr(var Dest; Str: String; Attrs: Word);
Функция Копирует строку в буфер для использования с TView.WriteBuf или TView.WriteLine. Dest должен быть TDrawBuffer (или эквивалентным массивом слов). Символы в Str копируются в младшие байты соответствующих слов в Dest. Старшие байты слов устанавливаются в Lo(Attr) или в Hi(Attr). Символы "~" в строке используются для переключения между двумя байтами атрибута, передаваемыми в слове Attr.
См. также тип TDrawBuffer, MoveChar, MoveBuf, MoveStr.

Процедура MoveStr Objects

================================================================= Объявление procedure MoveStr(var Dest; Str: String; Attr: Byte);
Функция Копирует строку в буфер для использования с TView.WriteBuf или TView.WriteLine. Dest должен быть TDrawBuffer (или эквивалентным массивом слов). Символы в Str копируются в младшие байты соответствующих слов в Dest. Старшие байты слов устанавливаются в Attr или остаются неизменными, если Attr - 0.
См. также тип TDrawBuffer, MoveChar, MoveCStr, MoveBuf.

Процедура PrintStr Drivers

================================================================= Объявление procedure PrintStr(S: String);
Функция Печатает строку S на экране, используя вызов функции DOS 40H для записи в стандартное устройство вывода DOS. Имеет тот же эффект, что и Write (S), за исключением того, что PrintStr не требует редактирования с программой библиотеки времени выполнения файлового ввода/вывода.

Процедура RegisterDialogs Dialogs

================================================================= Объявление procedure RegisterDialogs;
Функция Вызывает RegisterType для каждого стандартного типа объекта, определенного в модулях TDialog, TInputLine, TButton, TCluster, TRadioButtons, TCheckBoxes, TListBox, TStaticText, TParamText, TLabel, THistory. Это позволяет использовать все эти объекты с потоком В/В.
См. также TStreamRec, RegisterTypes.

Процедура RegisterType Objects

================================================================= Объявление procedure RegisterType(var S: TStreamRec);
Функция Тип объекта Turbo Vision должен быть зарегистрирован перед использованием в потоке В/В. Стандартные типы объектов уже зарегистрированы с ObjTypes в резервированном диапазоне 099. RegisterType создает элемент в связанном списке записей TStreamRec.
См. также TStream.Get, TStreamPut, TStreamRec.

Процедура Sample Модуль

================================================================= Объявление procedure Sample(AParameter);
Функция Sample выполняет ряд полезных функций с параметром, AParameter.
См. также Функция Example

Процедура SetVideoMode Drivers

================================================================= Объявление procedure SetVideoMode(Mode: Word);
Функция Устанавливает видеорежим. Mode одна из констант smCO80, smBW80 или smMono с необязательнвм smFont8x8 добавленным для выбора 43 или 50-строчного режима EGA или VGA. SetVideoMode инициализирует некоторые переменные как InitVideo (за исключением переменной StartupMode, на которую это не воздействует). SetVideoMode обычно не вызывается напрямую. Вместо этого используйте TApplication.SetScreenMode, которая также устанавливает палитру программы.
См. также InitVideo, константы smXXXX, TApplication.SetScreenMode.

Процедура ShowMouse Drivers

================================================================= Объявление procedure ShowMouse;
Функция ShowMouse уменьшает "счетчик невидимости" в драйвере мышки и делает курсор мышки видимым если счетчик равен 0.
См. также InitEvents, DoneEvents, HideMouse.

Процедуры и функции.

------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- Abstract Процедура по умолчанию для методов, которые должны быть перекрыты DisposeStr Удаляет строку, созданную с помощью NewStr RegisterType Регистрирует тип объекта в потоках Turbo Vision -------------------------------------------------------------
------------------------------------------------------------- Функция Операция ------------------------------------------------------------- LongDiv Деление длинного целого на целое LongMul Умножение двух целых в длинное целое NewStr Распределение строки в куче -------------------------------------------------------------

------------------------------------------------------------- Процедура Операция ------------------------------------------------------------- HistoryAdd Добавляет строку в список истории ClearHistory Очищает все списки истории InitHistory Инициализирует монитор списков истории DoneHistory Закрывает монитор списков истории -------------------------------------------------------------
------------------------------------------------------------- Функция Операция ------------------------------------------------------------- HistoryCount Возвращает число строк в списке истории HistoryStr Возвращает отдельную строку из списка истории -------------------------------------------------------------

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

Этот раздел суммирует методы и возможности обработки ошибок потоков Turbo Vision так, чтобы Вы знали что Вы можете использовать при создании новых типов потоков. TStream - это абстрактный объект, который должен быть расширен, чтобы создать используемый тип потока. Большинство методов TStream абстрактные и должны быть реализованы в Ваших наследниках, а другие зависят от методов TStream. Только методы Error, Get и Put полностью реализованы в TStream. GetPos, GetSize, Read, Seek, SetPos, Truncate и Write должны быть перекрыты. Если тип порожденного объекта имеет буфер, так же должен быть перекрыт метод Flush.

Программы.

TProgram предоставляет набор виртуальных методов для его потомка TApplication.

Просмотр списка.

TListViewer выводит список в одну или несколько колонок и пользователь может выбрать элемент из этого списка. ListViewer может взаимодействовать с двумя полосами скроллинга. TListViewer предназначен для построения блока и не используется отдельно. Он может обрабатывать список, но сам не содержит списка. Его абстрактный метод GetText загружает элементы списка для его метода Draw. Наследник TListViewer должен перекрывать GetText для загрузки актуальных данных.

Просмотр списков.

Тип объекта TListViewer - это абстрактный базовый тип, от которого наследуется просмотр списков различных родов, таких как TListBox. Поля и методы TListViewer позволяют Вам отображать связанные списки строк с управлением одной или двух полос скроллинга. Обработчик событий позволяет делать выбор элементов списка мышкой или от клавиатуры. Метод Draw позволяет изменение размера и скроллинг. TListViewer имеет абстрактный метод GetText, который Вы должны обеспечить механизмом создания и манипуляции отображаемых элементов. TListBox, наследуемый от TListViewer, реализует наиболее часто используемые окна списков, таких как, например, имена файлов. Объекты TListBox отображают списки таких элементов в одну или более колонок с дополнительной вертикальной полосой скроллинга. Горизонтальные полосы скроллинга в TListViewer не поддерживаются. Наследование методов TListViewer позволяет Вам выбрать элемент мышкой или через клавиатуру. TListBox имеет дополнительное поле List, указывающее на объект TCollection. Он предоставляет объекты для распечатки и выбора. Содержимое коллекции формируется Вами так же как и действия, которые выполняются при выборе элемента.

Просмотр в любом окне.

Если Вы работали с традиционными окнами, то следующим шагом Вы попытаетесь записать что-либо в него. Но TWindow не пустая доска для записи: это группа Turbo Vision, объект TGroup без экранного представления всего, что лежит под ним. Чтобы поместить что-либо в окно, Вам необходимо сделать дополнительный шаг, который вложит в Ваши руки огромную мощь. Чтобы что-либо появилось в окне, Вы создаете видимый элемент, который знает как рисовать себя и вставляете его в окно. Этот видимый элемент называется интерьером. Первый интерьер будет заполнять все окно, но позже Вы узнаете как легко уменьшить его размер и освободить место для других видимых элементов. Окно может владеть несколькими интерьерами и любым числом других полезных видимых элементов: строками ввода, метками, кнопками. Вы также увидите как просто поместить полосу скроллинга в рамку окна. Вы можете перекрывать подэлементы в группе - видимые элементы, с которыми Вы взаимодействуете, являются верхними. TDeskTop имеет метод Tile, который может перекрывать видимые подэлементы после их инициализации, но этот метод используется только с панелью экрана. Вы создаете интерьер простым наследованием от TView. Любой TView может иметь рамку, которая действует как рамка обычного окна. Рамка TView, которая не может быть отмечена, находится вне области отсечения любого вывода для этого видимого элемента. Эта рамка просто окаймляет окно. Если интерьер TView заполняет все окно владельца, не имеет значения имеет ли он рамку - рамка окна накрывает рамку интерьера. Если интерьер меньше, чем окно, рамка интерьера видима. Несколько интерьеров внутри окна могут быть окружены рамками, как Вы увидите в примере. Следующий код выводит "Hello, World!" в демонстрационном окне, как показано на рис. 2.3.
{ TVGUID05.PAS }
PInterior = ^TInterior; TInterior = object(TView) constructor Init(var Bounds: TRect); procedure Draw; virtual; end;
constructor TInterior.Init(var Bounds: TRect); begin TView.Init(Bounds); GrowMode := gfGrowHiX + gfGrowHiY; end;

procedure TInterior.Draw; begin TView.Draw; WriteStr(4, 2, 'Hello, World!'); end;

constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Integer); var S: string[3]; Interior: PInterior; begin Str(WindowNo, S); { устанавливает номер окна в заголовке } TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber); GetClipRect(Bounds); Bounds.Grow(-1,-1); { интерьер помещается внутри рамки окна } Interior := New(PInterior, Init(Bounds)); Insert(Interior); { добавляет интерьер к окну } end;

Рис. 2.3. TVGUID05 с открытым окном.

+-----------------------------------------------------------------+ | File Window | |*****************************************************************| |*****************************************************************| |*****************************************************************| |*****************************************************************| |*****************************************************************| |+=[ю]Demo Window 1 [ш]=+*****************************************| |*****************************************| |*****************************************| Hello, World! |*****************************************| |*****************************************| |*****************************************| |+=====================-+*****************************************| |*****************************************************************| |*****************************************************************| |*****************************************************************| |*****************************************************************| |*****************************************************************| | Alt-X Exit F4 New Alt-F3 Close | +-----------------------------------------------------------------+

Простой просмотр файлов.

В этом разделе мы добавим несколько новых функций в Ваше окно и поместим в интерьер что-нибудь реальное. Мы добавим методы для чтения текстового файла с диска и отображения его в интерьере.
Примечание: Эта программа будет выводить некоторые "лишние" символы. Не беспокойтесь.
{ TVGUID06.PAS }
const MaxLines = 100; { это произвольное число строк }
var LineCount: Integer; Lines: array[0MaxLines - 1] of PString;
type PInterior = ^TInterior; TInterior = object(TView) constructor Init(var Bounds: TRect); procedure Draw; virtual; end;
procedure TInterior.Draw; { это выглядит безобразно! } var Y: Integer; begin for Y := 0 to Size.Y - 1 do { простой счетчик строк } begin WriteStr(0, Y, Lines[Y]^, $01); { вывод каждой строки } end; end;
procedure ReadFile; var F: Text; S: String; begin LineCount := 0; Assign(F, FileToRead); Reset(F); while not Eof(F) and (LineCount < MaxLines) do begin Readln(F, S); Lines[LineCount] := NewStr(S); Inc(LineCount); end; Close(F); end;
procedure DoneFile; var I: Integer; begin for I := 0 to LineCount - 1 do if Lines[I] <> nil then DisposeStr(Lines[i]); end;

Простые видимые элементы.

Как Вы видите из схемы иерархии на рис. 4.6, все видимые элементы Turbo Vision имеют TObject в качестве предка. TObject - это несколько более, чем общий предок для всех объектов. Сам Turbo Vision в действительности начинается от TView. TView появляется на экране просто как пустой прямоугольник. Не имеет смысла создавать экземпляр TView, если только Вы не хотите создать пустой прямоугольник на экране для прототипирования. Но хотя TView визуально прост, он содержит все основные поля и методы управления экраном Turbo Vision. Любой объект, порожденный от TView, должен обладать двумя возможностями: Во-первых, он рисует себя в любой момент. TView определяет виртуальный метод Draw и каждый объект, порожденный от TView, так же должен иметь метод Draw. Это важно, поскольку часто видимый элемент будет перекрываться другим видимым элементом и когда этот другой элемент удаляется или перемещается, видимый элемент должен иметь возможность показать ту часть, которая была скрыта. Во-вторых, он должен обрабатывать все события, которые приходят к нему. Как замечено в главе 1, программы на Turbo Vision управляются от событий. Это означает, что Turbo Vision управляет вводом от пользователя и передает его в соответствующие объекты программы. Видимые элементы должны знать что делать, когда события воздействуют на них. Обработке событий посвящена глава 5.

Проверить биты.

Часто необходимо проверить, установлен ли определенный флаг. При этом используется операция and. Например, для того, чтобы проверить, может ли окно AWindow быть размещенным черепицей на панели экрана, проверьте флаг ofTileable:
if AWindow.Options and ofTileable = ofTileable then .

Проверка типов и коллекции.

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

Проверьте маску.

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

Псевдоабстрактные методы.

В базовом типе объекта псевдоабстрактный метод имеет минимальные действия. Он почти всегда будет перекрываться потомком, но метод содержит действия по умолчанию для всех объектов в цепи наследования. Пример - TSortedCollection.Compare.

Пул надежности.

Turbo Vision устанавливает фиксированное количество памяти (по умолчанию 4К) в конце кучи, называемое пулом надежности. Если распределение памяти в куче достигает пула надежности, функция Turbo Vision LowMemory возвращает True. Это означает, что последующие распределения ненадежны и могут привести к ошибке. Чтобы использование пула надежности давало эффект, пул должен быть больше, чем максимальное атомарное распределение. Другими словами, он должен быть достаточно большим, чтобы все распределения между проверками LowMemory были успешными; 4К должны удовлетворять большинство программ. (Размер пула надежности устанавливается переменной LowMemSize). Использование традиционного подхода при распределении памяти создает диалоговое окно:
OK := True; R.Assign(20,3,60,10); D := New(Dialog, Init(R, 'My dialog')); if D <> nil then begin with D^ do begin R.Assign(2,2,32,3); Control := New(PStaticText, Init(R, 'Do you really wish to do this?')); if Control <> nil then Insert(Control) else OK := False; R.Assign(5,5,14,7); Control := New(PButton, Init(R, '~Y~es', cmYes)); if Control <> nil then Insert(Control) else OK := False; R.Assign(16,6,25,7); Control := New(PButton, Init(R, '~N~o', cmNo)); if Control <> nil then Insert(Control) else OK := False; R.Assign(27,5,36,7); Control := New(PButton, Init(R, '~C~ancel', cmCancel)); if Control <> nil then Insert(Control) else OK := False; end; if not OK then Dispose(D, Done); end;
Заметим, что переменная OK используется для указания ошибочных распределений. Если произошла ошибка, все диалоговое окно должно быть удалено. Вспомним, что удаление диалогового окна так же удаляет все его подэлементы. С другой стороны, с пулом надежности весь этот блок кода может интерпретироваться как атомарная операция и код изменяется:
R.Assign(20,3,60,10); D := New(Dialog, Init(R, 'My dialog')); with D^ do begin R.Assign(2,2,32,3); Insert(New(PStaticText, Init(R, 'Do you really wish to do this?'))); R.Assign(5,5,14,7); Insert(New(PButton, Init(R, '~Y~es', cmYes))); R.Assign(16,6,25,7); Insert(New(PButton, Init(R, '~N~o', cmNo))); R.Assign(27,5,36,7); Insert(New(PButton, Init(R, '~C~ancel', cmCancel))); end; if LowMemory then begin Dispose(D, Done); OutOfMemory; DoIt := False; end; else DoIt := DeskTop^.ExecView(D) = cmYes;
Поскольку пул надежности достаточно велик для распределения всего диалогового окна, которое требует менее 4К, этот код может предполагать, что все распределения успешны. После того, как диалоговое окно полностью распределится, проверяется переменная LowMemory, и если она True, то все диалоговое окно уничтожается; иначе используется.

"Пустые" события.

"Пустые" события это в действительности мертвые события. Оно перестало быть событием, поскольку полностью обработано. Если поле What в записи события содержит значение evNothing, то эта запись не содержит полезной информации, которая требует обработки. Когда объект Turbo Vision заканчивает обработку события, он вызывает метод ClearEvent, который устанавливает поле What в evNothing, указывая что событие было обработано. Объекты должны просто игнорировать события evNothing, поскольку они уже обработаны другим объектом.

Работа Get.

Когда Вы читаете объект из потока методом Get, вначале вводится номер ID и сканируется список зарегистрированных типов на соответствие. Когда соответствие найдено, запись регистрации предоставляет потоку положение метода Load и VMT объекта. Затем вызывается метод Load для чтения соответствующего количества данных из потока. И снова, Вы просто говорите потоку взять следующий объект и вернуть указатель на его положение. Ваш объект не заботится, из какого потока он был получен. Поток обеспечивает чтение правильного количества данных, используя метод Load объекта. Это показывает как важно зарегистрировать тип до попытки В/В в поток.

Работа Put.

Когда Вы посылаете объект в поток методом Put, поток берет указатель VMT со смещением 0 от объекта и просматривает список типов, зарегистрированных с потоками на соответствие. Когда он находит соответствие, поток выбирает регистрационный номер ID объекта и записывает его в поток. Поток затем вызывает метод Store объекта для записи объекта. Метод Store использует процедуру Write потока, которая записывает правильное число байт в поток. Ваш объект ничего не знает о потоке. Это может быть дисковый файл, EMS память или другой тип потока - Ваш объект просто говорит "Запиши меня в поток" и поток выполняет остальное.

Рамки.

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

Равные экземпляры видимого элемента.

Аналогичная ситуация возникает, когда видимый элемент имеет поле, указывающее на равный ему видимый элемент. Видимый элемент называется равным другому видимому элементу, если оба видимых элемента принадлежат одной группе. Хороший пример - скроллер. Поскольку скроллер знает о двух полосах скроллинга, являющихся элементами окна, которому принадлежит скроллер, он имеет два поля, которые указывают на эти видимые элементы. Как и с видимыми подэлементами, у Вас могут быть проблемы при чтении и записи ссылок на равные видимые элементы в поток. Решение также просто. Методы PutPeerViewPtr и GetPeerViewPtr предназначены для доступа к позиции другого видимого элемента в списке подобъектов владельца. Нужно заботится только о загрузке ссылок на равные видимые элементы, который еще не загружены (т.е. они стоят позже в списке подэлементов и следовательно позже в потоке). Turbo Vision обрабатывает это автоматически, сохраняя трассу всех таких ссылок вперед и разрешая их, когда все подэлементы группы будут загружены. Вам необходимо помнить, что ссылки на равные видимые элементы не действительны до тех пор, пока не будет завершен весь Load. Вследствие этого Вы не должны помещать в метод Load код, который использует подэлементы, зависящие от равных подэлементов, иначе результаты будут непредсказуемы.

Разрешение и запрещение команд.

Иногда необходимо, чтобы некоторые команды были недоступны пользователю определенное время. Например, нет открытых окон, бессмысленно разрешать пользователю генерировать стандартную команду закрытия окна cmClose. Turbo Vision предоставляет способ запретить и разрешить набор команд. Для разрешения или запрещения Вы используете глобальный тип TCommandSet, который является множеством из чисел в диапазоне от 0 до 255. (Вот почему можно запретить только команды в диапазоне 0255). Следующий код запрещает группу из 5 оконных команд:
var WindowCommands: TCommandSet; begin WindowCommands := [cmNext, cmPrev, cmZoom, cmResize, cmClose]; DisableCommands(WindowCommands); end;

Регистрация потока.

В дополнение к определению методов Load и Store для нового объекта, Вы должны так же зарегистрировать новый тип объекта в потоке. Регистрация - это простой двухшаговый процесс, Вы определяете запись регистрации потока и передаете ее в глобальную процедуру RegisterType. Чтобы определить запись регистрации потока, просто следуйте формату. Запись регистрации потока - это запись Паскаля типа TStreamRec, определенная:
PStreamRec = ^TStreamRec; TStreamRec = record ObjType: Word; VmtLink: Word; Load: Pointer; Store: Pointer; Next: Word; end;
Примечание: Все стандартные объекты Turbo Vision зарегистрированы и Вам не нужно делать этого.
По соглашениям Turbo Vision все записи регистрации потоков имеют имена соответствующих объектных типов с заменой начальной Т на R. Так запись регистрации для TDeskTop - RDeskTop и запись регистрации для TMagritte - RMagritte. Абстрактные типы, такие как TObject и TView не имеют регистрационных записей, поскольку никогда не создаются экземпляры этого типа.

Регистрация.

После того, как Вы создали запись регистрации потока, Вы вызываете RegisterType, передавая ему Вашу запись. Так, чтобы зарегистрировать объект TMagritte для использования с потоками, Вы пишите:
const RMagritte: TStreamRec = ( ObjType: 100; VmtLink: Ofs(TypeOf(TMagritte)^); Load: @TMagritte.Load; Store: @TMagritte.Store ); RegisterType(RMagritte);
Теперь Вы можете выводить экземпляры нового типа объекта в любой поток Turbo Vision и читать эти экземпляры из потоков.

Вы не должны забывать регистрировать каждую из этих записей до выполнения ввода/вывода в поток. Простейший способ сделать это - поместить их в одну процедуру и вызвать ее в начале Вашей программы (или в методе Init Вашей программы).
procedure StreamRegistration; begin RegisterType(RCollection); RegisterType(RGraphPoint); RegisterType(RGraphCircle); RegisterType(RGraphRect); end;
Заметим, что Вы зарегистрировали TCollection (используя его запись RCollection - теперь Вы видите почему соглашения об именовании упрощает программирование), хотя Вы не определяли TCollection. Это правило просто: Вы отвечаете за регистрацию всех типов объектов, которые выводятся в поток.

Ресурсы.

Файл ресурсов - это специальный вид потока, в котором объекты (элементы) могут индексироваться с помощью строковых ключей. Вместо порождения файла ресурсов от TStream, TResourceFile содержит поле Stream, связывающее поток с файлом ресурсов. Элементы ресурса доступны через вызов Get(Key), где Key - строковый индекс. Метод Put сохраняет элемент с заданным ключем; метод KeyAt получает индекс данного элемента; Flush записывает все изменения в поток; Delete удаляет элемент с данным ключем и Count возвращает число элементов в файле.

Рисование по требованию.

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

Сколько выводить?

Заметим, что TInterior.Draw выводит такую часть файла, чтобы заполнить интерьер. Иначе, Draw будет тратить большую часть времени на вывод частей файла, которые будут отсекаться границами TInterior. Если видимый элемент тратит на свою прорисовку много времени, Вы можете вызвать GetClipRect. GetClipRect возвращает прямоугольник, который доступен внутри владельца так, что Вам требуется рисовать только эту часть видимого элемента. Например, если у Вас есть сложное диалоговое окно с рядом элементов управления и Вы передвигаете его за пределы экрана, вызовите GetClipRect до рисования, чтобы не перерисовывать те части диалогового окна, которые находятся за пределами экрана.

Скроллинг вверх и вниз.

Очевидно, что просмотр файла не очень-то полезен, если Вы можете просмотреть только несколько первых строк файла. Поэтому давайте изменим интерьер на видимый элемент со скроллингом и добавим в него полосы скроллинга так, чтобы TInteriоr стал окном, скользящим (скроллингуемым) по текстовому файлу. Вы так же можете изменить TDemoWindow, добавив метод MakeInterior, чтобы отделить эту функцию от механизма открытия окна.
{ TVGUID08.PAS }
type PInterior = ^TInterior; { Заметим, что Вы изменяете предка у TInterior } TInterior = object(TScroller) constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar); procedure Draw; virtual; end;
PDemoWindow = ^TDemoWindow; TDemoWindow = object(TWindow) constructor Init(Bounds: TRect; WinTitle: String; WindowNo: Word); procedure MakeInterior(Bounds: TRect); end;
constructor TInterior.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar); begin TScroller.Init(Bounds, AHScrollBar, AVScrollBar); GrowMode := gfGrowHiX + gfGrowHiY; SetLimit(128, LineCount); { горизонтальная и вертикальная границы скроллинга } end;
procedure TInterior.Draw; var Color: Byte; I, Y: Integer; B: TDrawBuffer; begin Color := GetColor(1); for Y := 0 to Size.Y - 1 do begin MoveChar(B, ' ', Color, Size.X); i := Delta.Y + Y; { Delta - смещение скроллинга } if (I < LineCount) and (Lines[I] <> nil) then MoveStr(B, Copy(Lines[I]^, Delta.X + 1, Size.X), Color); WriteLine(0, Y, Size.X, 1, B); end; end;
procedure TDemoWindow.MakeInterior(Bounds: TRect); var HScrollBar, VScrollBar: PScrollBar; Interior: PInterior; R: TRect; begin VScrollBar := StandardScrollBar(sbVertical + sbHandleKeyboard); HScrollBar := StandardScrollBar(sbHorizontal + sbHandleKeyboard); Interior := New(PInterior, Init(Bounds, HScrollBar, VScrollBar)); Insert(Interior); end;
constructor TDemoWindow.Init(Bounds: TRect; WinTitle: String; WindowNo: Word); var S: string[3]; begin Str(WindowNo, S); TWindow.Init(Bounds, WinTitle + ' ' + S, wnNoNumber); GetExtent(Bounds); Bounds.Grow(-1, -1); MakeInterior(Bounds); end;

Рис. 2.5. Просмотр файла со скроллингом.

+-----------------------------------------------------------------+ | File Window | |+------------- Demo Window 1 --------------+*********************| {*****************************************|*********************| { |*********************| { Turbo Pascal 6.0 |*********************| { Demo program from the Turbo Vision Gui|*********************| { |*********************| { Copyright (c) 1990 by Borland Internat|*********************| { |*********************| {*****************************************|*********************| +=[ю]== Demo Window 3 ==[ш]=+*****************| program TVGUID08; | AVScrollBar: PScrollBar);ш*****************| |begin #Window 2 -----+**| uses Objects, Driv| TScroller.Init(Bounds, AH# |**| | GrowMode := gfGrowHiX + g#: Integer; |**| |+------------------| Options := Options or ofF#ray[0MaxLine|**| |*******************| SetLimit(128, LineCount);# |**| |*******************|end; # |**| |*******************| #object(TApplic|**| |*******************|procedure TInterior.Draw; юre HandleEvent|**| |*******************|var #re InitMenuBar|**| |*******************| Color: Byte; щre InitStatusL|**| |*******************+=<ю######################>-+--------------+**| |*****************************************************************| | Alt-X Exit F4 New Alt-F3 Close | +-----------------------------------------------------------------+

Вертикальная и горизонтальная полосы скроллинга инициализируются и вставляются в группу, а затем передаются в TScroller в его инициализации. "Скроллер" - это видимый элемент, спроектированный для отображения части большого виртуального видимого элемента. Скроллер и его полосы скроллинга объединяются для создания скользящего видимого элемента с незначительными усилиями от Вас. Все, что Вам нужно сделать - это создать метод Draw для скроллера так, чтобы он отображал соответствующую часть виртуального видимого элемента. Полосы скроллинга автоматически управляют значениями Delta.X (колонка, с которой начинается вывод) и Delta.Y (строка, с которой начинается вывод) скроллера. Вы должны перекрыть метод Draw в TScroller. Значения Delta изменяются в соответствии с полосами скроллинга. Метод Draw вызывается каждый раз, когда изменяется Delta.

Сложные видимые элементы.

Вы уже знаете о наиболее важном элементе, порождаемом от TView - ТGroup. TGroup и его потомки называются группами. Видимые элементы не наследуемые от TGroup, называются терминальными видимыми элементами. Группа - это просто пустое окно, которое содержит и управляет другими видимыми элементами. Технически - это видимый элемент и, следовательно, отвечает за все, что должен уметь любой видимый элемент: управлять прямоугольной областью экрана, визуализировать себя в любое время и обрабатывать события в своей области экрана. Отличие в том, как он реализует эти функции: большинство из них обрабатывается видимыми подэлементами.

События и команды.

Большинство событий в конечном итоге преобразуются в команды, например, отметка мышкой элемента в строке статуса генерирует событие от мышки. Когда оно поступает в объект "строка статуса", этот объект откликается на событие от мышки, генерируя событие-команду со значением поля Command, определяемым командой связанной с элементом строки статуса. Нажатие мышкой на Alt-X Exit генерирует команду cmQuit, которую программа интерпретирует как инструкцию закрытия системы и завершения.

События определенные пользователем.

Как только Вы ознакомитесь с Turbo Vision и событиями, Вы захотите определить новую категорию событий, используя старшие биты поля What записи события. По умолчанию Turbo Vision направляет такие события как общие события. Но Вам может понадобиться сделать общие события активными или позиционированными и Turbo Vision предоставляет механизм, позволяющий сделать это. Turbo Vision определяет две маски Positional и Focused, которые содержат биты соответствующие событиям в поле What записи события, которые должны быть направлены как позиционированные или активные соответственно. По умолчанию Positional содержит все биты evMouse, а Focused содержит evKeyBoard. Если Вы определяете другой бит в новом виде события, которое Вы хотите направить как позиционированное или активное, Вы просто прибавляете бит к соответствующей маске. (Манипуляция битами в маске объясняется в главе 10).

События от клавиатуры.

События от клавиатуры намного проще. Когда Вы нажимаете клавишу, Turbo Vision генерирует событие evDown, которое содержит информацию о нажатой клавише.

События от мышки.

Существуют 4 вида событий от мышки: нажатие или отпускание любой кнопки, изменение позиции или "авто" событие. При нажатии на кнопку мышки генерируется событие evMouseDown. Когда кнопка отпускается генерируется событие evMouseUp. Перемещение мышки генерирует событие evMouseMove. Если Вы держите кнопку нажатой, Turbo Vision периодически генерирует событие evMouseAvto, позволяяя Вашей программе такие действия как повторяющийся скроллинг. Все записи событий от мышки включают позицию мышки, так что объект, обрабатывающий событие знает где находилась мышка в этот момент.

События сообщений.

События сообщений бывают 3 видов: команды, общие сообщения и пользовательские сообщения. Они отличаются обработкой как будет объяснено позднее. Команды помечаются в поле What через evCommand, общие сообщения через evBroadcast и пользовательские сообщения константой определенной пользователем.

События.

Событие - это что-то, на что Ваша программа должна отреагировать. События могут приходить от клавиатуры, от мышки или от других частей Turbo Vision. Например, нажатие клавиши - это событие такое же, как и нажатие кнопки мышки. События поступают в очередь внутри Turbo Vision по мере их появления и затем обрабатываются обработчиком событий. Объект TApplication, который является ядром Вашей программы, содержит обработчик событий. Через механизм, который будет описан позднее, события, которые не обрабатываются TApplication, передаются в другие видимые элементы до тех пор, пока не найдется видимый элемент, который обработает событие, или пока не возникнет ошибка "отказ от события". Например, клавиша F1 вызывает справочную систему. Если какой-то видимый элемент не имеет собственной части в справочной системе (как может случиться в контекстно-ориентированной справочной системе), клавиша F1 обрабатывается обработчиком событий главной программы. С другой стороны, алфавитно-цифровые клавиши или клавиши редактирования должны быть обработаны видимым элементом, который в данный момент активен; т.е. видимым элементом, который в данный момент взаимодействует с пользователем. События детально объяснены в главе 5.

Соглашения об именовании.

Все стандартные типы объектов в Turbo Vision имеют набор имен, использующих мнемонические префиксы. Первая буква идентификатора говорит Вам используете ли Вы тип объекта, указатель на него, его регистрационную запись в потоке или его палитру цветов. - Тип объекта начинается с Т: TObject. - Указатели на объекты начинаются с Р: PObject = ^TObject. - Регистрационные записи потоков начинаются с R: RObject. - Палитры цветов начинаются с С: CObject. Все константы Turbo Vision имеют двухсимвольные мнемонические префиксы, указывающие их использование.
Таблица 11.1. Префиксы констант Turbo Vision.
------------------------------------------------- Префикс Назначение Пример ------------------------------------------------- ap Палитра программы apColor bf Флаг кнопки bfNormal cm Команда cmQuit co Код коллекции coOverFlow dm Режим перемещения dmDragGrow ev Константа события evMouseDown gf Флаг режима перемещения gfGrowLoX hе Контекст помощи hеNoContent kb Константа клавиатуры kbAltX mb Кнопка мышки mbLeftButton of Флаг опций ofTopSelect sb Полоса скроллинга sbLeftArrow sf Флаг состояния sfVisible sm Режим экрана smMono st Код потока stOK wf Флаг окна wfMove wn Номер окна wnNoNumber wp Палитра окна wpBlueWindow -------------------------------------------------

Сохранение и загрузка панели экрана.

Если Вы сохраняете панель экрана в потоке, панель экрана будет сохранять все свое содержимое: всю среду панели экрана, включая все текущие видимые элементы. Если Вы хотите разрешить пользователю сохранять панель экрана, Вам необходимо убедиться, что все возможные видимые элементы имеют соответствующие видимые элементы Store и Load, что все видимые элементы зарегистрированы, поскольку пользователь может сохранить панель экрана в любой момент. Чтобы сделать это Вы можете использовать подобный код:
procedure TMyApp.RestoreDeskTop; var SaveFile: TBufStream; Temp: PDeskTop; begin SaveFile.Init('T.DSK', stOpen, 1024); Temp := PDeskTop(SaveFile.Get); SaveFile.Done; if Temp <> nil then begin Dispose(DeskTop, Done); DeskTop := Temp; Append(DeskTop); DeskTop^.DrawView; end; if SaveFile.Status <> 0 then ErrorReadingFile; end;
Вы можете сделать следующий шаг и сохранять и восстанавливать всю программу. Объект TApplication может сам сохранять и восстанавливать себя.

Сообщения между видимыми элементами.

Если Вы тщательно проанализировали Вашу ситуацию, решили, что программа спроектирована правильно и что Вам не требуется создавать промежуточные элементы, Вы можете реализовать простое взаимодействие между двумя видимыми элементами. До того, как один видимый элемент сможет взаимодействовать с другим, Вы можете определить где находится другой видимый элемент и вероятно даже убедиться, что другой видимый элемент существует в данное время. Вначале пример. Модуль Stddlg содержит диалоговое окно TFileDialog (этот видимый элемент открывается в интегрированной среде, когда Вы хотите загрузить новый файл). TFileDialog имеет TFileList, который показывает справочник на диске, а файл InputLine отображает текущий файл для загрузки. Каждый раз, когда пользователь выбирает другой файл в FileList, FileList должен сказать FilеInputLine вывести новое имя файла. В этом случае FileList может быть уверен, что FileInputLine существует, поскольку оба инициализированы внутри одного объекта FileDialog. Как FileList сможет сказать FileInputLine, что пользователь выбрал новое имя? FileList создает и посылает сообщение. FileList.FocusItem посылает сообщение, а FileInputLine.HandleEvent получает его:
procedure TFileList.FocusItem(Item: Integer); var Event: TEvent; begin TSortedListBox.FocusItem(Item); { вначале вызывает наследуемый метод } Message(TopView, evBroadcast, cmFileFocused, List^.At(Item)); { TopView указывает текущий модальный видимый элемент } end;
procedure TFileInputLine.HandleEvent(var Event:TEvent); var Name: NameStr; begin TInputLine.HandleEvent(Event); if (Event.What = evBroadcast) and (Event.Command = cmFileFocused) and (State and sfSelected = 0) then begin if PSearchRec(Event.InfoPtr)^.Attr and Directory <> 0 then Data^ := PSearchRec(Event.InfoPtr)^.Name + '\' + PFileDialog(Owner)^.WildCard else Data^ := PSearchRec(Event.InfoPtr)^.Name; DrawView; end; end;
Message - это функция, которая генерирует событие сообщения и возвращает указатель на объект (если есть), который обработал это событие. Заметим, что TFileList.FocusItem использует расширенный синтаксис Turbo Pascal (директива компилятора $X+), чтобы использовать функцию Message как процедуру, поскольку результат, возвращаемый Message, не нужен.

Сообщения об ошибках.

До того, как метод Valid вернет False, он должен выдать пользователю информацию об ошибке, поскольку видимый элемент не появится на экране. Это делал ReportError в предыдущем примере. Обычно он вызывает диалоговое окно с сообщением. Каждый отдельный видимый элемент отвечает за выдачу сообщения о любых ошибках, поскольку программа не знает как проверять каждую из возможных ситуаций. Это важное достижение в технике программирования, поскольку позволяет Вашей программе работать, как если бы все было правильно вместо того, чтобы всегда смотреть что может быть неправильным. Групповые объекты, включая программу, не беспокоятся о проверке ошибок за исключением проверки, если какой-либо из их видимых элементов был неверен. В этом случае группа просто удаляет себя и свои подэлементы и указывает своему владельцу, что была неправильной. Группа может предполагать, что ее неправильный подэлемент уже сообщил пользователю о проблеме. Использование Valid позволяет создавать окна и диалоговые окна, рассматривая их как атомарные операции. Каждый подэлемент, который создает окно, может быть создан без проверки на ошибку; если констрактор неверен, он просто установит Valid в False. Если любой подэлемент окна неверен, все окно возвращает False при проверке. ValidView будет освобождать окно и возвращать nil. Все, что требуется сделать - это проверить результат ValidView.

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

Используемые объекты: TView, TGroup, TDialog, TCluster, TCheckBoxes, TRadioButtons, TLabel, TInputLine. Диалоговое окно - это просто специальный вид окна. В действительности TDialog наследуется от TWindow и хотя Вы можете интерпретировать его как просто другое окно, обычно Вы будете делать некоторые вещи по-другому. В Вашей демонстрационной программе Вы добавите новый элемент меню, который генерирует команду, открывающую диалоговое окно, добавите метод в Вашу программу, который знает как это делать и добавите строку в метод HandleEvent Вашей программы, чтобы связать команду с действием. Заметим, что Вам не требуется порождать новый тип объекта от TDialog, как Вы делали с TWindow (чтобы создать TDemoWindow). Вместо создания специального типа диалогового окна Вы добавляете "разумность" в программу: вместо создания объекта типа "диалоговое окно", который знает что Вы хотите делать, Вы создаете общее диалоговое окно и говорите ему что он должен сделать. Вам редко потребуется создавать порожденный тип от TDialog, поскольку отличие между диалоговыми окнами только в их содержимом.
{ TVGUID11.PAS }
const cmNewDialog = 200;
procedure TMyApp.InitMenuBar; var R: TRect; begin GetExtent(R); R.B.Y := R.A.Y + 1; MenuBar := New(PMenuBar, Init(R, NewMenu( NewSubMenu('~F~ile', hcNoContext, NewMenu( NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext, NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext, NewLine( NewItem('E~x~it', 'Alt-X', kbAltX, cmQuit, hcNoContext, nil))))), NewSubMenu('~W~indow', hcNoContext, NewMenu( NewItem('~N~ext', 'F6', kbF6, cmNext, hcNoContext, NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcNoContext, NewItem('~D~ialog', 'F2', kbF2, cmNewDialog, hcNoContext, nil)))), nil)) ))); end;
procedure TMyApp.NewDialog; var Dialog: PDialog; R: TRect; begin R.Assign(0, 0, 40, 13); R.Move(Random(39), Random(10)); Dialog := New(PDialog, Init(R, 'Demo Dialog')); DeskTop^.Insert(Dialog); end;
procedure TMyApp.HandleEvent(var Event: TEvent); begin TApplication.HandleEvent(Event); if Event.What = evCommand then begin case Event.Command of cmNewWin: NewWindow; cmNewDialog: NewDialog; else Exit; end; ClearEvent(Event); end; end;

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

+= [ю]=== Demo Dialog Box =====+ | | | | | | | | | | | | | | +==============================+

Существует несколько различий между диалоговым окном и предыдущими окнами: - Цвет по умолчанию диалогового окна серый вместо синего. - Диалоговое окно не может изменять размер. - Диалоговое окно не имеет номера. Заметим, что Вы можете закрыть диалоговое окно, отметив его закрывающую кнопку или отметив элемент Alt-F3 в строке статуса или нажав клавишу ESC. По умолчанию клавиша ESC удаляет диалоговое окно. Это пример, так называемого, диалогового "немодального" окна (без режимов). Диалоговые окна обычно модальные, которые определяют режим действия. Обычно, когда Вы открываете диалоговое окно, активным является только это окно: это модальный видимый элемент. Отметка других окон или меню не будет вызывать никаких действий до тех пор, пока Вы находитесь в режиме диалогового окна. Иногда Вам может понадобиться немодальное диалоговое окно, но в большинстве случаев Вы будете работать с модальными диалоговыми окнами (модальные видимые элементы обсуждены в главе 4).

Создание экземпляра.

Создание экземпляра объекта обычно связано с объявлением переменной, статической или динамической:
MyScrollBar: TScrollBar; SomeButton: PButton;
MyScrollBar будет инициализироваться значениями полей по умолчанию в TScrollBar.Init. Это можно посмотреть в разделе TScrollBar.Init главы 13. Поскольку TScrollBar порожден от TView, TScrollBar.Init вызывает TView.Init, чтобы установить поля, унаследованные от TView. Аналогично TView.Init наследуется от TObject, поэтому он вызывает констрактор TObject для распределения памяти. TObject не имеет предка. Объект MyScrollBar сейчас имеет значения полей по умолчанию, которые Вы можете изменить. Он так же имеет все методы TScrollBar плюс методы (возможно перекрытые) от TView и TObject. Чтобы использовать MyScrollBar, Вам нужно знать что делают его методы, особенно HandleEvent и Draw. Если требуемая функциональность не определена в TScrollBar, Вам требуется породить новый тип.

Создание кластера.

Не существует причин для того, чтобы создавать экземпляр от TCluster. Поскольку процесс создания кластера независимых кнопок аналогичен созданию кластера зависимых кнопок, Вам требуется детально просмотреть это процесс только однажды. Добавим следующий код в метод TMyApp.NewDialog после создания диалогового окна, но до добавления кнопок. Вставим кнопки в последнюю очередь в том порядке, в котором они должны обходиться с помощью Tab.
+----------------+ | [ ] HVarti | | [ ] Tilset | | [ ] Jarlsberg | +----------------+
var B: PView; R.Assign(3, 3, 18, 6); B := New(PChecBoxes, Init(R, NewSItem('~H~varti', NewSItem('~T~ilset', NewSItem('~J~arsberg', nil))) )); Insert(B);
Инициализация очень проста. Вы устанавливаете прямоугольник, в котором находятся элементы (не забудьте оставить место для самих независимых кнопок), а затем создаете связанный список указателей на строки, завершаемый nil, которые будут показаны в следующих независимых кнопках.

Создание коллекции.

Создать коллекцию так же просто, как определить тип данных, который Вы хотите хранить. Предположим, что Вы консультант и хотите хранить и использовать табельный номер, имя и номер телефона каждого из Ваших клиентов. Для начала определите объект клиента (TClient), который будет храниться в коллекции:
{Не забудьте определить указатель на каждый новый тип объекта} type PClient = ^TClient; TClient = object(TObject) Account, Name, Phone: PString; constructor Init(NewAccount, NewName, NewPhone: String); destructor Done; virtual; end;
Затем Вы реализуете методы Init и Done для распределения и освобождения данных клиента. Заметим, что поля объекта типа PString, так что память распределяется только под используемую часть строки. Функции NewStr и DisposeStr обрабатывают динамические строки очень эффективно.
constructor TClient.Init(NewAccount, NewName, NewPhone: String); begin Account := NewStr(NewAccount); Name := NewStr(NewName); Phone := NewStr(NewPhone); end;
destructor TClient.Done; begin Dispose(Account); Dispose(Name); Dispose(Phone); end;
TClient.Done вызывается автоматически для каждого клиента при удалении всей коллекции. Сейчас Вы создадите коллекцию для хранения Ваших клиентов и вставите записи клиентов в нее. Тело главной программы:
{ TVGUID17.PAS } var ClientList: PCollection;
begin ClientList := New(PCollection, Init(50, 10)); with ClientList^ do begin Insert(New(PClient, Init('90-167', 'Smith, Zelda', '(800) 555-1212'))); Insert(New(PClient, Init('90-160', 'Johnson, Agatha', '(302) 139-8913'))); Insert(New(PClient, Init('90-177', 'Smitty, John', '(406) 987-4321'))); Insert(New(PClient, Init('90-160', 'Anders Smitty', '(406) 111-2222'))); end; PrintAll(ClientList); SearchPhone(ClientList, '(406)'); Dispose(ClientList, Done); end.
Заметьте как легко создать коллекцию. Первый оператор распределяет новую TCollection с именем ClientList, который имеет начальный размер 50 клиентов. Если в ClientList вставлено более 50 клиентов, ее размер увеличивается с шагом 10 клиентов. 2 последних оператора создают новый объект клиента и вставляют его в коллекцию. Dispose освобождает всю коллекцию. Вы нигде не говорили коллекции, какого вида данные она будет хранить - ей только передан указатель.

Создание новых команд.

Заметим, что команды cmQuit и cmClose, которые Вы связали с элементами строки статуса, являются стандартными командами Turbo Vision, поэтому Вам не требуется определять их. Для того, чтобы использовать собственные команды, Вы просто объявляете Ваши команды как константные значения. Например, Вы можете определить новую команду, чтобы открыть новое окно:
const cmNewWin = 199;
Примечание: Turbo Vision резервирует некоторые константы для собственных команд. См. "Определение команд" в главе 5.
Затем Вы можете связать эту команду с горячей клавишей и с элементом строки статуса.
StatusLine := New(PStatusLine, Init(R, NewStatusDef(0, $FFFF, NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit, NewStatusKey('~F4~ New', kbF4, cmNewWin, { включение новой команды } NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose, nil))), nil) ));
Синтаксис инициализации строки статуса - это хорошее введение в инициализацию меню, которая более сложна.

Создание ресурса.

Создание файла ресурса выполняется в 4 этапа. Вам необходимо открыть поток, инициализировать файл ресурса с этим потоком, сохранить один или более объектов с их ключами и закрыть ресурс. Следующий код создает простой файл ресурса MY.REZ, содержащий один ресурс: строку статуса с ключем 'Waldo':
program BuildResourse;
uses Drivers, Objects, Views, App, Menus;
type PHaltStream = ^THaltStream; THaltStream = object(TBufStream) procedure Error(Code, Info: Integer);virtual; end;
var MyRez: TResourceFile; MyStrm: PHaltStream;
procedure THaltStream.Error(Code, Info: Integer); begin Writeln('Stream error: ', Code, ' (', Info, ')'); Halt(1); end;
procedure CreateStatusLine; var StatusLine: PStatusLine; begin StatusLine := New(PStatusLine, Init( 0,$FFFF, NewStatusItem('~Alt-X~ Exit', AltX, cmQuit, NewStatusItem('~F3~ Open', F3Key, cmNewDlg, NewStatusItem('~F5~ Zoom', F5Key, cmZoom, NewStatusItem('~Alt-F3~ Close', AltF3, cmClose, nil)))) )); MyRez.Put(StatusLine, 'Waldo'); Dispose(StatusLine, Done); end;
begin MyStrm := New(PHaltStream, Init('MY.REZ', stCreate, 1024)); MyRez.Init(MyStrm); CreateStatusLine; MyRez.Done; end.

Создание списков строк.

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

Списки строк.

TStringList реализует специальный вид строкового ресурса, в котором к строкам можно обращаться через числовой индекс, используя метод Get. Поле Count содержит число строк в объекте. TStringList упрощает многоязыковые тектовые программы. Списки строк можно прочитать из потока, используя констрактор Load. Чтобы создать или добавить в список строк, используйте TStrListMaker. TStringList предоставляет доступ только к существующему списку строк с числовой индексацией. TStrListMaker предоставляет метод Put для добавления строки в список строк, а метод Store сохраняет список строк в потоке.

Список строк.

В дополнение к стандартному механизму ресурса, Turbo Vision предоставляет пару специализированных объектов для управления списками строк. Список строк - это специальный ресурс, который позволяет Вашей программе обращаться к строковым ресурсам по номерам (обычно представленными целыми константами) вместо строковых ключей. Это позволяет программе сохранять строки в файле ресурса для упрощения настройки. Например, IDE Turbo Pascal использует объект списка строк для всех сообщений об ошибках. Это означает, что программа может просто вызвать сообщение об ошибке по номеру и различные версии в различных странах будут выбирать различные строки из их ресурсов. Объект списка строк спроектирован не очень гибко, но очень быстр и удобен при правильном использовании. Объект TStringList используется для доступа к строкам. Чтобы создать список строк, необходимо использовать объект TStrListMaker. Записи регистрации для этих объектов имеют одинаковый номер типа объекта. Объект списка строк не имеет метода Init. Используется единственный констрактор - метод Load, поскольку списки строк существуют только в файлах ресурса. Аналогично, поскольку список строк - это ресурс только для чтения, он имеет функцию Get, но не имеет процедуры Put.

Стандартное оформление окон.

Окно Turbo Vision - это объект со встроенной в него возможностью реагировать на ввод пользователя без написания специального кода. Окна Turbo Vision уже знают как открываться, изменять размер, перемещаться и закрываться. Но Вы не пишите в окно Turbo Vision. Окно Turbo Vision содержит то, что содержат и чем управляют другие объекты: эти объекты отображают себя на экране. Окно управляет видимыми элементами и функции Вашей программы - это видимые элементы, которые окно содержит и которыми управляет. Видимые элементы, создаваемые Вами, предоставляют большую гибкость в том, где и как они появляются. Как же Вам комбинировать стандартные окна с теми элементами, которые Вы хотите поместить в них? Снова и снова запомните, что Вы получили мощную оболочку для построения и использования. Начните со стандартного окна, затем добавьте требуемые Вам возможности. Как только Вы просмотрите несколько следующих примеров, Вы увидите как просто наращивается программа вокруг представленной Turbo Vision основы. Следующий код инициализирует окно и подсоединяет его к панели экрана. Не забудьте добавить новые методы к объявлению Вашего типа TMyApp. Заметим, что Вы опять определяете новый тип (TDemoWindow) не добавляя полей и методов к типу предка. Как и раньше Вы просто создаете основу, которую Вы сможете быстро достраивать. Вы добавите новые методы при необходимости.
{ TVGUID04.PAS }
uses Views;
const WinCount: Integer = 0; { инициализация счетчика окон }
type PDemoWindow = ^TDemoWindow; { заметим, что Вы всегда объявляете тип указателя для каждого нового объектного типа } TDemoWindow = object(TWindow) { определение нового типа окна } end;
procedure TMyApp.NewWindow; var Window: PDemoWindow; R: TRect; begin Inc(WinCount); R.Assign(0, 0, 26, 7); { установка начального размера и позиции } R.Move(Random(58), Random(16)); { случайное перемещение по экрану } Window := New(PDemoWindow, Init(R, 'Demo Window', WinCount)); DeskTop^.Insert(Window); { вывести окно на панель экрана } end;
procedure TMyApp.HandleEvent(var Event: TEvent); begin TApplication.HandleEvent(Event); { действует как предок } if Event.What = evCommand then begin case Event.Command of { но откликается на дополнительные команды } cmNewWin: NewWindow; { определяет действие для команды cmNewWin } else Exit; end; ClearEvent(Event); { очищает событие после обработки } end; end;
Чтобы использовать это окно в программе, Вам необходимо связать программу cmNewWin с опцией меню или горячей клавишей строки статуса, как Вы делали ранее. Когда пользователь вызывает cmNewWin, Turbo Vision пересылает команду в TMyApp.HandleEvent, который реагирует, вызывая TMyApp.NewWindow.

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

Модуль StdDlg содержит предопределенное диалоговое окно, называемое TFileDialog. Вы используете это диалоговое окно в интегрированной среде, когда открываете файл. TFileDialog использует ряд других объектов, которые могут быть полезны, так же из модуля StdDlg:
TFileInputLine = object(TInputLine) TFileCollection = object(TSortedCollection) TSortedListBox = object(TListBox) TFileList = object(TSortedListBox) TFileInfoPane = object(TView)
Поскольку исходный код для модуля Dialogs доступен, мы не описываем эти объекты детально.

Статические методы.

Статический метод не может быть перекрыт. Порожденный тип может определить метод с тем же именем, используя совершенно другие аргументы и тип возврата, если необходимо, но статические методы не поддерживают полиморфизм. Это наиболее критично, когда Вы вызываете методы динамических объектов. Например, если PGeneric - переменная указателя типа PView, Вы можете назначить ему указатели любого типа из его иерархии. Однако когда Вы делаете ссылку по переменной и вызываете статический метод, вызванный метод всегда будет из TView, поскольку этот тип указателя определен во время компиляции. Другими словами, PGeneric^.StaticMethod всегда эквивалентен TView.StaticMethod, даже если Вы назначаете PGeneric указатель другого типа. Например TView.Init.

Статический текст.

TStaticText - это видимый элемент, который просто отображает строку, переданную в него. Строка - это слово, располагаемое внутри прямоугольника видимого элемента с переносом. Текст будет центрироваться, если строка начинается с Ctrl-C и строка может быть разбита с помощью Ctrl-M. По умолчанию текст не может активизироваться и объект не получает данных из записи данных.

Объекты TStaticText - это простые видимые элементы, используемые для отображения фиксированных строк, предоставляемых полем Text. Они игнорируют любые события, посланные им. Тип TLabel добавляет видимому элементу свойства хранения текста, известного как метка, который может быть выбран с помощью мышки, клавиш курсора или короткого нажатия Alt-клавиша. Дополнительное поле Link связывает метку с другим видимым элементом, обычно управляемым видимым элементом, который обрабатывает все события метки. Выбор метки выбирает связанный элемент управления, а выбор связанного элемента управления подсвечивает метку.

Строка статуса.

TApplication.InitStatusLine устанавливает видимый элемент TStatusLine, вызывая StatusLine для определения и отображения горячих клавиш. StatusLine выводится, начиная с левого края экрана и любая часть нижней строки экрана, не требуемая для элементов строки статуса, свободна для других видимых элементов. TStatusLine связывает горячие клавиши с командами и сами элементы могут быть отмечены мышкой.
Примечание: Горячие клавиши - это комбинации клавиш, которые действуют как элементы меню или строки статуса.
TVGUID02.PAS создает строку статуса, перекрывая TApplication.InitStatusLine:
procedure TMyApp.InitStatusLine; var R: TRect; { хранит границы строки статуса } begin GetExtent(R); { устанавливает R в координаты всего} { экрана } R.A.Y := R.B.Y - 1; { передвигает вершину на 1 строку } { выше нижней } StatusLine := New(PStatusLine, Init(R, { создает строку } { статуса } NewStatusDef(0, $FFFF, { устанавливает диапазон контекстного } { Help } NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit, { определяет элемент } NewStatusKey('~Alt-F3~ Close', kbAltF3, cmClose, { другой } nil)), { больше нет клавиш } nil) { больше нет определений } )); end;
Примечание: Не забудьте добавить
procedure InitStatusLine; virtual;
в объявление TMyApp.
Инициализация - это последовательность вложенных вызовов стандартных фунций Turbo Vision NewStatusDef, NewStatusKey и NewStatusBar (детально описаны в главе 14). TVGUID02 определяет строку статуса для отображения диапазона контекстной справочной информации от 0 до $FFFF и связывает стандартную команду cmQuit с клавишей Alt-X, а стандартную команду cmClose с клавишей Alt-F3. (Команды Turbo Vision - это константы. Их идентификаторы начинаются с cm.) Вы можете заметить, что в отличие от TMyApp.Init, метод InitStatusLine не вызывает метод, который он перекрывает - TApplication.InitStatusLine. Причина проста: обе программы устанавливают строки статуса, которые охватывают одинаковый диапазон контекстной справочной системы и назначают его одной переменной. В TApplication.InitStatusLine нет ничего, что позволило бы TMyApp.InitStatusLine выполнить работу более просто и, кроме того, Вы потратите время и память на ее вызов. Последняя строка, выводимая в строке команд этой инициализации - "Alt-F3 Close". Часть строки, заключенная в "~", будет подсвечиваться на экране. Пользователь может отметить мышкой любую часть строки для активации команды. Когда Вы выполняете TVGUID02, Вы заметите, что элемент статуса Alt-F3 не подсвечен и отметка его мышкой не имеет эффекта. Это происходит потому, что команда cmClose по умолчанию запрещена, и элементы, которые генерируют запрещенные команды, так же запрещены. После того, как Вы откроете окно, cmClose и элемент статуса будут активированы. Ваша строка статуса работает сразу после инициализации StatusLine, поскольку Вы используете только предопределенные команды (cmQuit и cmClose.) StatusLine может обрабатывать ввод пользователя без Вашего вмешательства.

Строка ввода.

Существует еще один тип элемента управления, который Вы можете добавить в диалоговое окно: элемент для редактирования входной строки, называемый строкой ввода. В действительности работа строки ввода черезвычайно сложна, но с Вашей точки зрения как программиста, TInputLine - очень простой для использования объект. Добавим следующий код после кода, назначающего метку зависимым кнопкам и до выполнения диалогового окна:
{ TVGUID15.PAS } R.Assign(3, 8, 37, 9); B := New(PInputLine, Init(R, 128)); Insert(B); R.Assign(2, 7, 24, 8); Insert(New(PLabel, Init(R, 'Delivery instructions', B)));
Установка строки ввода проста: Вы назначаете прямоугольник, который определяет длину строки ввода на экране. Необходим еще один параметр для определения максимальной длины редактируемой строки. Эта длина может превышать отображаемую длину, поскольку объект TInputLine знает как выполнять скроллинг строки. По умолчанию строка ввода может обрабатывать клавиши, команды редактирования, выбор и движение с помощью мышки.
Рис. 2.10. Диалоговое окно со строкой ввода.
+=[ю]======= Demo Dialog Box =============+ | | | Cheeses Consistency | | +----------------+ +--------------+ | | | [ ] HVarti | | [*] Solid | | | | [ ] Tilset | | [ ] Runny | | | | [ ] Jarlsberg | | [ ] Melted | | | +----------------+ +--------------+ | | | | Delivery instructions | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | | OK m Cancel m | | ^^^^^^^^ ^^^^^^^^ | +==========================================+
Строка ввода так же имеет метку для ясности, поскольку непомеченная строка ввода может быть еще более непонятной для пользователя, чем непомеченный кластер.

Строки статуса.

Объект TStatusLine предназначен для отображения статуса и подсказок обычно в нижней строке экрана. Строка статуса имеет высоту 1 символ и длину до ширины экрана. Этот объект обеспечивает динамическое отображение, реагируя на события программы. Элементы строки статуса можно выбрать мышкой или горячей клавишей. Большинство программ начинают работу становясь владельцами объектов TMenuBar, TDeskTop и TStatusLine. Дополнительные поля TStatusLine обеспечивают указатель Items и указатель Defs. Поле Items указывает на текущий связанный список записей TStatusItem. Он содержит отображаемые строки, связь с горячими клавишами и ассоциированное слово Command. Поле Defs указывает на связанный список записей PStatusDef, используемый для определения текущей контекстной подсказки. TStatusLine может инициализироваться, используя TApplication.InitStatusLine.

Строки ввода.

TInputLine - это специализированный видимый элемент, который предоставляет строковый редактор строки ввода. Он обрабатывает все обычные клавиши управления курсором, удаление и вставку. Чтобы отметить блок текста, может использоваться мышка.

Сущность использования потоков.

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

Связывание команд.

Когда Вы создаете элемент строки статуса или меню, Вы связываете с ним команду. Когда пользователь выбирает этот элемент, генерируется запись события с полем What установленным в evCommand и полем Command установленным в значение связанной команды. Команда может быть стандартной командой Turbo Vision или командой определенной Вами. В тот момент, когда Вы связываете Вашу команду с элементом меню или строки статуса, Вы также можете связать ее с горячей клавишей. Т.о. пользователь может вызвать команду, нажав клавишу короткого набора или мышкой. Примечание: Важно запомнить что определение команды не указывает какое действие должно быть выполнено, когда команда появляется в записи события. Вы должны сказать соответствующим объектам, как откликаться на эту команду.

TApplication App

+----------+ | TObject | +----+-----+ +----+-----+ | TView | +----+-----+ +----+-----+ | TGroup | +-+--+---+-+ +---------+ | +---------+ +----+----+ +----+-----+ +----+-----+ | TWindow | | TDeskTop | | TProgram | +----+----+ +----------+ +----+-----+ +----+----+ +=====+========+ | TDialog | | TApplication | +---------+ +==============+
TApplication просто наследуется от TProgram и отличается от TProgram только констрактором и дестрактором. TApplication.Init инициализирует все подсистемы Turbo Vision (управление памятью, видео, событиями, системными ошибками и списками историй) и затем вызывает TProgram.Init. Аналогично TApplication.Done вначале вызывает TProgram.Done, а затем уничтожает все подсистемы Turbo Vision. Обычно Вы будете наследовать свои программы от TApplication. Если Вам потребуется другая последовательность инициализации подсистем и их закрытия, Вы можете наследовать Вашу программу от TProgram и вручную инициализировать и закрывать подсистемы Turbo Vision.
Методы
Init constructor Init; Фактическая реализация TApplication.Init показана ниже:
constructor TApplication.Init; begin InitMemory; InitVideo; InitEvents; InitSysError; InitHistory; TProgram.Init; end;
См. так же: TProgram.Init
Done destructor Done; virtual; Реализация TApplication.Done показана ниже:
destructor TApplication.Done; begin TProgram.Done; DoneHistory; DoneSysError; DoneEvents; DoneVideo; DoneMemory; end;

TBackground App

+-------------+ | TObject | +------+------+ +------+------+ | TView | +------+------+ +======+======+ | TBackGround | +=============+
TBackground - это простой видимый элемент, содержащий однотонно заполненный прямоугольник. Обычно он принадлежит TDeskTop.
Поля
Pattern Pattern: Char; Только чтение Это битовый шаблон для фона видимого элемента.
Методы
Init constructor Init(var Bounds: TRect; APattern: Char); Создает объект TBackground с границами Bounds вызывая TView.Init. GrowMode устанавливается в gfGrowHiX + gfGrowHiY, а поле Pattern устанавливается в APattern. См. так же: TView.Init, TBackground.Pattern
Load constructor Load(var S: TStream); Создает объект TBackground и загружает его из потока S, вызывая TView.Load, а затем читая поле Pattern. См. так же: TView.Load
Draw procedure Draw; virtual; Перекрывается: Редко Заполняет прямоугольник видимого элемента текущим шаблоном с цветом по умолчанию.
GetPalette function GetPalette: PPalette; virtual; Перекрывается: Редко Возвращает указатель на палитру по умолчанию CBackground.
Store procedure Store(var S: TStream); Сохраняет видимый элемент TBackground в потоке, вызывая TView.Store, а затем записывая поле Pattern. См. так же: TView.Store, TBackground.Load
Палитра
Объекты фона используют по умолчанию палитру CBackground для отображения в первый элемент палитры программы.
1 +===+ CBackground | 1 | +=+=+ Color ----+

TBufStream Objects

+------------+ | TObject | +------+-----+ +------+-----+ | TStream | +------+-----+ +------+-----+ | TDosStream | +------+-----+ +======+=====+ | TBufStream | +============+
TBufStream реализует буферизованную версию TDosStream. Дополнительные поля указывают размер и положение буфера, а так же текущую и последнюю позицию в буфере. Кроме перекрытия восьми методов TDosStream, TBufStream определяет абстрактный метод TStream.Flush. Констрактор TBufStream создает и открывает файл, вызывая TDosStream.Init, затем создает буфер с помощью GetMem. TBufStream значительно эффективнее TDosStream при работе большого числа небольших данных в поток, а так же при сохранении и загрузке объектов с использованием TStream.Get и TStream.Put.
Поля
Buffer Buffer: Pointer; Только чтение Указатель на начало буфера потока.
BufSize BufSize: Word; Только чтение Размер буфера в байтах.
BufPtr BufPtr: Word; Только чтение Смещение от указателя Buffer, указывающее на текущую позицию внутри буфера.
BufEnd BufEnd: Word; Только чтение Если буфер не заполнен, BufEnd дает смещение от указателя Buffer на последний используемый байт в буфере.
Методы
Init constructor Init(FileName: FNameStr; Mode, Size: Word); Создает и открывает файл с режимом доступа Mode, вызывая TDosStream.Init. Так же создает буфер размером в SizeBuf, вызывая GetMem. Handle, Buffer и BufSize инициализируются соответственно. Типичный размер буфера от 512 до 2048 байт. См. так же: TDosStream.Init
Done destructor Done; virtual; Перекрывается: Никогда Закрывает и освобождает файловый поток; выталкивает и освобождает его буфер. См. так же: TBufStream.Flush
Flush procedure Flush; virtual; Перекрывается: Никогда Выталкивает буфер потока, обеспечивая, что поток будет в состоянии stOK. См. так же: TBufStream.Done
GetPos function GetPos: LongInt; virtual; Перекрывается: Никогда Возвращает значение текущей позиции потока (не перепутайте с BufPtr - текущей позицией в буфере). См. так же: TBufStream.Seek
GetSize function GetSize: LongInt; virtual; Перекрывается: Никогда Выталкивает буфер, а затем возвращает общее число байт в потоке.

Read procedure Read(var Buf; Count: Word); virtual; Перекрывается: Никогда Если stOK, читает Count байт в буфер Buf, начиная с текущей позиции потока. Заметим, что Buf - это не буфер потока, а внешний буфер, содержащий данные читаемые из потока. См. так же: TBufStream.Write, stReadError

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

Truncate procedure Truncate; virtual; Перекрывается: Никогда Выталкивает буфер, затем удаляет все данные потока от текущей позиции до конца потока. Текущая позиция устанавливается в новый конец потока. См. так же: TbufStream.GetPos, TBufStream.Seek

Write procedure Write(var Buf; Count: Word); virtual; Перекрывается: Никогда Если stOK, записывает Count байт из буфера Buf в поток, начиная с текущей позиции. Заметим, что Buf - это не буфер потока, а внешний буфер, содержащий данные, записываемые в поток. Когда Write вызывается, Buf указывает на переменную, чье значяение записывается. См. так же: TBudStream.Read, stWriteError

TButton Dialogs

+-----------+ | TObject | +-----+-----+ +-----+-----+ | TView | +-----+-----+ +=====+=====+ | TButton | +===========+
Объект TBuuton - это прямоугольник с заголовком и тенью, генерирующий команду при нажатии. Эти кнопки интенсивно используются в IDE. Кнопка может быть выбрана нажатием подсвеченной буквы, переходом на кнопку с помощью Tab и нажатием пробела, нажатием Enter, когда кнопка по умолчанию (указывается подсветкой) или отметкой кнопки мышкой. При цветной и черно-белой палитрах кнопка имеет трехмерный вид, который изменяется при нажатии. На монохромных системах кнопка выделена стрелками и другие ASCII символы используются для указания, является ли кнопка по умолчанию выбранной и т.д. Как и другие элементы управления, определенные в модуле Dialogs, TButton - это терминальный объект. Он может быть вставлен в любую группу и использован без перекрытия его методов. Кнопка инициализируется передачей ей TRect строки заголовка, команды, генерируемой при нажатии кнопки и байта флагов. Чтобы определить для кнопки клавишу короткого набора, строка заголовка может содержать "~" вокруг одного из символов, который становится символом короткого набора. Параметр AFlag указывает, будет заголовок центрироваться или выравниваться по левой границе и должна ли кнопка быть умалчиваемой (и следовательно выбираться через Enter). Вы можете установить в окне или диалоговом окне только одну кнопку по умолчанию в любой момент времени. Кнопки, которые равны в группе, получают и отдают умалчиваемое состояние через сообщения evBroadcast. Кнопки могут быть разрешены или запрещены с использованием методов SetState и CommandEnabled.
Поля
Title Title: PString; Только чтение Указатель на текст кнопки.
Command Commаnd: Word; Только чтение Слово команды в событии, генерируемом при нажатии кнопки. См. так же: TButton.Init, TButton.Load
Flags Flags: Byte; Чтение/Запись Flags - это поле, используемое для указания, будет ли текст кнопки центрироваться или выравниваться влево. Отдельные флаги описаны в разделе "Константы флага кнопки bfXXXX" главы 14. См. так же: TButton.Draw, константы bfXXXX

AmDefault AmDefault: Boolean; Только чтение Если True, кнопка - по умолчанию (и следовательно выбирается при нажатии Enter). Иначе - это "нормальная" кнопка. См. так же: Константы флага кнопки bfXXXX

Методы

Init constructor Init(var Bounds: TRect; ATitle: TTitleStr; ACommand: Word; AFlags: Byte); Создает объект TButton с заданным размером, вызывая TView. Init. Вызывается NewStr(ATitle) и назначается в Title. AFlags используется в двух целях: если AFlags and bfDefault - не 0, то AmDefault устанавливается в True; кроме того, AFlags указывает, будет заголовок центрироваться или выравниваться влево проверкой если AFlags and bfLeftJust не 0. Options устанавливается в (ofSelectable + ofFirstClick + ofPreProcess + ofPostProcess). EventMask устанавливается в evBroadсast. Если данная ACommand не разрешена, в поле State устанавливается sfDisabled. См. так же: TView.Init, константы флага кнопки bfXXXX

Load constructor Load(var S: TStream); Создает объект TButton и инициализирует его из заданного потока, вызывая TView.Load(S). Другие поля устанавливаются через вызовы S.Read, а State устанавливается в соответствии с тем, разрешена ли команда в поле Command. Используется совместно с TButton.Store для сохранения и получения объекта в TButton из TStream. См. так же: TView.Load, TButton.Store

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

Draw procedure Draw; virtual; Перекрывается: Редко Рисует кнопку соответствующей палитрой для ее текущего состояния (нормальная по умолчанию запрещена) и позиционирует метку в соответствии с битом bfLeftJust поля Flags.

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

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Иногда Отвечает на нажатие одним из трех способов: отметкой кнопки мышкой, нажатием короткой клавиши или становится кнопкой по умолчанию, когда получено общее сообщение cmDefault. Когда кнопка нажата, генерируется командное событие с TView.PutEvent, с полем TButton.Command: установленным в Event.Command, а Event.InfoPtr установленным в @Self. Кнопки так же распознают общие команды cmGrabDefault и cmReleaseDefault, чтобы стать или "не стать" кнопкой по умолчанию и cmCommandSetChanged, которая заставляет их проверять, разрешены команды или запрещены. См. так же: TView.HandleEvent


MakeDefault procedure MakeDefault(Evable: Boolean); Этот метод ничего не делает, если кнопка уже умалчиваемая. Иначе говорит Owner в кнопке измениться в состояние по умолчанию. Если Enable True, выдается общая команда cmGrebDefault, иначе cmReleaseDefault. Кнопка перерисовывается, чтобы показать новый статус. См. так же: TButton.AmDefault, bfDefault

SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Перекрывается: Редко Вызывает TView.SetState, затем рисует кнопку, если кнопка стала sfSelected или sfActive. Если она стала активной (т. е. если AState - sfFocused) кнопка забирает или отдает состояние по умолчанию кнопке по умолчанию, вызывая MakeDefault. См. так же: TCView.SetState, TButton.MakeDefault

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

Палитра

Объект кнопка использует палитру по умолчанию CButton для отображения элементов от 10 до 15 в палитру CDialog.

1 2 3 4 5 6 7 8 +====+====+====+====+====+====+====+====+ CButton | 10 | 11 | 12 | 13 | 14 | 14 | 14 | 15 | +==+=+==+=+==+=+==+=+==+=+==+=+==+=+=+==+ Нормальный --+ | | | | | | + Тень текст | | | | | | Текст по ------+ | | | | +---- Выбранная умолчанию | | | | короткая клавиша Выбранный ----------+ | | +--------- Короткая клавиша текст | | по умолчанию Запрещенный ---------------+ +-------------- Выбранная текст нормальная клавиша

TCheckBoxes Dialogs

+------------+ | TObject | +------+-----+ +------+-----+ | TView | +------+-----+ +------+-----+ | TCluster | +----+---+---+ +--------+ +-------+ +-------+-------+ +======+======+ | TRadioButtons | | TCheckBoxes | +---------------+ +=============+
TCheckBoxes - это кластер, содержащий от 1 до 16 элементв управления. В отличие от зависимых кнопок, любое число независимых кнопок может быть установлено независимо. Поэтому в этой группе нет кнопки по умолчанию. Кнопки можно отмечать мышкой, движением курсора и коротким нажатием Alt-буква. Каждая кнопка может быть подсвечена и включена/выключена (пробелом). Если кнопка выбрана, появляется Х. Другие части Вашей программы обычно проверяют состояние независимых кнопок для определения, какая опция выбрана пользователем (например в IDE опции компилятора и редактора выбираются таким способом). Кластеры независимых кнопок часто связаны с объектами TLabel.
Поля
Наследуют поля ValueSl от TCluster. Value интерпретируется как набор из 16 бит (от 0 до 15), где 1 в бите позиции означает, что соответствующий элемент отмечен.
Методы
Заметим, что TCheckBoxes не перекрывает констракторов, дестрактора и обработчика событий TCluster. Порожденные типы объектов могут однако перекрыть их.
Draw procedure Draw; virtual; Перекрывается: Редко Рисует объект TCheckBoxes вызывая наследуемый метод TCluster.DrawBox. По умолчанию независимая кнопка имеет вид: " [ ] " когда не выбрана и " [X] " когда выбрана. Заметим, что если границы видимого элемента достаточно велики, независимые кнопки могут отображаться в несколько колонок. См. так же: TCluster.DrawBox
Mark function Mark(Item: Integer) : Boolean; virtual; Перекрывается: Редко Возвращает True, если бит элемента в Value установлен, т.е. если данная кнопка отмечена. Вы можете перекрыть это, установив другую интерпретацию поля Value. По умолчанию элементы нумеруются от 0 до 15. См. так же: TCheckBoxes.Press
Press procedure Press(Item: Integer); virtual; Перекрывается: Редко Устанавливает бит элемента в Value. Вы можете перекрыть его для другой интерпретации поля Value. По умолчанию элементы нумеруются от 0 до 15. См. так же: TCheckBoxes.Mark
Палитра
По умолчанию объекты независимых кнопок используют CCluster - палитру по умолчанию для всех объектов-кластеров.
1 2 3 4 +====+====+====+====+ CCluster | 16 | 17 | 18 | 18 | +==+=+==+=+==+=+==+=+ Нормальный ----+ | | +--- Выбранная короткая текст | | клавиша Выбранный -------+ +-------- Нормальная короткая текст клавиша

TCluster Dialogs

+------------+ | TObject | +------+-----+ +------+-----+ | TView | +------+-----+ +======+=====+ | TCluster | +====+===+===+ +--------+ +-------+ +-------+-------+ +------+------+ | TRadioButtons | | TCheckBoxes | +---------------+ +-------------+
Кластер - это группа элементов управления, которые откликаются одинаково. TCluster - это абстрактный тип объекта, из которого порождаются группы элементов управления TRadioButtons и TCheckBoxes. Элементы управления кластера часто ассоциируются с объектами TLabel, позволяя Вам выбирать элемент управления, выбирая дополнительную метку с объяснением. В то время, как кнопки используются для генерации команд, а строки ввода - для редактирования строк, кластеры используются для переключения битовых значений поля Value (типа Word). Стандартные наследники TCluster используют различные алгоритмы изменения Value: TCheckBoxes просто переключает бит, а TRadioButtons включает один бит и очищает предварительно выбранный бит. Оба объекта наследуют почти все свое поведение от TCluster.
Поля
Value Value: Word; Только чтение Текущие значения элемента управления. Действительнвый смысл этого поля определяется методами, разработанными в типах объектов, порожденных от TCluster.
Sel Sel: Integer; Только чтение Текущий выбранный элемент кластера.
Strings Strings: TStringCollection; Только чтение Список элементов кластера.
Методы
Init constructor Init(var Bounds: TRect; AStrings: PSItem); Очищает поля Value и Sel. Параметр AStrings обычно выполняет серию вложенных вызовов глобальной функции NewSItem. Таким образом весь кластер зависимых или независимых кнопок может быть создан одним вызовом констрактора:
var Control: PView; . R.Assign(30, 5, 52, 7); Control := New(PRadioButtons, Init(R, NewSItem('~F~orward', NewSItem('~B~ackward', nil)))); .
Когда в кластер добавляются дополнительные зависимые или независимые кнопки, просто копируется первый вызов NewSItem и заголовок заменяется требуемым текстом. Затем добавляется дополнительная закрывающая скобка для каждой новой добавленной строки и оператор будет компилироваться без синтаксических ошибок. См. так же: тип TSItem

Load constructor Load(var S: TStream); Создает объект TCluster, вызывая TView.Load(S), затем устанавливает поля Value и Set вызовом S.Read. Наконец поле String кластера загружается из S с помощью Strings.Load(S). Используется совместно с TCluster.Store для сохранения и получения объектов TCluster из потока. См. так же: TCluster.Store, TView.Load

Done destructor Done; virtual; Перекрывается: Иногда Освобождает память, распределенную под строку кластера, затем разрушает видимый элемент, вызывая TView.Done. См. так же: TView.Done

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

DrawBox procedure DrawBox(Icon: String; Maker: Char); Вызывается методом Draw порожденного типа, чтобы рисовать прямоугольник перед строкой для каждого элемента кластера. Icon - это строка из 5 символов (' [ ] ' для независимых и ' ( ) ' для зависимых кнопок). Maker - это символ, используемый для указания, что кнопка отмечена ('X' для зависимых и '.' для независимых кнопок). См. так же: TCheckBoxes.Draw, TRadioButtons.Draw

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

GetHelpCtx function GetHelpCtx: Word; virtual; Перекрывается:Редко Возвращает значение Sel добавленное к HelpCtx. Это позволяет Вам задать отдельную констекстную справку для каждого элемента кластера. Допустимый диапазон контекстов равен HelpCtx плюс число элементов кластера минус 1.

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

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


Mark function Mark(Item: Integer): Boolean; virtual; Перекрывается: Всегда Вызывается из Draw для определения, какие элементы отмечены. По умолчанию TCluster.Mark возвращает False. Mark должен перекрываться, возвращая True, если элемент управления в кластере отмечен, иначе False.

MovedTo procedure MovedTo(Item: Integer); virtual; Перекрывается: Редко Вызывается из HandleEvent для перемещения полосы выбора на заданный элемент управления в кластере.

Press procedure Press(Item: Integer); virtual; Перекрывается: Всегда Вызывается из HandleEvent когда элемент управления в кластере нажат либо отметкой мышки, либо событием от клавиатуры. Этот абстрактный метод должен быть перекрыт.

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

SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Перекрывается: Редко Вызывает TView.SetState, затем рисует кластер, если AState - sfSelected. См. так же: TView.SetState, TView.DrawView

Store procedure Store(var S: TStream); Сохраняет объект TCluster в потоке, вызывая TView.Store(S), записывает Value и Sel, затем сохраняет поле Strings кластера, используя его метод Store. Используется совместно с TCluster.Load для сохранения и получения объектов TCluster из потока. См. так же: TCluster.Load, TStream.Write

Палитра

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

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

TCollection Objects

+---------+ | TObject | +----+----+ +======+======+ | TCollection | +======+======+ +---------+---------+ | TSortedCollection | +---------+---------+ +---------+---------+ | TStringCollection | +---------+---------+ +----------+----------+ | TResourceCollection | +---------------------+
TCollection - это абстрактный тип для реализации любой коллекции элементов, включая другие объекты. TCollection это намного более общая концепция, чем обычные массив, множество или список. Размер объектов TCollection динамически устанавливается во время выполнения и TCollection - базовый тип для многих специализированных типов, таких как TSortedCollection, TStringCollection и TResourceCollection. В дополнение к методам добавления и удаления элементов TCollection представляет несколько итераторных программ, которые вызывают процедуру или функцию для каждого элемента коллекции.
Поля
Items Items: PItemList; Только чтение Указатель на массив указателей элементов. См. так же: тип TItemList
Count Count: Integer; Только чтение Текущее число элементов в коллекции, максимально MaxCollectionSize. См. так же: переменная MaxCollectionSize
Limit Limit: Integer; Только чтение Текущий распределенный размер (в элементах) списка Items. См. так же: Delta, TCollection.Init
Delta Delta: Integer; Только чтение Число элементов, на которое увеличивается список Items при заполнении. Если Delta - 0, коллекция не может расти выше размера, установленного в Limit.
Примечание: Увеличение размера коллекции достаточно дорого в смысле производительности. Чтобы минимизировать число раз когда это происходит, попытайтесь установить начальное Limit в такое количество, которое будет достаточно для всех элементов, которые Вы собираетесь коллекционировать, и установите Delta так, чтобы она позволяла расширение на приемлемое количество. См. так же: Limit, TCollection.Init
Методы
Init constructor Init(ALimit, ADelta: Integer); Создает коллекцию с Limit, установленным в ALimit и Delta, установленным в ADelta. Первоначальное число элементов будет ограничено ALimit, но коллекция может расширяться, увеличиваясь по ADelta до тех пор, пока будет достаточно памяти или пока число элементов не достигнет MaxCollectionSize. См. так же: TCollection.Limit, TCollection.Delta.

Load constructor Load(var S: TStream); Создает и загружает коллекцию из потока. TCollection.Load вызывает GetItem для каждого элемента коллекции. См. так же: TCollection.GetItem

Done destructor Done; virtual; Перекрывается: Часто Удаляет и освобождает все элементы коллекции, вызывая TCollection.FreeAll и устанавливая Limit в 0. См. так же: TCollection.FreeAll, TCollection.Init

At function At(Index: Integer) : Pointer; Возвращает указатель на элемент с индексом Index в коллекции. Этот метод позволяет Вам интерпретировать коллекцию как индексированный массив. Если индекс меньше 0 или больше или равно Count, вызывается метод Error с аргументом coIndexError и возвращается значение nil. См. так же: TCollection.IndexOf

AtDelete procedure AtDelete(Index: Integer); Удаляет элемент в позиции Index и перемещает следующие элементы на одну позицию вверх. Count уменьшается на 1, но память, распределенная под коллекцию (как задано в Limit) не сокращается. Если Index меньше 0 или больше или равно Count, вызывается метод Error с аргументом coIndexError. См. так же: TCollection.FreeItem, TCollection.Free, TCollection.Delete

AtInsert procedure AtInsert(Index: Integer; Item: Pointer); Вставляет Item в позицию Index и передвигает следующие элементы на одну позицию вниз. Если Index меньше 0 или больше Count, вызывается метод Error с аргументом coIndexError и новый Item не вставляется. Если Count равен Limit до вызова AtInsert, распределенный размер коллекции расширяется на Delta элементов, вызывая SetLimit. Если вызов SetLimit не может расширить коллекцию, вызывается метод Error с аргументом coOverflow и новый Item не вставляется. См. так же: TCollection.At, TCollection.AtPut

AtPut procedure AtPut(Index: Integer; Item: Pointer); Заменяет элемент в позиции Index элементом, заданным в Item. Если Index меньше 0 или больше или равно Count, вызывается метод Error с аргументом coIndexError. См. так же: TCollection.At, TCollection.AtInsert

Delete procedure Delete(Item: Pointer); Удаляет элемент Item из коллекции. Эквивалентно AtDelete(IndexOf(Item)). См. так же: TCollection.AtDelete, TCollection.DeleteAll


DeleteAll procedure DeleteAll; Удаляет все элементы из коллекции, устанавливая Count в 0. См. так же: TCollection.Delete, TCollection.AtDelete

Error procedure Error(Code, Info: Integer); virtual; Перекрывается: Иногда Вызывается, когда встречается ошибка коллекции. По умолчанию этот метод генерирует ошибку времени выполнения 212. См. так же: константы коллекции coXXXX

FirstThat function FirstThat(Test: Pointer) : Pointer; FirstThat применяет булевскую функцию, заданную указателем на функцию Test к каждому элементу коллекции до тех пор, пока test возвращает True. Результат - указатель на элемент, для которого Test возвращает True, или nil, если функция Test возвращает False для всех элементов. Test должна указывать на дальнюю локальную функцию, использующую только один параметр типа Pointer и возвращающую значение типа Boolean. Например

function Matches(Item: Pointer) : Boolean; far;

Функция Test не может быть глобальной функцией. Предполагая, что List типа TCollection, оператор

P := List.FirstThat(@Matches);

соответствует

I := 0; while (I < List.Count) and not Matches(List.At(I)) do Inc(I); if I < List.Count then P := List.At(I) else P := nil;

См. так же: TCollection.LastThat, TCollection.ForEach

ForEarch procedure ForEarch(Action: Pointer); ForEach применяет действие, определенное процедурой, на которую указывает Action, для каждого элемента коллекции. Action должен указывать на локальную дальнюю процедуру, использующую один параметр типа Pointer. Например

function PrintItem(Item: Pointer);

Процедура Action не может быть глобальной процедурой. Если List типа TCollection, оператор

List.ForEach(@PrintItem);

соответствует

for I := 0 to List.Count - 1 do PrintItem(List.At(I));

См. так же: TCollection.FirstThat, TCollection.LastThat

Free procedure Free(Item: Pointer); Удаляет и освобождает Item. Эквивалентно

FreeItem(Item); Delete(Item);

См. так же: TCollection.FreeItem, TCollection.Delete

FreeAll procedure FreeAll; Удаляет и освобождает все элементы коллекции.


См. так же: TCollection.DeleteAll

FreeItem procedure FreeItem(Item: Pointer); virtual; Перекрывается: Иногда Метод FreeItem должен освобождать Item. По умолчанию TCollection.FreeItem предполагает, что Item - это указатель на объект, порожденный от TObject и поэтому вызывает дестрактор Done:

if Item <> nil then dispopse(PObject(Item), Done);

FreeItem вызывается из Free и FreeAll, но никогда не должен вызываться прямо.

См. так же: TCollection.Free, TCollection.FreeAll

GetItem function TCollection.GetItem(var S: TStream): Pointer; virtual; Перекрывается: Иногда Вызывается из TCollection.Load для каждого элемента коллекции. Этот метод может быть перекрыт, но не должен вызываться напрямую. По умолчанию TCollection.GetItem предполагает, что элементы коллекции порождены от TObject и вызывает TString.Get для загрузки элемента:

GetItem := S.Get;

См. так же: TStream.Get, TCollection.Load, TCollection.Store

IndexOf functionIndexOf(Item: Pointer): Integer; virtual; Перекрывается: Никогда Возвращает индекс для Item. Преобразует операцию в TCollection.At. Если Item - не в коллекции, IndexOf возвращает -1.

См. так же: TCollection.At

Insert procedure Insert(Item: Pointer); virtual; Перекрывается: Никогда Вставляет Item в коллекцию, перестраивая другие индексы, если необходимо. По умолчанию вставка производится в конец коллекции вызовом AtInsert(Count, Item);

См. так же: TCollection.AtInsert;

LastThat function LastThat(Test: Pointer): Pointer; LastThat применяет булевскую функцию, заданную указателем на функцию Test, к каждому элементу коллекции в обратном порядке до тех пор, пока Test не вернет True. Результат - указатель на элемент, для которого Test возвращает True, или nil, если функция Test возвращает False для всех элементов. Test должен указывать на дальнюю локальную функцию, использующую один параметр типа Pointer и возвращающую типа Boolean, например

function Patches(Item: Pointer): Boolean; far;

Функция Test не может быть глобальной функцией. Если List типа TCollection, оператор


P := List.LastThat(@Matches);

соответствует

I := List.Count - 1; while (I >= 0) and Matches(List.At(I)) do Dec(I); if I >= 0 then P := List.At(I) else P := nil;

См. так же: TCollection.FirstThat, TCollection.ForEach;

Pack Procedure Pack; Удаляет все nil указатели в коллекции.

См. так же: TCollection.Delete, TCollection.DeleteAll

PutItem procedure PutItem(var S: TStream; Item: Pointer); virtual; Перекрывается: Иногда Вызывается из TCollection.Store для каждого элемента коллекции. Этот метод может быть перекрыт, но не должен вызываться прямо. По умолчанию TCollection.PutItem предполагает, что элементы коллекций порождаются от TObject и вызов TString.Put сохраняет элемент:

S.Put(Item);

См. так же: TCollection.GetItem, TCollection.Store, TCollection.Load

SetLimit procedure SetLimit(ALimit: Integer); virtual; Перекрывается: Редко Расширяет или сокращает коллекцию, изменяя распределенный размер в ALimit. Если ALimit меньше Count, он устанавливается в Count, и если ALimit больше MaxCollectionSize, он устанавливается в MaxCollectionSize. Кроме того, если ALimit отличается от текущего Limit, распределяется новый массив Items из Alimit элементов, старый массив Items копируется в новый массив и старый массив освобождается.

См.так же: TCollection.Limit, TCollection.Count, переменная MaxCollectionSize

Store procedure Store(var S: TStream); Сохраняет коллекцию и все ее элементы в потоке S. TCollection.Store вызывает TCollection.PutItem для каждого элемента коллекции.

См. так же: TCollection.PutItem





TDeskTop App

+---------+ | TObject | +----+----+ +----+----+ | TView | +----+----+ +----+----+ | TGroup | +-+--+--+-+ +----------+ | +------------+ +----+----+ +====+=====+ +------+-------+ | TWindow | | TDeskTop | | TProgram | +----+----+ +==========+ +------+-------+ +----+----+ +------+-------+ | TDialog | | TApplication | +---------+ +--------------+
TDescTop - это простая группа, которая владеет видимым элементом TBackground, на котором появляются окна и другие видимые элементы программы. TDeskTop представляет область панели экрана, располагаемой между верхней полосой меню и нижней строкой статуса.
Методы
Init constructor Init(var Bounds: TRect); Создает группу TDeskTop с размером Bounds. По умолчанию GrowMode установлена в gfGrowHiX + gfGrowHiY. Init так же вызывает NewBackground для вставки видимого элемента TBackgroud в группу.
См. так же: TDeskTop.NewBackGround, TGroup.Init, TGroup.Insert
Cascade procedure Cascade(var R: TRect); Заново отображает все окна, принадлежащие панели экрана, в каскадном формате. Первое окно в Z порядке (самое нижнее) расширяется на всю панель экрана, а каждое последующее окно заполняет область, начинающуюся на одну строку ниже и на одну колонку правее, чем предыдущее. Активное окно появляется на вершине как самое наименьшее.
См. так же: ofTileable, TDeskTop.Tile
NewBackGround function NewBackGround: PView; virtual; Перекрывается: Иногда Возвращает указатель на фон, используемый в панели экрана. Этот метод вызывается в методе TDeskTop.Init. Наследуемые объекты могут изменить тип фона, перекрывая этот метод.
См. так же: TDeskTop.Init
HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Редко Вызывает TGroup.HandleEvent и отрабатывает команды cmNext (обычно горячая клавиша F6) и cmPrevious циклическим проходом по окнам (начиная с текущего выбранного видимого элемента) принадлежащим панели экрана.
См. так же: TGroup.HandleEvent, константы команд cmXXXX
Tile procedure Tile(var R: TRect); Заново отображает все видимые элементы с ofTileable, принадлежащие панели экрана в черепичном формате.
См. так же: TDeskTop.Cascade, ofTileable
TileError procedure TileError; virtual; Перекрывается: Иногда TileError вызывается, если возникла ошибка во время работы TDeskTop.Tile или TDeskTop.Cascade. По умолчанию ничего не делает. Вы можете перекрыть ее, чтобы указать пользователю, что программа не может реорганизовать окна.
См. так же: TDeskTop.File, TDeskTop.Cascade

TDialog Dialogs

+---------+ | TObject | +----+----+ +----+----+ | TView | +----+----+ +----+----+ | TGroup | +-+--+--+-+ +----------+ | +------------+ +----+----+ +----+-----+ +------+-------+ | TWindow | | TDeskTop | | TProgram | +----+----+ +----------+ +------+-------+ +====+====+ +------+-------+ | TDialog | | TApplication | +=========+ +--------------+
TDialog - это потомок TWindow со следующими свойствами: - GrowMode - 0, т.е. диалоговые окна не увеличиваются. - Флаги wfMove и wfClose установлены, т.е. диалоговые окна можно перемещать и закрывать (предоставлена закрывающая кнопка). - Обработчик событий TDialog вызывает TWindow.HandleEvent и дополнительно обрабатывает отклики на клавиши Esc и Enter. Клавиша Esc генерирует команду cmCancel, а Enter генерирует команду cmDefault. - TDialog.Valid возвращает True на команду cmCancel, иначе вызывает TGroup.Valid.
Методы
Init constructor Init(var Bounds: TRect; ATitle: TTitleStr); Создает диалоговое окно с заданным размером и заголовком, вызывая TWindow.Init(Bounds, ATitle, wnNoNumber). GrowMode устанавливается в 0 и Flags устанавливается в wfMove + wfClose. Это означает, что по умолчанию диалоговые окна можно перемещать и закрывать, но нельзя изменять их размеры. Заметим, что TDialog не определяет собственного дестрактора, а использует Close и Done, наследуемые через TWindow, TGroup и TView.
См. так же: TWindow.Init
HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Иногда Вызывает TWindow.HandleEvent(Event), затем обрабатывает клавиши Enter и Esc. В частности Esc генерирует команду cmCancel, а Enter посылает общие сообщения cmDeafult. Этот метод так же обрабатывает cmOK, cmCancel, cmYes и cmNo, заканчивая модальное состояние диалогового окна. Для каждого из успешно обработанных событий он вызывает метод ClearEvent.
См. так же: TWindow.HandleEvent
GetPalette function GetPalette: PPalette; virtual; Перекрывается: Редко Этот метод возвращает указатель на палитру по умолчанию CPalette.
Valid function Valid(Command: Word): Boolean; virtual; Перекрывается: Редко Возвращает True, если заданная команда - cmCancel, или если все элементы управления группы возвращают True.

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

Палитра

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

1 2 3 4 5 6 7 8 9 +===+===+===+===+===+===+===+===+===+ CDialog | 32| 33| 34| 35| 36| 37| 38| 39| 40| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Пассивная --+ | | | | | | | +- Короткая метка рамка | | | | | | | Активная ------+ | | | | | +----- Подсвеченная рамка | | | | | метка Кнопка ------------+ | | | +--------- Нормальная метка рамки | | | Страница ------------+ | +------------- Статический текст скроллинга | Элементы управления -----------+ скроллинга

10 11 12 13 14 15 16 17 18 +===+===+===+===+===+===+===+===+===+ CDialog | 41| 42| 43| 44| 45| 46| 47| 48| 49| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Нормальная -+ | | | | | | | +- Короткий кластер кнопка | | | | | | | Кнопка по ----+ | | | | | +----- Выбранный кластер умолчанию | | | | | Выбранная -------+ | | | +--------- Нормальный кнопка | | | кластер Запрещенная -----------+ | +------------- Тень кнопки кнопка | Короткая кнопка ---------------+

19 20 21 22 23 24 25 +===+===+===+===+===+===+===+ CDialog | 50| 51| 52| 53| 54| 55| 56| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Нормальная --+ | | | | | +-- Элементы управления строка ввода | | | | | окна истории Выбранная -------+ | | | | строка ввода | | | | Стрелки -------------+ | | +------ Страница окна истории строки ввода | | Стрелка истории ------------+ | +---------- Стороны истории

26 27 28 29 30 31 32 +===+===+===+===+===+===+===+ CDialog | 57| 58| 58| 59| 60| 61| 62| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Нормальный просмотр+ | | | | | +-- Зарезервировано списка | | | | | Активный просмотр ----+ | | | +------ Зарезервировано списка | | | Выбранный просмотр -------+ | +--------- Информационная панель | Разделитель просмотра ---------+

См. так же: Метод GetPalette для каждого типа объекта.

Текстовые устройства.

TTextDevice - это скользящий TTY тип просмотра текста - драйвера устройства. Кроме полей методов, наследуемых от TScroller, TTеxtDevice определяет виртуальные методы для чтения и записи строк в и из устройства. TTextDevice используется как базовый тип для порождения реальных драйверов. TTextDevice использует констрактор и дестрактор TScroller. TTerminal реализует терминал с буферизованным чтением и записью строк. Размер буфера определяется при инициализиции.

TEmsStream Objects

+------------+ | TObject | +-----+------+ +-----+------+ | TStream | +-----+------+ +=====+======+ | TEmsStream | +============+
TEmsStream - это специализированный поток, реализующий поток в Ems памяти, порожденный от TStream. Дополнительные поля представляют обработчик EMS, число страниц, размер потока и текущую позицию. TStreamEms перекрывает 6 абстрактных методов TStream, а так же предоставляет специальный констрактор и дестрактор.
Примечание: При отладке программы, использующей EMS потоки, IDE не может восстановить EMS память, распределенную Вашей программой, если Ваша программа преждевременно завершилась, или Вы забыли вызвать дестрактор Done для EMS потока. Только метод Done (или перезагрузка) могут освободить EMS страницы, принадлежавшие потоку.
Поля
Handle Handle: Word; Только чтение Обработчик EMS для потока.
PageCount PageCount: Word; Только чтение Число распределенных для потока страниц, по 16К на страницу.
Size Size: Longint; Только чтение Размер потока в байтах.
Position Position: Longint; Только чтение Текущая позиция внутри потока. Первая позиция - 0.
Методы
Init constructor Init(MinSize: Longint); Создает EMS поток с заданным минимальным размером в байтах. Вызывает TStream.Init, затем устанавливает Handle, Size и PageCount. Вызывает Error с аргументом stInitError, если инициализиция неудачна.
См. так же: TEmsStream.Done
Done destructor Done; virtual; Перекрывается: Никогда Освобождает EMS поток и используемые EMS страницы.
См. так же: TEmsStream.Init
GetPos function GetPos: Longint; virtual; Перекрывается: Никогда Возвращает значение текущей позиции в потоке.
См. так же: TEmsStream.Seek
GetSize function GetSize: Longint; virtual; Перекрывается: Никогда Возвращает общий размер потока.
Read procedure Read(var Buf; Count: Word); virtual; Перекрывается: Никогда Читает Count байт из буфера Buf, начиная с текущей позиции в потоке.
См. так же: TEmsStream.Write, stReadError
Seek procedure Seek(Pos: Longint); virtual; Перекрывается: Никогда Устанавливает текущую позицию в Pos байт от начала потока.
См. так же: TEmsStream.GetPos, TEmsStream.GetSize
Truncate procedure Truncate; virtual; Перекрывается: Никогда Удаляет все данные в потоке, начиная с текущей позиции до конца потока. Текущая позиция устанавливается в новый конец потока.
См. так же: TDosStream.GetPos, TDosStream.Seek
Write procedure Write(var Buf; Count: Word); virtual; Перекрывается: Никогда Записывает Count байт из буфера Buf в поток, начиная с текущей позиции.
См. так же: TDosStream.Read, TEmsStream.GetPos, TEmsStream.Seek

Терминальные видимые элементы.

Терминальные видимые элементы это все видимые элементы, которые не являются группами. Они не могут владеть другими видимыми элементами. Они, следовательно, являются конечными точками любых цепочек видимых элементов.

Территориальность.

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

TFrame Views

+---------+ | TObject | +----+----+ +----+----+ | TView | +----+----+ +====+====+ | TFrame | +=========+
TFrame предоставляет различные рамки вокруг окон и диалоговых окон. Вероятно пользователи никогда не будут использовать объекты рамок напрямую, т.к. они добавляются к окнам по умолчанию.
Методы
Init constructor Init(var Bounds: TRect); Вызывает TView.Init, затем устанавливает GrowMode в gfGrowHiX + gfGrowHiY и устанавливает EventMask в EventMask or evBroadcast, так, чтобы объекты TFrame обрабатывали по умолчанию общие события.
См. так же: TView.Init
Draw procedure Draw; virtual; Перекрывается: Редко Рисует рамку с цветом атрибутов и кнопками, соответствующими текущим флагам State: активный, неактивный и перемещаемый. Добавляет кнопки изменения размера, закрытия и масштабирования в зависимости от Flags окна - владельца. Добавляет заголовок, если есть, из поля Title окна-владельца. Активные окна рисуются с двойной рамкой и кнопками, а неактивные окна с одинарной рамкой и без кнопок.
См. так же: константы флагов состояния sfXXXX, константы флагов окна wfXХXX
GetPalette function GetPalette: Palette; virtual; Перекрывается: Редко Возвращает указатель на палитру рамки по умолчанию CFrame.
HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Редко Вызывает TView.HandleEvent, затем обрабатывает события от мышки. Если закрывающая кнопка отмечена мышкой, TFrame генерирует события cmClose. Отметка кнопки масштабирования или двойная отметка верхней линии рамки генерирует событие cmZoom. При перемещении мышкой за верхнюю строку рамки окно перемещается, а перемещение за кнопку изменения размера передвигает нижний правый угол элемента и соответственно изменяет его размер.
См. так же: TView.HandleEvent
SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Перекрывается: Редко Вызывает TView.SetState, затем, если новое состояние - sfActive или sfDragging, вызывает DrawView для перерисовки видимого элемента.
См. так же: TView.SetState
Палитра
Объекты рамок используют палитру по умолчанию CFrame для отображения первых трех элементов в палитру стандартного окна.
1 2 3 4 5 +===+===+===+===+===+ CFrame | 57| 58| 58| 61| 62| +=+=+=+=+=+=+=+=+=+=+ Пассивная ------+ | | | +-- Кнопки рамка | | | Пассивный ----------+ | +------ Активный заголовок заголовок | Активная ---------------+ рамка

TGroup Views

+---------+ | TObject | +----+----+ +----+----+ | TView | +----+----+ +====+====+ | TGroup | +=+==+==+=+ +----------+ | +------------+ +----+----+ +----+-----+ +------+-------+ | TWindow | | TDeskTop | | TProgram | +----+----+ +----------+ +------+-------+ +----+----+ +------+-------+ | TDialog | | TApplication | +---------+ +--------------+
Объекты TGroup и их порождения (которые мы для краткости называем группами) - основная управляющая сила Turbo Vision. Группы - это специальные порождения видимых элементов. В дополнение ко всем полям и методам, порожденным от TView, группа имеет дополнительные поля и методы (включая перекрывающие), позволяющие управлять динамически связанными списками видимых элементов (включая другие группы) как одним объектом. Мы часто говорили о подэлементах группы даже если эти подэлементы сами являются группами. Хотя группа имеет прямоугольную границу от своего предка TView, группа видима только через отображение своих подэлементов. Концептуально группа рисует себя через методы Draw своих подэлементов. Группа владеет своими подэлементами и они должны обеспечивать зарисовку (заполнение) всего прямоугольника группы Bounds. Во время работы программы подэлементы и подгруппы создаются, вставляются в группы и отображаются в результате деятельности пользователя и событий, генерируемых программой. Подэлементы могут быть легко скрыты, удалены из группы действиями пользователя (такими как закрытие окна или выход из диалогового окна). 3 порожденных от TGroup типа: TWindow, TDeskTop и TApplication (через TProgram) иллюстрируют концепцию групп и подгрупп. TApplication обычно владеет объектами TDeskTop, TStatusLine и TMenuView. TDeskTop порожден от TGroup и таким образом может владеть объектами TWindow, которые в свою очередь владеют объектами TFrame, TScrollBar и т.д. Объекты TGroup передают рисование и обработку событий своим подэлементам, как объясняется в главах 4 и 5. Многие из основных методов TView перекрываются в TGroup. Например, сохранение и чтение группы из потока может быть достигнуто одним вызовом TGroup.Store и TGroup.Load. Объекты TGroup обычно не имеют экземпляров; Вы будете создавать экземпляры от типов объектов, порожденных от TGroup: TApplication, TDeskTop и TWindow.

Поля

Last Last : PView; Только чтение Указывает на последний подэлемент группы (самый дальний от вершины в Z-порядке). Поле Next последнего подэлемента указывает на первый подэлемент, чье поле Next указывает на следующий подэлемент и т.д. формируя циклический список.

Current Current: PView; Только чтение Указывает на выбранный подэлемент или равен nil, если нет выбранного подэлемента.

См. так же: sfSelected, TView.Select

Buffer Buffer: PVideoBuf; Только чтение Указывает на буфер, используемый для кэширования операций перерисовки или равен nil, если группа не имеет кэш-буфера. Кэш-буфера создаются и уничтожаются автоматически, если флаг ofBuffered в поле Options не очищен.

См. так же: TGroup.Draw, TGroup.Lock, TGroup.Unlock

Phase Phase: (phFocused, phPreProcess, phPostProcess); Только чтение Текущая фаза обработки для активного события. Подэлементы, в которых установлены флаги ofPreProcess и/или ofPostProcess могут проверять Owner^.Phase, чтобы определить, в какой из фаз phPreProcess, phFocused или phPostProcess был вызван их HandleEvent.

См. так же: ofPreProcess, ofPostProcess, TGroup.HandleEvent

Методы

Init constructor Init(var Bounds: TRect); Вызывает TView.Init, устанавливает в Options ofSelectable и ofBuffered и устанавливает EventMask в $FFFF.

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

Load constructor Load(var S: TStream); Загружает всю группу из потока, вызывая вначале наследуемый TView.Load, а затем используя TStream.Get для чтения каждого подэлемента. После загрузки всех подэлементов выполняет проход по подэлементам для установки всех считанных указателей с использованием GetPeerViewPtr. Если тип объекта, порожденного от TGroup содержит поля, которые указывают на подэлементы, он должен использовать GetSubViewPtr внутри Load, чтобы читать эти поля.

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

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


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

ChangeBounds procedure ChangeBounds(var Bounds: Trect); virtual; Перекрывается: Никогда Перекрывает TView.ChangeBounds. Изменяет границы группы в Bounds, затем вызывает CalcBounds и ChangeBounds для каждого элемента группы.

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

DataSize function DataSize: Word; virtual; Перекрывается: Редко Перекрывает TView.DataSize. Возвращает общий размер группы, вызывая и накапливая DataSize для каждого подэлемента.

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

Delete procedure Delete(P: PView); Удаляет подэлемент P из группы и перерисовывает другие подэлементы, если необходимо. Поля Owner и Next в Р устанавливаются в nil.

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

Draw procedure Draw; virtual; Перекрывается: Никогда Перекрывает TView.Draw. Если кэш-буфер существует (см. поле TGroup.Buffer), то буфер пишется на экран с использованием TView.WriteBuf. Иначе каждый подэлемент рисует себя с помощью TGroup.Redraw.

См. так же: TGroup.Buffer, TGroup.Redraw

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

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

EventError procedure EventError(var Event: TEvent); virtual; Перекрывается: Иногда EventError вызывается когда в цикле обработчика события модального TGroup.Execute встречается событие, которое не может быть обработано. Действие по умолчанию: Если Owner группы не nil, EventError вызывает EventError своего владельца. Обычно эта цепочка распространяется до EventError из TApplication. Вы можете перекрыть EventErrоr для выполнения требуемого действия.

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

ExecView function ExecView(P: PView): Word; ExecView - это модальный вариант немодальных методов Insert и Delete. В отличие от Insert после вставки видимого элемента в группу ExecView ожидает видимый элемент для выполнения, затем удаляет видимый элемент и возвращает результат выполнения. ExecView используется в ряде мест в Turbo Vision, например для реализации TApplication.Run и для выполнения модальных диалоговых окон. ExecView сохраняет текущий контекст (выбранный видимый элемент, модальный видимый элемент и набор команд) делает Р модальным, вызывая Р^.SetState(sfModal, True), вставляет Р в группу (если он еще не вставлен) и вызывает P^.Execute. Когда P^.Execute возвращает управление, группа восстанавливается в предыдущее состояние и результат P^.Execute возвращается как результат вызова ExecView. Если P - nil в вызове ExecView, возвращается значение cmCancel.


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

Execute function Execute: Word; virtual; Перекрывается: Редко Перекрывает TView.Execute. Execute - это главный цикл событий группы: она постоянно получает события, используя GetEvent и обрабатывает их, используя HandleEvent. Цикл событий завершается группой или подэлементом с помощью вызова EndModal. Однако до возврата Exec вызывает Valid для проверки, что модальное состояние в самом деле было завершено. Реализация TGroup.Execute показана ниже. Заметим, что EndState - это private поле в TGroup, которое устанавливается вызовом EndModel.

function TGroup.Execute: Word; var E: TEvent; begin repeat EndState := 0; repeat GetEvent(E); HandleEvent(E); if E.What <> evNothing then EventError(E); until EndState <> 0; until Valid(EndState); Execute := EndState; end;

См. так же: TGroup.GetEvent, TGroup.HandleEvent, TGroup.EndModal, TGroup.Valid

First function First: PView; Возвращает указатель на первый подэлемент (ближайший к вершине в Z-порядке), или nil, если в группе нет подэлементов.

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

FirstThat function FirstThat(Test: Pointer): PView; FirstThat применяет булевскую функцию, заданную указателем на функцию Test к каждому подэлементу в Z-порядке до тех пор, пока Test не вернет True. Результат - указатель на подэлемент, для которог Test возвращает True, или nil, если функция Test возвращает False для всех подэлементов. Test должна указывать дальнюю локальную функцию, использующую параметр типа Pointer и возвращающую значение типа Boolean. Например:

function MyTestFunc(P: PView): Boolean; far;

Метод SubViewAt, показанный ниже, возвращает указатель на первый подэлемент, содержащий данную точку.

function TMyGroup.SubViewAt(Where: TPoint): PView;

function ContainsPoint(P: PView): Boolean; far; var Bounds: TRect; begin P^.GetBounds(Bounds); ContainsPoint := (P^.State and sfVisible <> 0) and Bounds.Contains(Where); end;

begin SubViewAt := FirstThat(@ContainsPoint); end;

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


ForEach procedure ForEach(Action: Pointer); ForEach выполняет действие, заданное указателем Action на процедуру к каждому подэлементу группы в Z-порядке. Action должна указывать на дальнюю локальную процедуру, использующую параметр типа Pointer, например:

procedure MyActionProc(P: PView); far;

Метод MoveSubViews перемещает все подэлементы группы на значение, заданное в Delta. Заметим использование Lock и UnLock для ограничения числа выполняемых операций по перерисовке для предотвращения неприятного мерцания.

procedure TMyGroup.MoveSubViews(Delta: TPoint);

procedure DoMoveView(P: PView); far; begin P^.MoveTo(P^.Origin.X + Delta.X, P^.Origin.Y + Delta.Y); end;

begin Lock; ForEach(@DoMoveView); UnLock; end;

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

GetData procedure GetData(var Rec); virtual; Перекрывается: Редко Перекрывает TView.GetData. Вызывает GetData для каждого подэлемента в Z-порядке увеличивая положение, заданное в Rec на DataSize для каждого подэлемента.

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

GetHelpCtx function GetHelpCtx: Word; virtual; Перекрывается: Редко Возвращает контекст подсказки для текущего активного видимого элемента, вызывая метод выбранного подэлемента GetHelpCtx. Если нет контекста подсказки, заданного подэлементом, GetHelpCtx возвращает значение собственного поля HelpCtx.

GetSubViewPtr procedure GetSubViewPtr(var S: TStream; var P); Загружает указатель на подэлемент Р из потока S. GetSubViewPtr должна использоваться только внутри констрактора Load для чтения значений указателей, которые были записаны вызовом PutSubViewPtr из метода Store.

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

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Часто Перекрывает TView.HandleEvent. Группа обрабатывает события, передавая их в методы HandleEvent одного или более подэлементов. Однако действительный маршрут зависит от класса события. Для активных событий (по умолчанию evKeyDown и evCommand, см. переменную FocusedEvents) обработка событий выполняется в 3 фазы: во-первых, поле Phase устанавливается в phPreProcess и событие передается в HandleEvent всех подэлементов, в которых установлен флаг ofPreProcess. Затем Phase устанавливается в phFocused и событие передается в HandleEvent текущего выбранного видимого элемента. Наконец, Phase устанавливается в phPostProcess и событие передается в HandleEvent всех подэлементов, в которых установлен флаг ofPostProcess. Для позиционированных событий (по умолчанию evMouse, см. переменную PositionalEvents), событие передается в HandleEvent первого подэлемента, чей ограничивающий прямоугольник содержит точку, заданную в Event.Where. Для общих событий (т.е. не активных и не позиционированных), событие передается в HandleEvent каждого подэлемента группы в Z-порядке.


Примечание: Если поле EventMask подэлемента маскирует класс события, TGroup.HandleEvent никогда не будет посылать события этого класса подэлементу. Например, по умолчанию EventMask из TView запрещает evMouseUp, evMouseMove и evMouseAuto, поэтому TGroup.HandleEvent никогда не будет посылать такие события стандартному TView.

См. так же: FocusedEvents, PositionalEvents, константы событий evXXXX, TView.EventMask, методы HandleEvent

Insert procedure Insert(P: PView); Вставляет видимый элемент, заданный Р в список подэлементов группы. Новый подэлемент помещается над всеми другими видимыми подэлементами. Если в подэлементе установлены флаги ofCenterX и/или ofCenterY, он центрируется в группе соответственно. Если видимый элемент имеет установленный флаг sfVisible, он будет показан в группе - иначе остается невидимым до тех пор, пока не будет показан специально. Если видимый элемент имеет установленным флаг ofSelectable, он становится текущим выбранным подэлементом.

InsertBefore procedure InsertBefore(P, Target: PView); Вставляет видимый элемент, заданный Р, перед видимым элементом, заданным Target. Если Target nil, видимый элемент размещается после всех видимых элементов группы.

См. так же: TGrouup.Unsert, TGroup.Delete

Lock procedure Lock; Блокирует группу, задерживая все записи, производимые подэлементами на экран до тех пор, пока группа не будет разблокирована. Lock не имеет эффекта, если в группе нет кэш-буфера (см. ofBuffered и TGroup.Buffer). Lock работает, увеличивая счетчик блокировок, который соответственно уменьшается с помощью UnLock. Когда вызов UnLock уменьшает счетчик до 0, вся группа пишется на экран, используя образ, созданный в кэш-буфере. Накапливая интенсивные операции прорисовки между вызовами Lock и UnLock, можно сократить или полностью избавиться от неприятного мерцания экрана. Например, TDeskTop.Tile и TDeskTop.Cascade используют Lock и UnLock для сокращения мерцания.

Примечание: Вызовы Lock и UnLock должны быть сбалансированы, иначе группа может остаться в постоянно заблокированном состоянии, что приведет к тому, что она не сможет вывести себя при необходимости.


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

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

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

Redraw procedure Redraw; Перерисовывает подэлементы группы в Z-порядке. TGroup.Redraw отличается от TGroup.Draw тем, что перерисовка никогда не производится выводом из кэш-буфера.

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

SelectNext procedure SelectNext(Forwards: Boolean); Если Forwards - True, SelectNext будет выбирать (делать текущим) следующий выбираемый подэлемент (подэлемент, в котором установлен бит ofSelectable) группы в Z-порядке. Если Forwards - False, метод выбирает предыдущий выбираемый элемент.

См. так же: константы флагов опций ofXXXX

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

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

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

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

Store procedure Store(var S: TStream); Сохраняет всю группу в потоке вначале вызывая унаследованный TView.Store, затем используя TStream.Put для вывода каждого подэлемента. Если объектный тип, порожденный от TGroup, содержит поля, которые указывают на подэлементы, он должен использовать PutSubViewPtr внутри его Store для записи этих полей.

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

Unlock procedure Unlock; Разблокирует группу, уменьшая счетчик блокировки. Если счетчик блокировки становится 0, то вся группа выводится на экран, используя образ, созданный в кэш-буфере.

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

Valid function Valid(Command: Word): Boolean; virtual; Перекрывает TView.Valid. Возвращает True, если вызовы Valid всех подэлементов возвращают True. TGroup.Valid используется в конце цикла обработки событий в TGroup.Execute для подтверждения, что завершение разрешено. Модальное состояние не может быть завершено до тех пор, пока все вызовы Valid не вернут True. Подэлемент может вернуть False, если он хочет, чтобы управление осталось у него.

См. так же: TView.Valid, TGroup.Execute

THistory

+----------+ | TObject | +----+-----+ +----+-----+ | TView | +----+-----+ +====+=====+ | THistory | +==========+
Объект THistory реализует список для значений, действий или выборов. связываютя с объектом TInputLine и со Информация списка истории хранится в Когда блок заполняется, наиболее стары удаляются, а новые добавляются. Объект THistory показан как кнопка (|щ| ввода. Когда пользователь отмечает кно Vision открывает окно истории (смотри просмотром истории (смотри THistoryV список предыдущих элементов. Различные строки ввода могут использ истории, используя одинаковый номер ID.
Поля
Link: PInputLine; Только чтение Указатель на связанный объект TInputLine.
HistoryID HistoryID: Word; Только чтение Каждый список истории имеет уникальный номер ID, назначаемый программистом. Различные объекты историй в различных окнах могут разделять список истории, используя одинаковый ID номер.
Методы
Init constructor Init(var Bounds: TRect; ALink: PInputLine; AHistoryID: Word); Создает объект THistоry заданного размера, вызывая TView.Init, затем устанавливает поля Link и HistoryId значениями, заданными в аргументах. Поле Options устанавливатся в ofPostProcess, а EventMask в evBroadcast.
См. так же: TView.Init
Load constructor Load(var S: TStream); Создает и инициализирует объект History из TStream, вызывая TView.Load(S) и читая Link и HistoryId из S.
См. так же: TView.Store
Draw procedure Draw; virtual; Перекрывается: Редко Рисует кнопку History в палитре по умолчанию.
GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на умалчиваемую палитру CHistory.
Store procedure Store(var S:TStream); Сохраняет объект THistory в TStream, вызывая TView.Store(S), затем записывает Link и HistoryId в S.
См. так же: TView.Load
Палитра
Кнопки истории используют палитру по умолчанию CHistory для отображения 14 и 20-го элементов в палитру стандартного диалогового окна.
1 2 +====+====+ CHistory | 14 | 20 | +==+=+=+==+ Стрелка --------+ +------- Стороны

THistoryViewer Dialogs

THistoryViewer - прямой потомок TListViewer. Он используется системой списка истории и появляется внутри окна истории при отметке кнопки истории. Для детального описания взаимодействия THistory, THistoryWindow и THistoryViewer смотри THistory в этой главе.
Поля
HistoryID HistoryID: Word; Только чтение HistoryId - это ID номер списка истории, отображаемого в этом видимом элементе.
Методы
Init constructor Init(var Bounds:TRect; AHScrollBar, AVScrollBar: PScrollBar; AHistoryID: Word); Init инициализирует видимый элемент просмотра списка, вначале вызывая TListViewer.Init для установки границ, одной колонки и двух полос скроллинга, передаваемых в AHScrollBar и AVScrollBar. Видимый элемент связывается затем со списком истории, с полем HistoryId, установленным в значение, переданное в AHistory. Этот список проверяется затем на длину так, что диапазон списка устанавливается в число списка. Первый элемент в списке истории дан как активный. Диапазон горизонтального скроллинга устанавливается в соответствие с самым широким элементом списка.
См. так же: TListViewer.Init
GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на умалчиваемую палитру CHistoryViewer.
GetText function GetText(Item: Integer; MaxLen: Integer): String; virtual; Перекрывается: Редко Возвращает строку Item в связанном списке истории. GetText вызывается виртуальным методом Draw для каждого видимого элемента в списке.
См. так же: TListViewer.Draw, HistoryStr function
HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Иногда Видимый элемент просмотра истории управляет двумя видами событий; все другие передаются в TListViewer.HandleEvent. Двойная отметка или нажатие клавиши Enter будут завершать модальное состояние окна истории с командой cmOK. При нажатии клавиши Esc или получении командного события cmCancel, выбор списка истории будет отменен.
См. так же: TListViewer.HandleEvent
HistoryWidth function HistoryWidth: Integer; Возвращает длину самой длинной строки в списке истории, связанном с HistoryId.
Палитра
Объекты просмотра истории используют палитру по умолчанию CHistoryViewer для отображения в 6 и 7 элементы палитры стандартного диалогового окна.
1 2 3 4 5 +===+===+===+===+===+ CHistoryViewer | 57| 58| 58| 61| 62| +=+=+=+=+=+=+=+=+=+=+ Активный ---------+ | | | +-- Разделитель Неактивный -----------+ | +------ Выбранный Сфокусированный ----------+

THistoryWindow Dialogs

THistoryWindow - это специализированный наследник от TWindow, используемый для объекта просмотра списка истории, когда пользователь отмечает кнопку истории, стоящую за строкой ввода. По умолчанию окно не имеет заголовка и номера. Рамка окна истории имеет закрывающую кнопку, поэтому окно может быть закрыто, но не может изменить размер или масштабироваться. Для деталей по использованию списков истории и связанных с ними объектов см. THistory в этой главе.
Поля
Viewer Viewer: PListViewer; Viewer указывает на список просмотра окна истории.
Методы
Init constructor Init(var Bounds: TRect; HistoryId: Word); Вызывает TWindow.Init для установки окна с заданными границами, пустой строкой заголовка и без номера окна (wnNoNumber). Поле TWindow.Flags устанавливается в wfClose, чтобы обеспечить закрывающую кнопку и объект просмотра истории создается, чтобы показать элементы списка истории, заданные через HistoryID.
См. так же: TWindow.Init, THistoryWindow.InitViewer
GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на палитру по умолчанию CHistoryWindow.
GetSelection function GetSelection: String; virtual; Перекрывается: Никогда Возвращает строковое значение активного элемента из просмотра истории.
См. так же: THistoryViewer.GetText
InitViewer procedure InitViewer(HistoryOd: Word); virtual; Перекрывается: Никогда Создает и вставляет объект THistoryViewer внутри границ окна истории со списком, заданным через HistoryId. Стандартные полосы скроллинга размещены на рамке окна для скольжения по списку.
См. так же: THistoryViewer.Init
Палитра
Объекты окна истории используют по умолчанию палитру CHistoryWindow для отображения на элементы с 19 по 25-й в палитре стандартного диалогового окна.
1 2 3 4 5 6 7 +====+====+====+====+====+====+====+ CHistoryWindow | 10 | 11 | 12 | 13 | 14 | 14 | 14 | +==+=+==+=+==+=+==+=+==+=+==+=+==+=+ Пассивная рамка --+ | | | | | +-- Выбранный текст Активная рамка -------+ | | | | Кнопка рамки ---------------+ | | +------ Нормальный текст | | | +-------- Элементы управления +------------- Область страницы

TInputLine Dialogs

+-------------+ | TObject | +------+------+ +------+------+ | TView | +------+------+ +======+======+ | TInputLine | +=============+
Объект TInputLine обеспечивает редактор строк ввода. Он управляет вводом с клавиатуры и мышки и перемещением помеченных блоков в различных функциях редактирования строки (см. TInputLine.HandleEvent). Выбранный текст удаляется и заменяется первым введенным текстом. Если MaxLen больше размера по Х (Size.X), поддерживается горизонтальный скроллинг, который указывается правой и левой стрелками. Методы GetData и SetData предназначены для записи и чтения строк данных (через поле указателя Data) в данную запись. TInputLine.SetState упрощает перерисовку видимого элемента соответствующим цветом, когда состояние изменяется из или в sfActive и sfSelected. Строка ввода часто имеет ассоциированные с ним объекты TLabel и/или THistory. TInputLine можно расширить для обработки типов данных отличных от строк. Чтобы сделать это, Вы добавляете новые поля и перекрываете методы Init, Load, Store, Valid, DataSize, GetData и SetData. Например, чтобы определить строку ввода числа, Вы можете задать минимальное и максимальные допустимые значения, которые будут проверяться функцией Valid. Эти минимальные и максимальные поля будут загружаться и сохраняться в потоке методами Load и Store. Valid модифицируется для проверки того, что значение находится в допустимом диапазоне. DataSize модифицируется для включения размера диапазона новых полей (вероятно SizeOf(Longint) для каждого). В этом примере не обязательно добавлять поле для хранения числового значения. Оно может храниться как строковое значение (которое уже обрабатывается в TInputLine) и преобразовываться из строки в числовое значение и обратно методами GetData и SetData соответственно.
Поля
Data Data: PString; Чтение/Запись Указатель на строку, содержащую редактируемую информацию.
MaxLen MaxLen: Integer; Только чтение Максимальная длина, допустимая для строки, включая байт длины.
См. так же: TInputLine.DataSize

CurPos CurPos: Integer; Чтение/ Запись Индекс на точку вставки (т.е. на текущую позицию курсора).

См. так же: TInputLine.SelectAll FirstPos FirstPos: Integer; Чтение/Запись Индекс на первый отображаемый символ.

См. так же: TInputLine.SelectAll

SelStart SelStat: Integer; Только чтение Индекс на начало выбранной области (т.е. на первый символ отмеченного блока).

См. так же: TInputLine.SelectAll

SelEnd SelEnd: Integer; Только чтение Индекс на конец выбранной области (т.е. на последний символ отмеченного блока).

См. так же: TInputLine.SelectAll

Методы

Init constructor Init(var Bounds: TRect; AMaxLen: Integer); Создает прямоугольник ввода с заданными значениями, вызывая TInputLine.Init. State устанавливается в sfCursorVis, Options устанавливается в (ofSelectable + ofFirstClick), и MaxLen устанавливается в AMaxLen. Память распределяется и очищается под AMaxLen + 1 байт и поле Data устанавливается для указания этого распределения.

См. так же: TView.Init, TView.sfCursorVis, TView.ofSelectable, TView.ofFirstClick

Load constructor Load(var S: TStream); Создает и инициализирует объект TInputLine, вызывая TView. Load(S) для загрузки видимого элемента из потока, затем читает целочисленные поля, используя S.Read, распределяет MaxLen+1 байт через Data, вызывая GetMem. Наконец устанавливает байт длины строки и загружает данные из потока двумя дополнительными вызовами S.Read. Load используется совместно с TInputLine.Store для сохранения и восстановления объектов TInputLine из TStream. Перекрывайте этот метод, если Вы определили потомков, содержащих дополнительные поля.

См. так же: TView.Load, TInputLine.Store, TStream.Read

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

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

DataSize function DataSize: Word; virtual; Перекрывается: Иногда Возвращает размер записи для TInputLine.GetData и TInputLine.SetData. По умолчанию возвращается MaxLen+1. Перекройте этот метод, если Вы определили потомков для обработки других типов данных.


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

Draw procedure Draw; virtual; Перекрывается: Редко Рисует прямоугольник ввода и его данные. Прямоугольник рисуется соответствующим цветом в зависимости от того, является ли он sfFocused или нет (т.е. находится ли в видимом элементе курсор или нет) и стрелки рисуются, если строка ввода превышает размер видимого элемента (в любом или в обоих направлениях). Любые выбранные (отмеченный блок) символы рисуются соответствующим цветом.

GetData procedure GetData(var Rec); virtual; Перекрывается: Иногда Записывает DataSize байт из строки Data^ в запись. Используется с TInputLine.SetData в ряде программ, например во временной памяти или при передаче строки ввода в другие видимые элементы. Перекройте этот метод, если Вы определяете потомка для обработки нестроковых типов данных. Используйте этот метод для преобразования Ваших типов данных в строку, редактируемую с помощью TInputLine.

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

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

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Иногда Вызывает TView.HandleEvent, которая обрабатывает все события от мышки и клавиатуры, если прямоугольник ввода выбран. Этот метод реализует стандартные функции редактирования. Функции редактирования включают: отметку блока мышкой; удаление блока, вставку или перекрытие элемента управления с автоматическим изменением формы курсора; автоматический и ручной скроллинг (зависит от относительных размеров строки Data и Size.X); ручной горизонтальный скроллинг через отметку мышкой на кнопках стрелок; ручное движение курсора с помощью стрелок Home и End; удаление символа и блока с помощью Del и Ctrl-G. Видимый элемент перерисовывается при необходимости и поля TInputLine соответственно изменяются.

См. так же: sfCursorIns, TView.HandleEvent, TIputLine.SelectAll

SelectAll procedure SelectAll(Enable: Boolean); Устанавливает CurPos, FirstPos и SelStart в 0. Если Enable установлен в True, SelEnd устанавливается в Length(Data^) выбирая таким образом всю строку ввода. Если Enable установлен в False, SelEnd устанавливается в 0 снимая таким образом выбор всей строки. Наконец, видимый элемент перерисовывается вызовом DrawView.


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

SetData procedure SetData(var Rec); virtual; Перекрывается: Иногда По умолчанию читает DataSize байт из записи в строку Data^ и вызывает SelectAll(True) для установки CurPos, FirstPos и SelStart в 0; SelEnd устанавливается на последний символ Data^ и видимый элемент перерисовывается. Перекройте этот метод, если Вы определили потомка для обработки нестроковых типов данных. Используйте этот метод для преобразования из строки в Ваш тип данных после редактирования с помощью InputLine.

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

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

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

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

См. так же: TView.Store, TInputLine.Load, TStream.Write

Палитра

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

1 2 3 4 +====+====+====+====+ CInputLine | 19 | 19 | 20 | 21 | +==+=+==+=+==+=+==+=+ Пассивный -----+ | | +--- Стрелка Активный -----------+ +-------- Выбранный

Тип FNameStr Objects

================================================================= Объявление FNameStr = String[79];
Функция Строка, содержащая имя файла DOS.

Тип LongRec Objects

================================================================= Объявление LongRec = record Lo, Hi: Word; end;
Функция Полезный тип записи для обработки переменных двойного слова.

Тип PChar Objects

================================================================= Объявление PChar = ^Char;
Функция Определяет указатель на символ.

Тип PString Objects

================================================================= Объявление PString = ^String;
Функция Определяет указатель на строку.

Тип PtrRec Objects

================================================================= Объявление PtrRec = record Ofs, Seg: Word; end;
Функция Запись, содержащая значение сегмента и смещения указателя.

Тип SelectMode Views

================================================================= Объявление SelectMode = (NormalSelect, EnterSelect, LeaveSelect);
Функция Используется внутренне Turbo Vision.
См. также TGroup.ExecView, TGroup.SetCurrent.

Тип TByteArray Objects

================================================================= Объявление TByteArray = array[032767] of Byte;
Функция Тип массива байт для общего использования при приведении типа.
См. также TStringListMaker.

Тип TCommandSet Views

================================================================= Объявление TCommandSet = set of Byte;
Функция TCommandSet полезен для хранения произвольного множества, содержащего до 256 команд. Он позволяет выполнить простое тестирование, соответствует ли данная команда определенному критерию в программах обработки событий и позволяет Вам установить маски команд. Например, методы TView: EnableCommands, DisableCommands, GetCommands и SetCommands используют аргументы типа TCommandSet. Множество команд может быть объявлено и инициализировано, используя синтаксис Паскаля:
CurCommandSet: TCommandSet = [0255] - [cmZoom, cmClose, cmResize, cmNext];
См. также cmXXXX, TView.DisableCommands, TView.EnableCommands, TView.GetCommands, TView.SetCommands.

Тип TDrawBuffer Views

================================================================= Объявление TDrawBuffer = array[0MaxViewWidth-1] of Word;
Функция Тип TDrawBuffer используется для объявления буферов для методов Draw различных видимых элементов. Обычно данные и атрибуты сохраняются и форматируются строка за строкой в TDrawBuffer, а затем выводятся на экран:
var B: TDrawBuffer; begin MoveChar(B, ' ', GetColor(1), Size.X); WriteLine(0, 0, Size.X, Size.Y, B); end;
См. также TView.Draw, MoveBuf, MoveChar, MoveCStr, MoveStr.

Тип TEvent Drivers

================================================================= Объявление TEvent = record What: Word; case Word of evNothing: (); evMouse: ( Buttons: Byte; Double: Boolean; Where: TPoint); evKeyDown: ( case Integer of O: (KeyCode: Word); 1: (CharCode: 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;
Функция Тип записи с вариантами TEvent играет фундаментальную роль в стратегии управления событиями в Turbo Vision. Внешние события, такие как события от клавиатуры и от мышки и события-команды, генерируемые взаимодействием видимых элементов, сохраняются и передаются как записи TEvent.
См. также evXXXX, HandleEvent методы, GetKeyEvent, GetMouseEvent

Тип TItemList Objects

================================================================= Объявление TItemList = array[0MaxCollectionSize - 1] of Pointer;
Функция Массив общих указателей используется внутренне объектами TCollection.

Тип TMenu Menus

================================================================= Объявление TMenu = record Items: PMenuItem; Default: PMenuItem); end;
Функция Тип TMenu представляет один уровень дерева меню. Поле Items указывает на список TMenuItems и поле Default указывает на умалчиваемый элемент внутри этого списка (элемент выбирается по умолчанию при открытии этого меню). Объект TMenuView (потомками которого являются TMenuBar и TMenuBox) имеет поле Menu, которое указывает на TMenu. Записи TMenu создаются и удаляются с помощью подпрограмм NewMenu и DisposeMenu.
См. также TMebuView, TMenuItem, NewMenu, DisposeMenu, TMenuView.Menu поля

Тип TMenuItem Menus

================================================================= Объявление TMenuItem = record Next: PMenuItem; Name: PString; Command: Word; Disabled: Boolean; KeyCode: Word; HelpCtx: Word; case Integer of 0: (Param: PString); 1: (SubMenu: PMenu); end; end;
Функция Тип TMenuItem представляет элемент меню, который может быть обычным элементом, подменю или строкой-разделителем. Next указывает на следующий TMenuItem в списке элементов меню, или равен nil, если это последний элемент. Name указывает на строку, содержащую имя элемента меню или равен nil, если элемент меню является строкой-разделителем. Command содержит событие-команду (см. константы cmXXXX) генерируемую при выборе элементов меню или 0, если элемент меню представляет подменю. Disable - True, если элемент меню запрещен, False, в противном случае. KeyCode содержит скан-код горячей клавиши связанной с элементом меню или 0, если элемент меню не имеет горячей клавиши. HelpCtx содержит номер контекстной подсказки элемента меню (значение hcNoContext указывает, что элемент меню не имеет контекстной подсказки). Если элемент - меню это обычный элемент, Param содержит указатель на параметр строки (отображаемый справа от элемента в TMenuBox) или nil, если элемент не имеет параметра строки. Если элемент меню - это подменю, Submenu указывает на структуру подменю. Записи TMenuItem создаются использованием функций NewItem, NewLine и NewSubmenu.
См. также TMenu, TMebuView, NewItem, NewLine, NewSubMenu

Тип TMenuStr Menus

================================================================= Объявление TMenuStr = string[31];
Функция Тип строки, используемый NewItem и NewSubMenu. Максимальный размер заголовка элемента меню - 31 символ.
См. также NewItem, NewSubMenu

Тип TPalette Views

================================================================= Объявление TPalette = String;
Функция Тип строки, используемый для объявления палитр Turbo Vision.
См. также GetPalette методы

Тип TScrollChars Views

================================================================= Объявление TScrollChars = array[04] of Char;
Функция Массив, представляющий символы, используемые для рисования TScrollBar.
См. также TScrollBar

Тип TSItem Dialogs

================================================================= Объявление TSItem = record Value: PString; Next: PSItem; end;
Функция Тип записи TSItem обеспечивает односвязный список из PString. Подобные списки могут быть полезны во многих программах на Turbo Vision, где не требуется полная гибкость коллекций строк (см. TCluster, например). Функция NewSItem предназначена для добавления записей в список TSItem.

Тип TStatusDef Menus

================================================================= Объявление TStatusDef = record Next: PStatusDef; Min, Max: Word; Items: PStatusItem; end;
Функция Тип TStatusDef представляет определение строки статуса. Поле Next указывает на следующий TStatusDef в списке строк статуса или nil, если это последняя строка статуса. Min и Max определяют диапазон контекста подсказки, который соответствует строке статуса. Items указывает на список элементов строки статуса или nil, если в строке статуса нет элементов. Объект TStatusLine (строка статуса) имеет указатель на список записей TStatusDef и будет всегда отображать первую строку статуса, для которой текущая контекстная подсказка находится внутри диапазона Min и Max. Программа Turbo Vision автоматически корректирует строку статуса, вызывая TStatusLine.Update из TProgram.Idle. Записи TStatusDef создаются использованием функции NewStatusDef.
См. также TStatusLine, TProgram.Idle, функция NewStatusDef

Тип TStatusItem Menus

================================================================= Объявление TStatusITEm = record Next: PStatusItem; Text: PString; KeyCode: Word; Command: Word; end;
Функция Тип TStatusItem представляет элемент строки статуса, который может быть видим или невидим. Next указывает на следующий TStatusItem в списке элементов строки статуса или nil, если это последний элемент. Text указывает на строку, содержащую надпись элемента статуса (такую как 'Alt-X Exit') или nil, если элемент статуса невидим (в таком случае элемент служит только для определения горячей клавиши). KeyCode содержит скан-код горячей клавиши связанной с элементом статуса или 0, если элемент статуса не имеет горячей клавиши. Command содержит команду-событие (см. константы cmXXX) генерируемую при выборе элемента статуса. Функция записи TStatusItem не только в определении визуализации строки статуса, она также используется для определения горячей клавиши, чьи коды автоматически отображаются в команды. Метод TProgram. GetEvent вызывает TStatusLine.HandleEvent для всех событий evKeyDown. TStatusLine.HandleEvent сканирует текущую строку статуса на элементы, содержащие данный код клавиши и, если один из них найден, он преобразует это событие evKeyDown в событие evCommand со значением Command данным в TStatusItem. Записи TStatusItem создаются использованием функции NewStatusKey.
См. также TStatusLine, NewStatusKey, TStatusLine.HandleEvent

Тип TStreamRec Objects

================================================================= Объявление TStreamRec = ^TStreamRec; TStreamRec = record ObjType: Word; VmLink: Word; Load: Pointer; Store: Pointer; Next: Word; end;
Функция Тип объекта Turbo Vision должен быть зарегистрирован TStreamRec, до его загрузки или сохранения на объекте TStream. Подпрограмма RegisterTypes регистрирует тип объекта записью TStreamRec.
Поля в регистрационной записи потока определены:
Таблица 14.33. Поля записи потока.
-------------------------------------------------------------- Поле Содержимое -------------------------------------------------------------- ObjType Уникальный числовой идентификатор для типа объекта VmtLine Связь типа объекта с элементом VMT Load Указатель на констрактор Load объектного типа Store Указатель на метод Store объектного типа Next Указатель на следующую TStreamRec --------------------------------------------------------------
Turbo Vision резервирует значения идентификаторов объектных типов от 0 до 999 для внутреннего использования. Программист может определить свои значения в диапазоне от 1,000 до 65,535. По соглашению, tStreamRec для типа объекта Txxxx называется Rxxxx. Например, TStreamRec для типа TCalculator называется RCalculator, как показано в следующем коде:
type TCalculator = object(TDialog) constructor Load(var S: TStream); procedure Store(var S: TStream); . end;
const RCalculator: TStreamRec = ( ObjType: 2099; VmtLink: Ofs(TypeOf(TCalculator)^); Load: @TCalculator.Load; Store: @TCalculator.Store);
begin RegisterType(RCalculator); . end;
См. также RegisterType

Тип TStrIndex Objects

================================================================= Объявление TStrIndex = array[09999] of TStrIndexRec;
Функция Используется внутренне TStringList и TStrListmaker.

Тип TStrIndexRec Objects

================================================================= Объявление TStrIndexRec = record Key, Count, Offset: Word; end;
Функция Используется внутренне TStringList и TStrListmaker.

Тип TSysErrorFunc Drivers

================================================================= Объявление TSysErrorFunc = function(ErrorCode: Integer; Drive: Byte): Integer;
Функция Определяет тип и функцию обработчика системной ошибки.
См. также SysErrorFunc, SystemError, InitSysError, DoneSysError

Тип TTerminalBuffer TextView

================================================================= Объявление TTerminalBuffer = array[065519] of Char;
Функция Используется внутренне TTerminal.
См. также TTerminal

Тип TTitleStr Views

================================================================= Объявление TTitleStr = string[80];
Функция Используется для объявления строк текста для заголовков окон.
См. также TWindow.Title

Тип TVideoBuf Views

================================================================= Объявление TVideoBuf = array[03999] of Word;
Функция Используется для объявления видеобуферов.
См. также TGroup.Buffer

Тип TWordArray Objects

================================================================= Объявление TWordArray = array[016383] of Word;
Функция Тип массива слов для общего использования.

Тип WordRec Objects

================================================================= Объявление WordRec = record Lo, Hi: Byte; end;
Функция Утилитная запись, позволяющая доступ к младшему и старшему биту слова.
См. также LongRec

Типология объектов.

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

Типы.

Типы преобразования записей.
------------------------------------------------------------- Тип Использование ------------------------------------------------------------- FNameStr Строка имени файла DOS LongRec Преобразует Longint в старшее и младшее слово PChar Указатель для динамического распределения символа PString Указатель для динамических строк PtrRec Преобразует Pointer в сегмент и смещение TByteArray Массив значений Byte, используемый для приведения типов TWordArray Массив значений Word, используемый для приведения типов WordRec Преобразует Word в старший и младший байт -------------------------------------------------------------
Типы модуля Objects.
------------------------------------------------------------- Тип Использование ------------------------------------------------------------- TBufStream Буферизованный поток DOS Turbo Vision TCollection По существу полиморфный массив TDosStream Поток Turbo Vision для файла DOS TEmsStream Поток Turbo Vision в EMS памяти TItemList Массив указателей, используемый коллекциями TObject Базовый объект иерархии Turbo Vision TPoint Объект для построения точки на экране TRect Объект из двух точек для определения области на экране TResourceCollection Специализированный TCollection для ресурсов TResourceFile Объект для сохранения ресурсов на диске TSortedCollection Специализированный TCollection для автоматической сортировки TStream Базовый тип определения потока Turbo Vision TStreamRec Запись регистрации потока TStrIndex Массив TStrIndexRec TStrIndexRec Запись строковых индексов, используемая TStrIndex TStringCollection Специализированный TSortedCollection для для строк TStringList Объект списка, используемый для ресурсов строк TStrListMaker Специальный объект для создания списков строк -------------------------------------------------------------

TLabel Dialogs

+-------------+ | TObject | +-----+-------+ +-----+-------+ | TView | +-----+-------+ +=====+=======+ | TStaticText | +=====+=======+ +-----+-------+ | TLabel | +-------------+
Объект TLabel - это текст в видимом элементе, который может быть выбран (подсвечен) отметкой мышки, клавишами курсора или коротким выбором Alt-буква. Метка обычно присоединена через указатель PView к другому видимому элементу управления, такому как строка ввода, кластер или просмотр списка для пояснения пользователю. Выбор (или нажатие) метки будет выбирать присоединенный элемент управления. Метка так же будет подсвечиваться, когда выбран связанный элемент управления.
Поля
Link Link: PView; Только чтение Указывает на элемент управления, связанный с этой меткой.
Light Light: Boolean; Только чтение Если True - метка, а связанный с ней элемент управления будут выбираться и подсвечиваться.
Методы
Init constructor Init(var Bounds: TRect; AText: String; ALink: PView); Создает объект TLabel заданного размера, вызывая TStaticText.Init, затем устанавливает поле Link в ALink для связывания с элементом управления (задайте Alink равным nil, если элемент управления не требуется). Поле Option устанавливается в ofPreProcess и ofPostProcess. EventMask устанавливается evBroadcast. Поле AText назначается полю Text через TStaticText.Init. AText может задать клавишу короткого набора для метки, окружив соответствующую букву "~".
См. так же: TStaticText.Init
Load constructor Load(var S: TStream); Создает и загружает объект TLabel из потока, вызывая TStaticText.Load, GetPeerViewPtr(S, Link) для установки связи с ассоциированным элементом управления (если он есть).
См. так же: TLabel.Store
Draw procedure Draw; virtual; Перекрывается: Никогда Рисует видимый элемент соответствующим цветом из палитры по умолчанию.
GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на палитру по умолчанию CLabel.
HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Никогда Обрабатывает все события, вызывая TStaticText.HandleEvent. Если evMouseDown или если получено событие от клавиши короткого набора, выбирается связанный элемент управления (если он есть). Этот метод так же обрабатывает общие события cmReceivedFocus и cmReleasedFocus от связанного элемента управления для настройки значения поля Light и перерисовки метки.
См. так же: TView.HandleEvent, cmXXXX константы команд
Store procedure Store(var S: TStream); Сохраняет видимый элемент в потоке, вызывая TStaticText.Store, затем записывает связь с ассоциированным элементом управления, вызывая PutPeerViewPtr.
См. так же: TLabel.Load
Палитра
Метки используют палитру по умолчанию CLabel для отображения в элементы 7, 8 и 9 палитры стандартного диалога.
1 2 3 4 +====+====+====+====+ CLabel | 7 | 8 | 9 | 9 | +==+=+==+=+==+=+==+=+ Нормальный текст + | | +--- Короткая выбранная Выбранный текст ------+ +-------- Нормальная выбранная

TListBox Dialogs

+-------------+ | TObject | +------+------+ +------+------+ | TView | +------+------+ +------+------+ | TListViewer | +------+------+ +======+======+ | TListBox | +=============+
TListBox, порожденный от TListViewer, помогает Вам создавать наиболее часто используемые окна списков отображающих коллекции строк таких, как имена файлов. Объекты TListBox отображают списки таких элементов в одну или более колонок с возможной вертикальной полосой скроллинга. Горизонтальные полосы скроллинга не поддерживаются в TListViewer. Наследуемые методы TListViewer позволяют Вам выбрать (и подсветить) элементы мышкой или через клавиатуру. TListBox не перекрывает TListViewer.HandleEvent и TListViewer.Draw, поэтому Вы должны просмотреть их описание до использования TListBox в своих программах. TListBox имеет дополнительное поле List, которое указывает на объект TCollection, содержащий выводимые и выбираемые элементы. Ответственность за вставку данных в TCollection лежит на Вас так же как и действия, выполняемые при выборе элемента. TListViewer наследует метод Done от TView, поэтому Вы так же отвечаете за освобождение содержимого List при окончании работы. Вызов NewList будет освобождать старый список, поэтому вызов NewList(nil) и последующее освобождение окна списка будут освобождать все.
Поля
List List: PCollection; Только чтение List указывает на коллекцию элементов для просмотра. Это может быть коллекция PString, представляющая текстовые элементы.
Методы
Init constructor Init(var Bounds: TRect; ANumCols: Word; AScrollBar: PScrollBar); Создает окно списка с заданным размером, числом колонок и вертикальной полосой скроллинга, указываемой указателем AScrollBar. Этот метод вызывает TListViewer.Init с аргументом горизонтальной полосы скроллинга nil. Поле List первоначально nil (пустой список) и наследуемое поле Range устанавливается в 0. Ваша программа должна задать TCollection, содержащую строки (или другие объекты для вывода). Поле List должно быть установлено на эту коллекцию с использованием NewList.

См. так же: TListViewer.Init, TListBox.NewList

Load constructor Load(var S: TStream); Создает объект TListBox и загружает его значениями из TStream. Этот метод вызывает метод TListViewer.Load, затем устанавливает List, читая указатель List из S с помощью S. Get.

См. так же: TListViewer.Load, TListBox.Store, TStream.Get

DataSize function DataSize: Word; virtual; Перекрывается: Иногда Возвращает размер читаемых и записываемых данных для записей, передаваемых в TListBox.GetData и TListBox.SetData. Эти 3 метода полезны для инициализации групп. По умолчанию TListBox.DataSize возвращает размер указателя плюс размер слова (для List и выбранного элемента). Вам может потребоваться перекрыть этот метод для Вашей программы.

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

GetData procedure GetData(var Rec); virtual; Перекрывается: Иногда Записывает данные объекта TListBox в запись. По умолчанию этот метод пишет в Rec текущие поля List и Focused. Вам может потребоваться перекрыть этот метод для Вашей программы.

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

GetText function GetText(Item: Integer; MaxLen: Integer): String; virtual; Перекрывается: Иногда Возвращает строку из вызываемого объекта TListBox. По умолчанию возвращаемая строка получается из элемента Item в TCollection, используя PString(List^.At(Item))^. Если List содержит не строковые объекты, Вам необходимо перекрыть этот метод. Если List - nil, GetText возвращает пустую строку.

См. так же: TCollection.At

NewList procedure NewList(AList: PCollection); virtual; Перекрывается: Редко Если AList не nil, новый список, заданные в AList, заменяет текущий List. Наследуемое поле Range устанавливается в поле Count новой TCollection и первый элемент активизируется вызовом FocusItem(0). Наконец, новый список отображается вызовом DrawView. Заметим, что если предыдущее поле List не nil, оно освобождается до назначения нового списка значений.

См. так же: TListBox.SetData, TListViewer.SetRange, TListViewer.FocusItem, TView.DrawView


SetData procedure SetData(var Rec); virtual; Перекрывается: Иногда Заменяет текущий список со значениями List и Focused, считанными из Rec. SetData вызывает NewList так, чтобы новый список отображался с корректным активным элементом. Как с GetData и DataSize, Вам может потребоваться перекрыть этот метод для Вашей программы.

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

Store procedure Store(var S:TStream); Записывает окно списка в TStream, вызывая TListView.Store, затем выводит коллекцию в список, вызывая S.Put(List).

См. так же: TListBox.Load, TListViewer.Store, TStream.Put

Палитра

Окна списка используют палитру по умолчанию CListViewеr, отображая элементы с 26 по 29 в палитру стандартной программы.

1 2 3 4 5 +===+===+===+===+===+ CListViewer | 25| 26| 27| 28| 29| +=+=+=+=+=+=+=+=+=+=+ Активный ------+ | | | +-- Разделитель Неактивный --------+ | +------ Выбранный Сфокусированный -------+

TListViewer Views

+-------------+ | TObject | +-----+-------+ +-----+-------+ | TView | +-----+-------+ +=====+=======+ | TListViewer | +=====+=======+ +-----+-------+ | TListBox | +-------------+
Тип объекта TListViewer - это базовый тип, из которого порождаются просмотры списков различного вида такие, как TListBox. Основные поля и методы TListViewer предоставляют следующие функции: - Видимый элемент для отображения связанных списков элементов (но не списков). - Управление одним или двумя полосами скроллинга. - Скроллинг списков по двум координатам. - Загрузка и сохранение видимого элемента и его полос скроллинга из и в TStream. - Возможность выбора элементов списка мышкой или клавишами. - Метод Draw поддерживающий изменение размера и скроллинг.
TListViewer имеет абстрактный метод GetText так, что Вам потребуется предоставить механизм создания и манипуляции отображаемых элементов текста. TListViewer не имеет собственного механизма запоминания списка. Используйте его для отображения скроллингуемых списков, массивов, связанных списков или подобных структур данных. Вы так же можете использовать его наследников таких, как TListBox, которые ассоциируют коллекцию с просмотром списка.
Поля
HScroolBar HScrollBar: PScrollBar; Только чтение Указатель на горизонтальную полосу скроллинга, связанную с этим видимым элементом. Если nil, видимый элемент не имеет такой полосы скроллинга.
VScroolBar VScrollBar: PScrollBar; Только чтение Указатель на вертикальную полосу скроллинга, связанную с этим видимым элементом. Если nil, видимый элемент не имеет такой полосы скроллинга.
NumCols NumCols: Integer; Только чтение Число колонок в элементе управления списком.
TopItem TopItem: Integer; Чтение/Запись Номер верхнего отображаемого элемента. Элементы нумеруются от 0 до Range-1. Это число зависит от числа колонок, размера видимого элемента и значения Range.
См. так же: Range
Focused Focused: Integer; Только чтение Номер активного элемента. Элементы нумеруются от 0 до Range-1. Первоначально устанавливается в 0 - первый элемент, Focused может изменяться отметкой мышки или выбором через пробел.

См. так же: Range

Range Range: Integer; Только чтение Общее число элементов в списке. Элементы нумеруются от 0 до Range-1.

TListViewer.SetRange

Методы

Init constructor Init(var Bounds: TRect; ANumCols: Integer; AHScrollBar, AVScrollBar: PScrollBar); Создает и инициализирует объект TListViewer заданного размера, вызывая TView.Init. Поле NumCols устанавливается в ANumCols. Options устанавливается в (ofFirstClick + ofFirstSelectable) так, что выбор мышкой этого элемента будет передаваться в TListViewer.HandleEvent. EventMask устанавливается в evBroadcast. Начальные значения Range и Focused - 0. Указатели на вертикальную и/или горизонтальную полосы скроллинга можно задать через аргументы AVScrollBar и AHSсrollBar. Если Вам не нужны полосы скроллинга, можно установить один из них или оба в nil. Эти значения аргументов назначаются полям VScrollBar и HScrollBar. Если Вы задали полосы скроллинга, их поля PgStep и ArStep будут настраиваться в соответствии с размером TListViewer и числом колонок. Например, для одноколоночного TListViewer вертикальный PgStep равен Size.Y-1, а вертикальный ArStep равен 1.

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

Load Load constructor Load(var S: TStream); Создает объект TListViewer, вызывая TView.Load. Полосы скроллинга, если они есть, так же загружаются из потока с использованием вызовов GetPeerViewPtr. Все целочисленные поля загружаются с использованием S.Read.

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

ChangeBounds ChangeBounds(var Bounds: TRect); virtual; Перекрывается: Никогда Изменяет размер объекта TListViewer, вызывая TView.ChangeBounds. Если назначена горизонтальная полоса скроллинга, этот метод при необходимости настраивает PgStep.

См. так же: TView.ChangeBounds, TScrollBar.ChangeStep

Draw procedure Draw; virtual; Перекрывается: Никогда Рисует объект TListViewer палитрой по умолчанию, вызывая GetText для каждого отображаемого элемента, принимая во внимание активные и выбранные элементы и является ли видимый элемент sfActive.


См. так же: TListViewer.GetText

FocusItem procedure FocusItem(Item: Integer); virtual; Перекрывается: Никогда Делает данный элемент активным, устанавливая поле Focused в Item. Этот метод так же устанавливает поле Value вертикальной полосы скроллинга (если есть) в Item и настраивает поле TopItem.

См. так же: TListViewer.IsSelected, TScrollBar.SetValue

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

GetText function GetText(Item: Integer; MaxLen: Integer): String; virtual; Перекрывается: Всегда Это абстрактный метод. Порожденные типы должны определить механизм для возвращения строки, не превышающей MaxLen по индексу, заданному в Item.

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

IsSelected function IsSelected(Item: Integer): Boolean; virtual; Перекрывается: Никогда Возвращает True, если Item активный, т.е. если Item = Focused.

См. так же: TListViewer.FocusItem

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Редко Обрабатывает события, вызывая TView.HandleEvent. Отметки мышкой и "автоматические" движения по списку будут изменять активный элемент. Активные элементы могут быть выбраны двойным нажатием мышки. Обрабатываются события от клавиатуры: пробел выбирает текущий активный элемент; клавиши стрелок, PgUp, PgDn, Ctrl-PgUp, Ctrl-PgDn, Home и End изменяют активный элемент. Наконец общие сообщения от полос скроллинга обрабатываются, изменяя активный элемент и перерисовывая видимый элемент.

См. так же: TView.HandleEvent, TListViewer. FocusItem

SelectItem procedure SelectItem(Item: Integer); virtual; Перекрывается: Иногда Абстрактный метод для выбора элемента, индексируемого через Item.

См. так же: TListViewer.FocusItem

SetRange procedure SetRange(ARange: Integer); Устанавливает поле Range в ARange. Если вертикальная полоса скроллинга была задана, ее параметры настраиваются. Если текущий активный элемент выходит за новый Range, поле Focused устанавливается в 0.

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


SetState procedure SetState(AState: Word; Enable: Boolean); virtual; Перекрывается: Редко Вызывает TView. SetState для изменения состояния объекта TListViewer, если Enable - True. В зависимости от аргумента AState это приводит к отображению или скрытию видимого элемента. Дополнительно, если AState - sfSelected и sfActive, полосы скроллинга перерисовываются; если AState - sfSelected, но не sfActive, полосы скроллинга скрываются.

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

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

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

Палитра

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

1 2 3 4 5 +===+===+===+===+===+ CListViewer | 25| 26| 27| 28| 29| +=+=+=+=+=+=+=+=+=+=+ Активный ------+ | | | +-- Разделитель Неактивный --------+ | +------ Выбранный Сфокусированный -------+

TMenuBar Menus

+------------+ | TObject | +------+-----+ +------+-----+ | TView | +------+-----+ +------+-----+ | TMenuView | +----+---+---+ +--------+ +------+ +====+=====+ +----+-----+ | TMenuBar | | TMenuBox | +==========+ +----------+
Объекты TMenuBar представляют полосы горизонтального меню, из которого меню может быть выбрано через: - прямую отметку. - F10 и короткую клавишу. - выбор (подсветку) и нажатие Enter. - горячие клавиши. Выборы главного меню отображаются в верхней полосе меню. Они представлены объектом типа TMenuBar обычно принадлежащему объекту TApplication. Подменю отображаются в объектах типа TMenuBox. TMenuBar и TMenuBox порождаются от абстрактного типа TMenuView. Для большинства программ на Turbo Vision Вы не включаете прямо объекты меню. Перекрывая TApplication.InitMenuBar соответствующим набором вложенных вызовов New, NewSubMenu, NewItem и NewLine, Turbo Vision выполняет это.
Методы
Init constructor Init(var Bounds: TRect; AMenu: PMenu); Создает полосу меню, заданную через Bounds, вызывая TMenuView.Init. GrowMode установлена в gfGrouHiX. Поле Options установлено в ofPreprocess для возможности работы с горячими клавишами. Поле меню установлено в AMenu, задавая элементы меню.
См. так же: TMenuView.Init, gfXXXX флаги grow mode, ofXXXX флаги опций, TMenuView.Menu
Draw procedure Draw; virtual; Перекрывается: Редко Рисует полосу меню палитрой по умолчанию. Поля Name и Disabled каждой записи TMenuItem в связанном списке читаются, чтобы установить элементы меню в корректный цвет. Текущий элемент Current подсвечивается.
GetItemRect procedure GetIteRect(Item: PMenuItem; var R: TRect); virtual; Перекрывается: Никогда Перекрывает абстрактный метод в TMenuView. Возвращает прямоугольник, занимаемый элементом меню в R. Используется для определения, находится ли отметка мышки в данном элементе меню.
См. так же: TMenuView.GetItemRect
Палитра
Полосы меню, как и все видимые элементы меню, используют палитру по умолчанию CMenuView для отображения элементов со 2 по 7 в палитру стандартной программы.
1 2 3 4 5 6 +====+====+====+====+====+====+ CMenuView | 2 | 3 | 4 | 5 | 6 | 7 | +==+=+==+=+==+=+==+=+==+=+==+=+ Нормальный текст -+ | | | | +-- Короткий выбранный Запрещенный текст -----+ | | +------ Запрещенный выбранный Короткий текст -------------+ +------------ Нормальный выбранный

TMenuBox Menus

+------------+ | TObject | +------+-----+ +------+-----+ | TView | +------+-----+ +------+-----+ | TMenuView | +----+---+---+ +--------+ +------+ +----+-----+ +====+=====+ | TMenuBar | | TMenuBox | +----------+ +==========+
Объекты MenuBox представляют вертикальные прямоугольники меню. Они могут содержать произвольный список выбираемых действий, включая элементы подменю. Как и в полосе меню, для указания запрещенных элементов используется цвет. Прямоугольники меню могут создаваться как подменю полосы меню или других прямоугольников меню или могут использоваться как отдельные выпадающие меню.
Методы
Init constructor Init(var Bounds: TRect; Amenu: PMenu; AParentMenu: PMenuView); Init настраивает параметр Bounds в соответствии с шириной и длиной элементов в AMenu, затем создает прямоугольник меню, вызывая TMenuView.Init. Бит ofPreProcess в поле Options установлен так, чтобы могли использоваться горячие клавиши. Установка State включает sfShadow. Поле меню установлено в AMenu, которое задает элементы меню. Поле ParentMenu установлено в AParentMenu.
См. так же: TMenuView.Init, sfXXXX флаги состояний, ofXXXX флаги опций, TMenuView.Menu, TMenuView.ParentMenu
Draw procedure Draw; virtual; Перекрывается: Редко Рисует рамку прямоугольника меню и элементы меню цветом по умолчанию.
GetItemRect procedure GetItemRect(Item: PMenuItem; var R: TRect; virtual; Перекрывается: Редко Перекрывает абстрактный метод в TMenuView. Возвращает прямоугольник, занятый элементом меню. Используется для определения, находится ли отметка мышкой на данном элементе меню.
См. так же: TMenuView.GetItemRect
Палитра
Прямоугольники меню, как и все видимые элементы меню, используют палитру по умолчанию CMenuView для отображения элементов со 2 по 7 в палитру стандартной программы.
1 2 3 4 5 6 +====+====+====+====+====+====+ CMenuView | 2 | 3 | 4 | 5 | 6 | 7 | +==+=+==+=+==+=+==+=+==+=+==+=+ Нормальный текст -+ | | | | +-- Короткий выбранный Запрещенный текст -----+ | | +------ Запрещенный выбранный Короткий текст -------------+ +------------ Нормальный выбранный

TMenuView Menus

+------------+ | TObject | +------+-----+ +------+-----+ | TView | +------+-----+ +======+=====+ | TMenuView | +====+===+===+ +--------+ +------+ +----+-----+ +----+-----+ | TMenuBar | | TMenuBox | +----------+ +----------+
TMenuView предоставляет тип абстрактного меню, из которого порождаются полосы и прямоугольники меню. Вы вероятно никогда не будете создавать экземпляров TMenuView.
Поля
ParentMenu ParenMenu: PMenuView; Только чтение Указатель на объект TMenuView (или порожденный от него), который владеет этим меню. Заметим, что TMenuView - не группа. Здесь принадлежность намного проще, чем для TGroup, позволяя вложенность меню: выбор подменю и обратный возврат в "родительское" меню. Выборы из полос меню, например, обычно приводят к "выпаданию" подменю. В этом случае полоса меню - предок прямоугольника меню.
См. так же: TMenuBox.Init
Menu Menu: PMenu; Только чтение Указатель на запись TMenu для этого меню, которая содержит связанный список элементов меню. Указатель меню позволяет обращаться ко всем полям элементов меню в видимом элементе меню.
См. так же: TMenuView.FindItem, TMenuView.GetItemRect, тип TMenu
Current Current: PMenuItem; Только чтение Указатель на текущий выбранный элемент меню.
Методы
Init constructor Init(var Bounds: TRect); Вызывает TView.Init, чтобы создать объект TMenuView размера Bounds. По умолчанию EventMask установлено в evBroadcast. Этот метод не предназначен для использования с экземплярами объектов TMenuView. Он предназначен для вызова из порожденных типов TMenuBar и TMenuBox.
См. так же: TView.Init, evBroadcast, TMenuBar.Init, TMenuBox.Init
Load constructor TMenuView.Load(var S: TStream); Создает объект TMenuView и загружает его из потока S вызывая TView.Load, а затем загружая элементы в список меню.
См. так же: TView.Load, TMenuView.Store
Execute function Execute: Word; virtual; Перекрывается: Никогда Выполняет видимый элемент меню до тех пор, пока пользователь не выберет элемент меню или не отменит этот процесс. Возвращает команду, назначенную выбранному элементу меню, или 0, если меню было отменено. Этот метод должен вызываться только из ExecView.

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

FindItem function FindItem(Ch: Char): PMenuItem); Возвращает указатель на элемент меню, который имеет Ch как горячую клавишу (подсвеченный символ). Возвращает nil, если такой элемент не найден или этот элемент запрещен. Заметим, что для Ch не различаются прописные и строчные буквы.

GetItemRect procedure GetItemRect(Item: PMenuItem; var R: TRect); virtual; Перекрывается: Всегда Этот метод возвращает в R прямоугольник, занимаемый данным элементом меню. Используется для определения, не был ли отмечен данный элемент мышкой. Наследники TMenuView должны перекрывать этот метод для того, чтобы откликаться на события от мышки.

См. так же: TMenuBar.GetItemRect, TMenuBox.GetItemRect

GetHelpCtx function GetHelpCtx: Word; virtual; Перекрывается: Иногда По умолчанию этот метод возвращает контекст подсказки текущего элемента меню. Если это hcNoContext, выбирается текущий контекст родительского меню. Если родительского меню нет, GetHelpCtx возвращает hcNoContext.

См. так же: hcXXXX константы контекста help

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

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Никогда Вызывается для обработки событий меню. Определяет, какой элемент меню был выбран мышкой или клавиатурой (включая горячие клавиши) и генерирует соответствующее командное событие через PutEvent.

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

HotKey function HotKey(KeyCode: Word): PMenuItem; Возвращает указатель на элемент меню, связанный с горячей клавишей, заданной через KeyCode. Возвращает nil, если не существует такого элемента меню или если элемент запрещен. Горячие клавиши - это обычно функциональные клавиши или комбинации Alt ключей и определяются аргументами в вызовах NewItem и NewSubMenu в InitMenuBar. Этот метод используется в TMenuView.HandleEvent для определения, будет ли событие от клавиатуры вибирать элемент меню.

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

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

Палитра

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

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

TObject Objects

+===========+ | TObject | ++=+=+=+=+=++ +---------+ | | | | +---------+ +-------+-------+ | | | | +-------+-------+ | TCollection | | | | | | TResourceFile | +---------------+ | | | | +---------------+ +-----------+ | | +----------+ +-------+-------+ | | +-------+-------+ | TStream | | | | TStringList | +---------------+ | | +---------------+ +-------------+ +-------------+ +-------+-------+ +-------+-------+ | TStrListMaster| | TView | +---------------+ +---------------+
TObjеct - это начальная точка иерархии объектов Turbo Vision. Как базовый объект он не имеет предков, но имеет множество потомков. Кроме TPoint и ТRect все стандартные объекты Turbo Vision порождены в конечном счете от TObject. Любой объект, использующий потоки Turbo Vision, должен происходить от TObject.
Методы
Init constructor Init; Распределяет память в куче для объекта и заполняет его нулями. Вызывается из констракторов всех порожденных объектов. Заметим, что TObject.Init будет заполнять все поля в потомках так, что Вы должны вызвать TObject.Init до инициализации любых полей в констракторах порожденных объектов.
Free procedure Free; Освобождает объект и вызывает дестрактор Done.
Done destructor Done; virtual; Выполняет необходимую очистку и освобождение динамических объектов.

TObject.

TObject - это абстрактный базовый тип без полей. Это предок всех объектов Turbo Vision, за исключением TPoint и TRect. TObject предоставляет 3 метода: Init, Free и Done. Констрактор Init формирует основу для всех констракторов Turbo Vision, выполняя распределение памяти. Free освобождает это распределение. Done - это абстрактный дестрактор, который должен быть перекрыт в потомках. Все объекты, которые Вы намереваетесь использовать с потоками Turbo Vision должны быть производными от TObject. Потомки TObject делятся на 2 больших семейства: видимые и невидимые элементы. Видимые элементы призводны от TView, который дает им специальные свойства, отсутствующие у невидимых элементов. Видимые элементы могут рисовать себя и обрабатывать события, посланные им. Невидимые объекты предоставляют набор утилит для обработки потоков и коллекций других объектов, включая видимые элементы, но они не могут быть визуализированы напрямую.

TParamText Dialogs

TParamText порожден от TStaticText, который использует параметризованные строки текста для форматного вывода, используя процедуру FormatStr.
Поля
ParamCount ParamCount: Integer; ParamCount указывает число параметров, содержащихся в ParamList.
См. так же: TParamText.ParamList
ParamList ParamList: Pointer; ParamList - это нетипированный указатель на массив или запись указателей или значений типа LongInt, используемый как параметр форматирования для текстовой строки.
Методы
Init constructor Init(var Bounds: TRect; AText: String; AParamCount: Integer); Инициализирует объект статического текста, вызывая TStaticText.Init с заданным Bounds и текстовой строкой AText, которая может содержать спецификаторы формата в форме %[-][nnn]X, который будет замещаться параметрами, переданными во время выполнения. Число параметров, переданных в ParamCount, присваивается полю ParamCount. Спецификаторы формата детально описаны в процедуре FormatStr.
См. так же: TStaticText.Init, FormatStr процедуры
Load constructor Load(var S: TStream); Распределяет объект TParamText в куче и загружает его занчение из потока S, вызывая TStaticText.Load, затем читая поле ParamCount из потока.
См. так же: TStaticText.Load
DataSize function DataSize: Word; virtual; Возвращает размер данных, требуемый параметрами объекта, т.е. ParamCount*SizeOf(LongInt).
GetText procedure GetText(var S: String); virtual; Создает форматированную строку текста в S, выполняя объединение параметров, заданных в ParamList в текстовую строку Text с помощью вызова FormatStr(S, Text^, ParamList^).
См. так же: FormatStr процедуры
SetData procedure SetData(var Rec); virtual; Этот видимый элемент читает DataSize байт в ParamList из Rec.
См. так же: TView.SetData
Store procedure Store(var S: TStream); Сохраняет объект в потоке S, вызывая TStaticText.Store, затем записывая поле ParamCount в поток.
См. так же: TStaticText.Store
Палитра
Объекты TParamText используют палитру по умолчанию CStaticText для отображения 6-го элемента в палитру стандартного диалога.
1 +===+ CStaticText | 6 | +=+=+ Текст -----+

TPoint Objects

TPoint - это простой объект, представляющий точку на экране.
Поля
X X: Integer; Х - это колонка точки на экране.
Y Y: Integer; Y - это строка точки на экране.

TPoint.

Этот объект представляет точку. Его поля X и Y определяет картезианские (X, Y) координаты позиции экрана. Точка (0, 0) - это верхняя левая точка экрана. X увеличивается горизонтально вправо, Y увеличивается вертикально вниз. TPoint не имеет методов, но другие типы имеют методы, которые преобразуют между глобальными (весь экран) и локальными (относительно смещения видимого элемента) координатами.

TProgram App

+---------+ | TObject | +----+----+ +----+----+ | TView | +----+----+ +----+----+ | TGroup | +-+--+--+-+ +----------+ | +------------+ +----+----+ +----+-----+ +======+=======+ | TWindow | | TDeskTop | | TProgram | +----+----+ +----------+ +======+=======+ +----+----+ +------+-------+ | TDialog | | TApplication | +---------+ +--------------+
TProgram обеспечивает базовую заготовку для всех стандартных программ на Turbo Vision. Все такие программы должны порождаться от TProgram или его потомка TApplication. TApplication отличается от TProgram только констрактором и дестрактором. 2 типа объекта предоставляются для большей гибкости при создании нестандартных программ. В большинстве случает Ваша программа будет порождаться от TApplication. TProgram порождается от TGroup, поскольку она должна содержать объекты TDeskTop, TStatusLine и TMenuBar.
Методы
Init constructor Init; Перекрывается: Иногда Устанавливает глобальную переменную Application в @Self; вызывает TProgram.InitScreen для инициализации переменных, определяющих режим экрана; вызывает TGroup.Init передавая прямоугольник Bounds равный полному экрану; устанавливает поле State в sfVisible + sfSelected + sfFocused + sfModal + sfExposed; устанавливает поле Options в 0; устанавливает поле Buffer в адрес экранного буфера, заданного в ScreenBuffer; наконец вызывает InitDeskTop, InitStatusLine и InitMenuBar и вставляет эти видимые элементы в группу TProgram.
См. так же: TGroup.Init, TProgram.InitDeskTop, TProgram.InitStatusLine, TProgram.InitMenuBar
Done destructor Done; virtual; Перекрывается: Иногда Освобождает объекты DeskTop, MenuBar и StatusLine и устанавливает глобальную переменную Application в nil.
См. так же: TGroup.Done
GetEvent procedure GetEvent(var Event: TEvent); virtual; Перекрывается: Редко По умолчанию TView.GetEvent просто вызывает GetEvent своего владельца и поскольку TProgram (или TApplication) в конечном итоге являются владельцем любого видимого элемента, любой вызов GetEvent будет приводить к TProgram. GetEvent (если только видимый элемент не перекроет GetEvent) TРrogram.GetEvent вначале проверяет, не сгенерировал ли TProgram.PutEvent событие. Если да, то GetEvent возвращает это событие. Если нет пришедшего события, GetEvent вызывает GetMouseEvent; если тот возвращает evNothing, вызывается GetKeyEvent, если оба возвращают evNothing: указывая, что нет ввода от пользователя, GetEvent вызывает TProgram.Idle, чтобы запустить "фоновые" задачи, выполняемые во время ожидания ввода от пользователя. До возврата GetEvent передает все события evKeyDown и evMouseDown в StatusLine для отображения в ассоциированные события от горячих клавиш evCommand.

См. так же: TProgram.PutEvent, GetMouseEvent, GetKeyEvent

GetPalette function GetPalette: PPalette; virtual; Перекрывается: Иногда Возвращает указатель на палитру, заданную индексом палитры в глобальной переменной AppPalette. TProgram поддерживает 3 палитры: apColor, apBlackWhite и apMonochrome. Переменная AppPalette инициализируется в TProgram.InitScreen.

См. так же: TProgram.InitScreen, AppPalette, apXXXX константы

HandleEvent procedure HandleEvent(var Event: TEvent); virtual; Перекрывается: Всегда Обрабатывает событие от клавиатуры от Alt-1 до Alt-9 генерируя событие evBroadcast с значением Command равным cmSelectWindowNum и значением InfoInt 19. TWindow.HandleEvent реагирует на такие сообщения, выбирая окно с данным номером. Обрабатывает событие evCommand со значением Command равным cmQuit вызывая EndModal(cmQuit) которое приводит к завершению программы. TProgram.Handle почти всегда перекрывается для введения обработки команд, специфичных для Вашей программы.

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

Idle procedure Idle; virtual; Перекрывается: Иногда Idle вызывается из TProgram.GetEvent когда очередь событий пуста, позволяя программе выполнять фоновые задачи при ожидании ввода от пользователя. По умолчанию TProgram.Idle вызывает StatusLine^.Update, чтобы разрешить строке статуса обновлять себя в соответствии с текущим констекстом подсказки. Затем, если набор команд изменился после последнего вызова TProgram.Idle, генерируется evBroadcast со значением Command равным cmCommandSetChanged, чтобы разрешить видимому элементу, который зависит от этого набора команд, разрешить или запретить себя. Если Вы перекрываете Idle, всегда вызывайте наследуемый Idle. Так же убедитесь, что любые задачи, выполняемые в Вашем Idle, не занимают слишком большого времени в программе, поскольку это будет блокировать ввод пользователя.

InitDeskTop procedure InitDeskTop; virtual; Перекрывается: Редко Создает объект TDeskTop для программы и сохраняет указатель на него в глобальной переменной DeskTop. InitDeskTop вызывается в TProgram.Init и никогда не должен вызываться прямо. InitDeskTop может быть перекрыт созданием потомка от TDeskTop.


См. так же: TProgram.Init, TDeskTop, TWindow.Init

InitMenuBar procedure InitMenuBar; virtual; Перекрывается: Всегда Создает объект TMenuBar для программы и сохраняет указатель на него в глобальной переменной в MenuBar. InitMenuBar вызывается в TProgram.Init и никогда не должен вызываться прямо. InitMenuBar почти всегда перекрывается потомком от TMenuBar, определенным пользователем.

См. так же: TProgram.Init, TMenuBar, TWindow.Init

InitScreen procedure InitScreen; virtual; Перекрывается: Иногда Вызывается из TProgram.Init и TProgram.SetScreenMode каждый раз, когда режим экрана инициализируется или изменяется. Это метод, который действительно выполняет обновление и настройку переменных, определяющих режим экрана для размера тени, маркеров и палитры программы.

См. так же: TProgram.Init, TProgram.SetScreenMode

InitStatusLine procedure InitStatusLine; virtual; Перекрывается: Всегда Создает объект TStatusLine для программы и сохраняет указатель на него в глобальной переменной в StatusLine. InitStatusLine вызывается в TProgram.Init и никогда не должен вызываться прямо. InitStatusLine почти всегда перекрывается потомком от TStatusLine, определенным пользователем.

См. так же: TProgram.Init, TStatusLine

OutOfMemory procedure OutOfMemory; virtual; Перекрывается: Часто OutOfMemory вызывается из TProgram.ValidView для определения, что LowMemory - True. OutOfMemory должна сообщать пользователю, что недостаточно памяти для выполнения операции. Например с использованием программы MessageBox из модуля StdDlg:

procedure TMyApp.OutOfMemory; begin MessageBox('Not enough memory to complete operation.', nil, mfError + mfOKButton); end;

См. так же: TProgram.ValidView, LowMemory

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


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

Run procedure Run; virtual; Перекрывается: Редко Выполняет TProgram, вызывая метод Execute (который TProgram наследует от TGroup).

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

SetScreenMode procedure SetScreenMode(Mode: Word); Устанавливает режим экрана. Mode - одна из констант smCO80, smBW80 или smMono с дополнительным smFont8x8 для выбора 43- или 50-строчного режима на EGA или VGA. SetScreenMode скрывает мышку, вызывает SetVideoMode для изменения режима экрана, вызывает InitScreen для инициализации переменных режима экрана, назначает ScreenBuffer в TProgram.Buffer, вызывает ChangeBounds с новым прямоугольником экрана и, наконец, показывает мышку.

См. так же: TProgram.InitScreen, SetVideoMode, smXXXX константа

ValidView function TProgram.ValidView(P: PView): PView; Проверяет правильность вновь созданных видимых элементов, возвращая Р, если видимый элемент правильный и nil - если нет. Во-первых, если Р - nil, возвращается значение nil. Во-вторых, если LowMemory - True, при вызове ValidView видимый элемент, заданный в Р, освобождается, вызывается метод OutOfMemory и возвращается значение nil. В-третьих, если вызов P^.Valid(cmValid) возвращает False, видимый элемент освобождается и возвращается значение nil. Иначе видимый элемент считается правильным и возвращается указатель на этот видимый элемент Р. ValidView часто используется для проверки правильности нового видимого элемента до вставки его во владельца. Например, следующий оператор показывает типичную последовательность создания, проверки и вставки нового окна в панель экрана (TProgram.ValidView и TGroup.Insert знают как игнорировать возможные указатели nil, возникающие в результате ошибок).

DeskTop^.Insert(ValidView(New(TMyWindow, Init(.))));

См. так же: LowMemory, TProgram.OutOfMemory, Valid методы

Палитра

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


1 2 3 4 5 6 7 +===+===+===+===+===+===+===+ CColor |$71|$70|$78|$74|$20|$28|$24| +===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+ CBlackWhite |$70|$70|$78|$7F|$07|$07|$0F| +===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+ CMonochrome |$70|$07|$07|$0F|$70|$70|$70| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Фон ----+ | | | | | +-- Короткий выбор Нормальный текст --+ | | | +------ Запрещенный выбор Запрещенный текст -----+ | +---------- Нормальный выбор Короткий текст ------------+

Элементы в 8 по 15 используются голубыми окнами.

8 9 10 11 12 13 14 15 +===+===+===+===+===+===+===+===+ CColor |$17|$1F|$1A|$31|$31|$1E|$71|$00| +===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+ CBlackWhite |$07|$0F|$07|$70|$70|$07|$70|$00| +===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+ CMonochrome |$07|$0F|$07|$70|$70|$07|$70|$00| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Рамка пассивна + | | | | | | +-- Зарезервировано Рамка активна -----+ | | | | +- Выбранный текст скроллера Кнопка рамки ----------+ | | +---- Нормальный текст скроллера Страница скроллинга -------+ +-------- Зарезервировано

Элементы с 16 по 23 используются бирюзовыми окнами.

16 17 18 19 20 21 22 23 +===+===+===+===+===+===+===+===+ CColor |$37|$3F|$3A|$13|$13|$3E|$21|$00| +===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+ CBlackWhite |$07|$0F|$07|$70|$70|$07|$70|$00| +===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+ CMonochrome |$07|$0F|$07|$70|$70|$07|$70|$00| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Рамка пассивна + | | | | | | +-- Зарезервировано Рамка активна -----+ | | | | +- Выбранный текст скроллера Кнопка рамки ----------+ | | +---- Нормальный текст скроллера Страница скроллинга -------+ +-------- Зарезервировано

Элементы с 24 по 31 используются серыми окнами.

24 25 26 27 28 29 30 31 +===+===+===+===+===+===+===+===+ CColor |$70|$7F|$7A|$13|$13|$70|$7F|$00| +===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+ CBlackWhite |$70|$7F|$7F|$70|$07|$70|$07|$00| +===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+ CMonochrome |$70|$70|$70|$07|$07|$70|$07|$00| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Рамка пассивна + | | | | | | +-- Зарезервировано Рамка активна -----+ | | | | +- Выбранный текст скроллера Кнопка рамки ----------+ | | +---- Нормальный текст скроллера Страница скроллинга -------+ +-------- Зарезервировано


Элементы с 32 по 63 используются диалоговыми окнами. См. TDialog для отдельных элементов.

32 33 34 35 36 37 38 39 40 +===+===+===+===+===+===+===+===+===+ CColor |$17|$1F|$1A|$31|$31|$31|$1E|$71|$00| +===+===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+===+ CBlackWhite |$07|$0F|$07|$70|$70|$70|$07|$70|$00| +===+===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+===+ CMonochrome |$07|$0F|$07|$70|$70|$70|$07|$70|$00| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Рамка пассивна + | | | | | | | +-- Короткая метка Рамка активна -----+ | | | | | +- Подсвеченная метка Кнопка рамки ----------+ | | | +----- Нормальная метка Страница скроллинга -------+ | +--------- Статический текст Элементы управления -----------+ скроллинга

41 42 43 44 45 46 47 48 49 +===+===+===+===+===+===+===+===+===+ CColor |$17|$1F|$1A|$31|$31|$31|$1E|$71|$00| +===+===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+===+ CBlackWhite |$07|$0F|$07|$70|$70|$70|$07|$70|$00| +===+===+===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+===+===+ CMonochrome |$07|$0F|$07|$70|$70|$70|$07|$70|$00| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Нормальная кнопка | | | | | | | +-- Короткий кластер Кнопка по умолчанию+ | | | | | +----- Выбранный кластер Выбранная кнопка-------+ | | | +-------- Нормальный кластер Запрещенная кнопка---------+ | +------------ Тень кнопки Короткая кнопка ---------------+

50 51 52 53 54 55 56 +===+===+===+===+===+===+===+ CColor |$1F|$2F|$1A|$20|$72|$31|$31| +===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+ CBlackWhite |$0F|$70|$0F|$07|$70|$70|$70| +===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+ CMonochrome |$07|$70|$07|$07|$70|$07|$07| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Нормальная строка----+ | | | | | +- Элементы управления ввода | | | | | скроллинга окна истории Выбранная строка ------+ | | | +----- Страница скроллинга ввода | | | окна истории Стрелки строки ввода --------+ | +---------- Стороны истории Стрелка истории -----------------+

57 58 59 60 61 62 63 +===+===+===+===+===+===+===+ CColor |$30|$2F|$3E|$31|$13|$00|$00| +===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+ CBlackWhite |$07|$70|$0F|$07|$07|$00|$00| +===+===+===+===+===+===+===+ +===+===+===+===+===+===+===+ CMonochrome |$07|$70|$0F|$07|$07|$00|$00| +=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Нормальный просмотр--+ | | | | | +-- Зарезервировано списка | | | | | Активный просмотр ------+ | | | +------ Зарезервировано списка | | | Выбранный просмотр списка ---+ | +---------- Информационная Разделитель просмотра списка ----+ панель

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 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 равны.

TRect.

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

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 и о котором Вы забыли, это может привести к конфликтам. Всегда просматривайте не используют ли другие объекты события, которые кажутся "потерянными".

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

Одно из ограничений при использовании 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 подсоединить к Вашим данным.

Управление.

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

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

Чтобы установить бит используйте оператор 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 восстанавливает сложные объекты. Так, если объект, считанный Вами из потока, - это видимый элемент, владеющий подэлементами, подэлементы будут так же загружены.

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

Внутри любой группы видимых элементов может быть выбран один и только один подэлемент. Например, когда Ваша программа устанавливает полосу меню, панель экрана и строку статуса, панель экрана - выбранный видимый элемент и вся работа будет происходить в нем. Когда Вы открыли на панели экрана несколько окон, выбранное окно это окно с которым Вы работаете в данный момент. Оно также называется активным окном (обычно самое верхнее окно). Внутри активного окна выбранный подэлемент называется активным видимым элементом. Вы можете думать об активном видимом элементе как об элементе на который Вы смотрите или с которым взаимодействуете. (Активный видимый элемент находится в конце цепочки выбранных элементов, которая начинается от программы). В окне редактора активный видимый элемент будет интерьером с текстом внутри него. В диалоговом окне активный элемент это подсвеченный элемент управления. В диаграмме программы на рисунке 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.

Выбор.

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

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

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

Выход.

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

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

Выберите 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-битное слово, каждый бит которого соответствует одному элементу. После того, как Вы закончите создание всего диалогового окна, Вы увидите как устанавливать и читать значения элементов управления. Сейчас сосредоточимся на помещении управляющих элементов в соответствующее место.



    Программирование: Языки - Технологии - Разработка