Турбо Паскаль 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



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


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

Рис. 1.1. Объекты Turbo Vision на экране.

+--------------------------------------+ | Полоса меню | +--------------------------------------| |**************************************| |**************************************| |**************************************| |** Панель экрана ********************| |**************************************| |**************************************| +--------------------------------------| | Строка статуса | +--------------------------------------+

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



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


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



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


Конечно не все ошибки связаны с памятью. Например видимый элемент может читать дисковый файл, а файл может быть не найден или разрушен. Этот тип ошибки должен быть указан пользователю. К счастью 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 строчным режимом. Этот флаг не предназначен для использования с видимыми элементами внутри окна.



Флаг 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.




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, когда он вставляется в группу.


Флаг 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.