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

         

Функция 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.


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



ИЕРАРХИЯ ОБЪЕКТОВ.


Эта глава предполагает, что Вы хорошо знаете Turbo Pascal, особенно объектно-ориентированные расширения, хотя мы будем напоминать некоторую информацию о типах объектов. Также предполагается, что Вы читали часть 1 этого руководства и получили обзор философии возможностей и терминологии Turbo Vision. После общих замечаний об ООП и иерархии эта глава дает короткий обзор иерархии объектов Turbo Vision, обращая особое внимание на взаимосвязи объектов через механизм наследования. Изучая главное свойство каждого стандартного типа объектов Вы получите представление о том как их наследовать и как объединены поля и методы объекта для создания функциональности этого объекта. Полное иерархическое дерево показано на рис.3.1. Вам поможет тщательное изучение этого рисунка. Например, информация о том что TDialog порожден от TWindow, который порожден от TGroup, который порожден от TView значительно сокращает время изучения. Каждый новый порожденный тип имеет уже известные унаследованные свойства. Вы просто изучаете дополнительные поля и свойства, которыми он дополняет своих родителей.

Рис. 3.1 Иерархия объектов 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 +-TStaticText---+-TLabel +-TDialog +-THistory +-TParamText +-TListViewer---+-THistoryViewer +-TInputLine +-TListBox +-TMenuView-----+-TMenuBar +-TScrollBar +-TMenuBox +-TScroller--------TTextDevice--TTerminal +-TStatusLine

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



ВИДИМЫЕ ЭЛЕМЕНТЫ.


Сейчас Вы должны иметь внешнее представление о работе программ на Turbo Vision. Что присходит внутри? Ответу на этот вопрос посвящены 2 следующие главы.



ПРОГРАММИРОВАНИЕ УПРАВЛЯЕМОЕ СОБЫТИЯМИ.


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



НАПИСАНИЕ НАДЕЖНЫХ ПРОГРАММ.


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



КОЛЛЕКЦИИ.


Программисты на Паскале традиционно тратят много времени на создание кода, который поддерживает структуры данных, такие как связанные списки и динамические массивы. В дейсвительности один и тот же код структуры данных переписывается и отлаживается снова и снова. Традициооный Паскаль обеспечивает только встроенные записи и массивы. Остальные структуры Вы должны разрабатывать сами. Например, если Вы собираетесь хранить данные в массиве, Вам необходимо написать код для создания массива, импортирования данных в массив, выборки данных из массива для обработки и, вероятно, для вывода данных на устройство В/В. Позже, когда в программе потребуется новый тип элементов массива, Вы начнете все сначала. Было бы хорошо, если бы тип массива поступал вместе с кодом, который будет обрабатывать большинство операций, который Вы обычно производите с массивом, или если бы этот тип массива можно было расширить не изменяя оригинальный код. В этом назначение типа TCollection в Turbo Vision. Это объект, который хранит набор указателей и предоставляет встроенные методы для манипуляции ими.



ПОТОКИ.


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



РЕСУРСЫ.


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



СОВЕТЫ.


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



КАК ИСПОЛЬЗОВАТЬ СПРАВОЧНИК.


Справочник по Turbo Vision описывает все стандартные объекты и методы в иерархии Turbo Vision вместе с мнемоническими идентификаторами, константами и записями, необходимыми для разработки программ на Turbo Vision. Справочник не задумывался как учебник. По своей природе сложные библиотеки объектов, такие как в Turbo Vision, имеют множество компонент. Для того, чтобы избежать бесконечного повторения материала мы поместили наиболее полную информацию в алфавитных разделах (глава 13 и 14) вместе с другими менее детальными материалами, которые позволяют Вам просматривать компоненты Turbo Vision в их иерархических и физических взаимосвязях с ссылками на более детальную информацию.



СПРАВОЧНИК ПО МОДУЛЯМ.


Эта глава кратко описывает содержимое каждого из модулей Turbo Vision. Вначале мы дадим обзор модулей Turbo Vision, а затем более детально опишем каждый модуль. Turbo Vision содержит 9 модулей:

Таблица 12.1. Модули Turbo Vision.

------------------------------------------------------------- Модуль Содержимое ------------------------------------------------------------- App Все определения объектов для написания программ, управляемых от событий.

Dialogs Инструменты и элементы управления, используемые в диалоговых окнах.

Drivers Поддержка мышки, обработчик клавиатуры, обработчик системных ошибок и т.п.

HistList Списки историй для строк ввода.

Memory Система управления памятью.

Menus Объекты для добавления меню и строки статуса.

Objects Основные определения объектов, включая все типы объектов для потоков, коллекций и ресурсов.

TextView Видимые элементы для представления текста.

Views Основные объекты для использования окон в программе: видимые элементы, окна, рамки, полосы скроллинга и т.д. -------------------------------------------------------------



СПРАВОЧНИК ПО ОБЪЕКТАМ.


Эта глава содержит алфавитный список всех стандартных объектов Turbo Vision с объяснением их назначения и использования, с полями, методами и палитрами цветов. Чтобы найти информацию по определенному объекту помните, что многие свойства объектов в иерархии наследуются от предков. Вместо бесконечного дублирования всей информации эта глава описывает только поля и методы, которые добавляются или изменяются в этом объекте. Например, если Вы хотите найти поле Owner объекта TLabel, Вы можете посмотреть поля TLabel, среди которых Вы не найдете Owner. Затем посмотрите непосредственного предка TLabel в иерархии - TStaticText. Поля Owner нет опять. Посмотрите следующего непосредственного предка TView. Здесь Вы найдете полную информацию об Owner, которое наследуется неизменным в TLabel. Каждый объект в этой главе имеет графическое представление предков и непосредственных наследников так, что Вы сможете легко найти объекты, от которых наследуются поля и методы. Каждый объект представлен в следующем формате:



ГЛОБАЛЬНЫЕ ССЫЛКИ.


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



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


На верхнем уровне абстракции главная программа на Turbo Vision выглядит аналогично Hello:

var HelloWorld: THelloApp; begin HelloWorld.Init; HelloWorld.Run; HelloWorld.Done; end;

Каждый из этих 3 методов требует небольшого пояснения.



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


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



Группы.


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



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


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

Рис. 4.2. Экран TApplication.

+--------------------------------------+ | Строка меню | +--------------------------------------| |**************************************| |**************************************| |**************************************| |***DeskTop****************************| |**************************************| |**************************************| +--------------------------------------| | Строка статуса | +--------------------------------------+

Заметим, что сама программа не имеет представления экрана - Вы не видите программы. Ее появление полностью определяется ее видимыми элементами.



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