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

         

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


Вы видите, что коллекции могут хранить любой тип данных динамически и что они содержат методы, помогающие Вам эффективно обращаться к данным коллекции. В действительности TCollection определяете 23 метода. Когда Вы используете коллекции в Ваших программах, Вы удивитесь скорости их работы. Они спроектированы для обеспечения гибкости и реализованы на удивление быстрыми. Сейчас Вы увидите реальную мощь коллекций: элементы могут обрабатываться полиморфно. Это означает, что Вы можете делать больше, чем просто сохранять тип объекта в коллекции; Вы можете хранить множество различных типов объектов из любого места в иерархии объектов. В примерах, которые мы рассматривали до сих пор, все элементы коллекции были одного типа. Но коллекции могут хранить любые объекты, порожденные от TObject и Вы можете свободно смешивать эти объекты. Обычно Вам необходимо иметь объекты с определенным сходством. Как пример рассмотрим программу, которая помещает 3 различных графических объекта в коллекцию. Затем итератор ForEach используется для прохода по коллекции и отображения каждого объекта. Этот пример использует модуль Graph и драйверы BGI, поэтому выо время компиляции GRAPH.TPU должен быть в текущем справочнике или в справочниках модулей (Options/Directories/Unit Directory). При выполнении программы перейдите в справочник, содержащий драйверы .BGI или модифицируйте вызов InitGraph, чтобы указать их расположение (например C:\TP\BGI). Вначале определим объект абстрактного предка.

{ TVGUID20.PAS } type PGraphObject = ^TGraphObject; TGraphObject = object(TObject) X,Y: Integer; constructor Init; procedure Draw; virtual; end;

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

PGraphPoint = ^TGraphPoint; TGraphPoint = object(TGraphObject) constructor Init; procedure Draw; virtual; end;

PGraphCircle = ^TGraphCircle; TGraphCircle = object(TGraphObject) Radius: Integer; constructor Init; procedure Draw; virtual; end;


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

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

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

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

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

procedure DrawAll(C: PCollection);

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

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

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

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


Поля Turbo Vision.


Если Вы возьмете 3 объекта TView, TGroup и TWindow, то увидите наследование их полей и как растет функциональность при движении вниз по иерархии (вспомним, что дерево объектов растет вниз от корня).

Таблица 3.1. Наследование полей видимых элементов.



--------------------------------------------- Поля TView Поля TGroup Поля TWindow --------------------------------------------- Owner Owner Owner Next Next Next Origin Origin Origin Size Size Size Cursor Cursor Cursor GrowMode GrowMode GrowMode DragMode DragMode DragMode HelpCtx HelpCtx HelpCtx State State State Options Options Options EventMask EventMask EventMask Buffer Buffer Phase Phase Current Current Last Last Flags Title Number ZoomRect Palette Frame ---------------------------------------------

Заметим, что TGroup наследует все поля TView и добавляет поля, которые необходимы для операций над группой, такие как указатели на текущий и последний видимые элементы в группе. TWindow наследует все поля TGroup и добавляет поля, требуемые для операций над окном, такие как заголовок и номер окна. Для того, чтобы полностью понять TWindow Вам необходимо помнить, что окно - это группа (group) и видимый элемент (view).



Полоса меню.


Переменная полосы меню MenuBar инициализируется вложенными вызовами стандартных функций NewMenu, NewSubMenu, NewItem и NewLine. После того, как Вы инициализируете меню, Ваша работа закончена. Полоса меню знает как обработать ввод пользователя без Вашей помощи. Инициализируем простую полосу меню с одним элементом, содержащем один выбор:

## File ############# +----------------+** |**Open F3*******|#* +----------------+#* **##################* *********************

const cmFileOpen = 200; { определение новой команды } procedure TMyApp.InitMenuBar; var R: TRect; begin GetExtent(R); R.B.Y := R.A.Y + 1; MenuBar := New(PMenuBar, Init(R, NewMenu( { создать полосу с меню } NewSubMenu('~F~ile', hcNoContext, NewMenu( { определить меню } NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext, { элемент } nil)), { больше нет элементов } nil) { больше нет подменю } ))); { конец полосы } end;

Меню, создаваемое этим кодом, называется 'File' и элемент меню называется 'Open'. "~" делает F символом короткого ввода в 'File', а O - символом короткого ввода 'Open'; клавиша F3 устанавливается как горячая клавиша для 'Open'. Все видимые элементы Turbo Vision могут иметь номер контекстной подсказки, связанный с ними. Номер позволяет просто реализовать контекстно-ориентированную справочную систему в Вашей программе. По умолчанию видимые элементы имеют контекст hcNoContext - это специальный контекст, который не изменяет текущий контекст. Номера контекстов подсказки появляются при инициализации полосы меню, поскольку из-за вложенной структуры этих объектов добавить номера позднее будет трудно. Когда Вы готовы добавить контекст подсказки в полосу меню, Вы можете подставить свои значения для hcNoContext в коде Init. Чтобы добавить второй элемент в меню 'File', Вы просто вкладываете другую функцию NewItem:

## File ############# +----------------+** |**Open F3*******|#* | New F4 |#* +----------------+#* **##################* *********************

MenuBar := New(PMenuBar, Init(R, NewMenu( NewSubMenu('~F~ile', hcNoContext, NewMenu( NewItem('~O~pen', 'F3', kbF3, cmFileOpen, hcNoContext, NewItem('~N~ew', 'F4', kbF4, cmNewWin, hcNoContext, nil))), nil) )));


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

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

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

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

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

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

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


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


Как подэлементы присоединяются к группе? Этот процесс называется вставкой. Видимые подэлементы создаются и затем вставляются в группу. В предыдущем примере констрактор TApplication.Init создает 3 объекта и вставляет их в программу:

InitDeskTop; InitStatusLine; InitMenuBar; if DeskTop <> nil then Insert(DeskTop); if StatusLine <> nil then Insert(StatusLine); if MenuBar <> nil then Insert(MenuBar);

В данном случае TApplication делит свою область на 3 части и передает каждую из них подэлементам. Это упрощает видимое представление, поскольку видимые подэлементы не перекрываются. Однако одним из наибольших достижений оконной среды является возможность иметь множество перекрывающихся окон на панели экрана. Группы (включая панель экрана) знают как обрабатывать перекрывающиеся подэлементы. Группа хранит порядок вставки подэлементов. Этот порядок соответствует порядку Z. Как Вы увидите, Z-упорядочивание определяет порядок, в котором подэлементы рисуются и порядок, в котором события передаются в них.



Получение TPoint.


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



Получение TRect.


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

procedure ThisWindow.MakeInside; var R: TRect; Inside: PInsideView; begin GetExtent(R); { установить R в размер ThisWindow} RR.Grow(-1, -1); { сократить прямоугольник на 1 } Inside := New(PInsideView, Init(R)); { создать внутренний видимый элемент} Insert(Inside); { вставить новый видимый элемент в окно } end;

GetExtent - это метод TView, который устанавливает аргумент TRect в координаты прямоугольника, покрывающего весь видимый элемент. Grow - это метод TRect, который увеличивает (а с отрицательными параметрами уменьшает) горизонтальный и вертикальный размеры прямоугольника.



Порождение.


Вы можете легко породить объектный тип из существующего.

PNewScrollBar = ^TNewScrollBar; TNewScrollBar = object(TScrollBar) end;

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



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


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



Посредники.


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



Потоки.


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



Потоки DOS.


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



Потоки EMS.


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



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


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



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


Давайте попробуем поработать с Вашей программой. Она уже имеет ряд возможностей. Она знает как открыть, закрыть, выбрать, переместить и изменить размеры множества окон на панели экрана. Неплохо для менее, чем ста строк кода! После того, как TMyApp инициализирует окно, он вставляет его в панель экрана. Как Вы помните, DeskTop - это группа, что означает, что его назначение - владеть и управлять видимыми подэлементами, такими как Ваше окно. Если Вы откомпилировали и выполнили код, Вы заметите, что Вы можете изменять размер, перемещать и закрывать новое окно. Ваш ввод от мышки преобразуется в серию событий и направляется из панели экрана в новое окно, которое знает, как обработать их. Если Вы сохранили вызов cmNewWin, на панели экрана будет появляться несколько окон с уникальными номерами. Эти окна могут изменять размеры, выбираться и перемещаться. Рис. 2.2 показывает панель экрана, на котором открыто несколько окон.

Рис. 2.2. TVGUID04 с несколькими открытыми окнами.

+-----------------------------------------------------------------+ | File Window | |*****************************************************************| |*********************+-- Demo Window 3----+**********************| |*********************| +-- Demo Window 7--+*****| |*********************| | |*****| |*********************| | |*****| |*********************| +-- Demo Window 8--+ |*****| |*********************| | | |*****| |*********************+--| | |*****| |+-- Demo Window 1--+** | |---------------+*****| |** | | |***************| |** | | |***************| +-- Demo Window 4--+------------------+ |***************| | |****| +-- Demo Window 6--+Window 2--+*| | |****| | | |*| |+----| |****+--| | |*| |*****| +=[ю]= Demo Window 9=[ш]=+ | |*| |*****| | | | |*| |*****+------------------| | | |*| |************************| |--+----------+*| |************************| |***************| |************************| |***************| |************************+=======================-+***************| |*****************************************************************| | Alt-X Exit F4 New Alt-F3 Close | +-----------------------------------------------------------------+

TWindow - это группа, которая первоначально владеет одним видимым элементом TFrame. Пользователь отмечает кнопки на рамке для перемещения, изменения размера или закрытия окна. Рамка отображает заголовок, который был получен во время инициализации окна и он рисуется фоновым цветом окна, таким как TBackGround панели экрана. Все это происходит без написания Вашего кода.



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


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



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


Краеугольным объектом любой программы является объект TApplication. В действительности, Вы никогда не создаете экземпляра объекта типа TApplication. TApplication - это абстрактный тип объекта. Он ничего не делает. Вы используете TApplication, создавая порожденные типы от TApplication, которые содержат Ваш программный код. В HELLO определяется порожденный тип объекта THelloApp:

PHelloApp = ^THelloApp; THelloApp = object(TApplication) procedure GreetingBox; procedure HandleEvent(var Event: TEvent); virtual; procedure InitMenuBar; virtual; procedure InitStatusLine; virtual; end;

Как показано здесь, полезно определить тип указателя на каждый тип, определяемого Вами объекта, поскольку большая часть работы над объектами производится через указатели. Полиморфизм главным образом работает через указатели. THelloApp содержит гораздо больше, чем эти 4 метода; порожденный объект наследует все от его предка. В определении THelloApp Вы определяете, чем новый объект отличается от его предка TApplication. Все, что Вы не переопределяете, наследуется в неизменном виде от TApplication. 4 метода, определенные в THelloApp, завершают "большую картину" Вашего приложения: - Как прикладным функциям указывается, что событие произошло и как они отвечают на них. Вы должны определить метод HadleEvent для выполнения этого требования. Метод HandleEvent, определенный в TApplication, работает с общими событиями, которые возникают внутри любой программы, но Вы должны обеспечить обработку событий, специфичных для Вашей программы. - Метод InitMenuBar устанавливает меню для полосы меню Вашей программы. TApplication содержит полосу меню, но не сами меню; если Вам необходимы меню, Вы просто определяете метод для определения меню. Вас может удивить, почему код InitMenuBar не является частью констрактора THelloApp. Может быть и так, но большие возможности предоставляет выбор из нескольких меню для начального меню. Лучше вывести это за пределы констрактора, оставляя внутри констрактора только те вещи, которые необходимо выполнять всегда при каждом выполнении программы. - Метод InitStatusLine устанавливает текст строки статуса внизу экрана. Этот текст обычно отображает сообщение о текущем состоянии программы, показывая доступные горячие клавиши или напоминая пользователю о некоторых действиях. - Метод GreetingBox вызывает диалоговое окно в ответ на элемент меню Greeting. GreetingBox вызывается из метода HandleEvent в ответ на событие, переключаемое выбором элемента меню Greeting. В более сложных программах Вы можете использовать различные методы в ответ на каждый элемент меню, определенный в начальном меню. Короче, методы из THelloApp обеспечивают все, что должны выполнять объекты главной программы: установку программы, выполнение действий в ответ на события и методы реализующие отклики на отдельные события. Именно эти 3 вещи Вы должны добавить к TApplication при создании порожденного типа объекта.



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


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



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


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



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


Другой способ взаимосвязи видимых элементов - дерево видимых элементов. В диаграмме дерева видимых элементов (рис. 4.7.) TDialog владеет типом TButton. Здесь взаимосвязь не между иерархическими типами объектов (TDialog не является предком TButton!), а между экземплярами объектов, между владельцем и подэлементами.

Рис. 4.7. Дерево видимых элементов простого диалогового окна.

+----------+ | TDialog | +-+---+---++ +-------+ | +-------+ +---+----++-----+---++------+------+ | TFrame TButton TStaticText | +--------++---------++-------------+

Вам необходимо, чтобы TButton взаимодействовал с его владельцем в дереве элементов (TDialog) и TButton будет рисовать атрибуты, наследованные от своего предка (TView). Не путайте эти взаимосвязи. Выполнение программы на Turbo Vision подобно дереву с созданием экземпляров видимых элементов и владением другими видимыми элементами. Когда программа открывает и закрывает окна, дерево видимых элементов растет и уменьшается при вставке и удалении экземпляров объектов. С другой стороны иерархия объектов только растет, когда Вы производите новый тип объекта от стандартного объекта.



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


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



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


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



Процедура Abstract Objects


================================================================= Объявление procedure Abstract;

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

См. также "Абстрактные методы" в главе 3.



Процедура AssignDevice TextView


================================================================= Объявление procedure AssignDevice(var T: Text; Screen: PTextDevice);

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

См. также TTextDevice; TextRec



Процедура ClearHistory HistList


================================================================= Объявление procedure ClearHistory;

Функция Удаляет все строки из всех списков истории.



Процедура ClearScreen Drivers


================================================================= Объявление procedure ClearScreen;

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

См. также InitVideo



Процедура DisposeMenu Menus


================================================================= Объявление procedure DisposeMenu(Menu: PMenu);

Функция Освобождает все элементы указанных меню (и все их подменю).

См. также Тип TMenu



Процедура DisposeStr Objects


================================================================= Объявление procedure DisposeStr(P:String);

Функция Освобождает строки, распределенные в куче с помощью функции NewStr.

См. также NewStr



Процедура DoneEvents Drivers


================================================================= Объявление procedure DoneEvents;

Функция Завершает монитор событий Turbo Vision, отключая обработчик прерываний мышки. Вызывается автоматически при вызове TApplication.Done.

См. также TApplication.Done, InitEvents



Процедура DoneHistory Drivers


================================================================= Объявление procedure DoneHistory;

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

См. также Процедура InitHistory, TApplication.Done



Процедура DoneMemory Memory


================================================================= Объявление procedure DoneMemory;

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

См. также TApplication.Done, InitMemory



Процедура DoneSysError Drivers


================================================================= Объявление procedure DoneSysError;

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

См. также TApplication.Done, InitSysError



Процедура DoneVideo Drivers


================================================================= Объявление procedure DoneVideo;

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

См. также TApplication.Done, InitVideo, переменная StartupMode



Процедура FormatStr Drivers


================================================================= Объявление procedure FormatStr(var Result: String; Format: String; var Params);

Функция Процедура форматирования строки, которая работает подобно функции языка Си vsprintf. Format включает спецификаторы формата, а Params содержит список параметров. FormatStr выполняет форматированный вывод строки в Result. Параметр Format может содержать любое число спецификаторов формата, для отображения параметров в Params. Формат спецификаторов - %[-][nnn]X, где - % указывает начало спецификатора формата; - [-] необязательный знак минуса, указывающий, что параметр будет выровнен влево (по умолчанию параметры при отображении выравниваются вправо); - [nnn] - необязательный десятичный спецификатор длины в диапазоне 0-255 (0 указывает на отсутствие длины, а не нуль означает, что выводится поле в nnn символов); - Х - символ формата: - 's' означает, что параметр указывает на строку; - 'd' означает десятичное представление LongInt параметра; - 'c' означает, что младший байт параметра - символ; - 'x' означает шестнадцатиричное представление параметра LongInt. - '#'устанавливает индекс параметра в nnn.

Например, если параметр указывает на строку, содержащую 'spiny', следующая таблица показывает спецификаторы и их результаты при печати:

Таблица 14.11. Спецификаторы формата и их результаты.

----------------------------------------- Спецификатор Результат ----------------------------------------- %6s ' spiny' %-6s 'spiny' %3s 'iny' %-3s 'spi' %06s '0spiny' %-06s 'spiny0' ----------------------------------------

Params - это нетипированный var параметр, содержащий параметры с соответствующимим спецификаторами формата в Format. Params должен быть массивом из LongInt или указателей или записью, содержащей LongInt или указатели. Например, для вывода строки сообщения об ошибке

Error in file [file name] at line [line number]

Вы должны послать следующую строку в Format:

'Error in file %s at line %d'.

Params должен содержать указатель на строку имени файла и Longint, представляющая число строк в файле. Это может быть сделано двумя способами: в массиве или в записи. Следующий пример показывает два типа объявлений и присвоений переменных, оба создают допустимые значения, передаваемые как Params в FormatStr.


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

ErrMsgArray = array[01] of Longint;

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

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

begin MyFileName := 'WARTHOG.ASM';

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

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

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


Процедура FreeBufMem Memory


================================================================= Объявление procedure FreeBufMem(P: Pointer);

Функция Освобождает кэш-буфер, ссылаемый указателем Р.

См. также GetBufMem, DoneMemory.



Процедура GetBufMem Memory


================================================================= Объявление procedure GetBufMem(var P: Pointer; Size: Word);

Функция Распределяет кэш-буфер для Size байт и запоминает указатель на него в Р. Если нет памяти для кэш-буфера запрашиваемого размера, Р устанавливается в nil. Кэш- буфер отличается от обычных блоков кучи (распределяемых с помощью New, GetMem или MemAlloc), в которых они могут размещаться или освобождаться монитором памяти в любое время. Указатель, передаваемый в GetBufMem, становится указателем на кэш-буфер и он (и только он) корректируется, когда буфер перемещается монитором памяти. Если монитор памяти решает освободить буфер, он устанавливает этот указатель в nil. Кэш-буфер может быть освобожден через вызов FreeBufMem. Кэш-буфера будут занимать любое нераспределенное пространство кучи между HeapPtr и HeapEnd, включая область, установленную для пула надежности программы.

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

См. также FreeBuffMem, InitMemory, TGroup.Draw.



Процедура GetKeyEvent Drivers


================================================================= Объявление procedure GetKeyEvent(var Event: TEvent);

Функция Проверяет, доступно ли событие от клавиатуры вызовом прерывания BIOS INT 16H. Если клавиша была нажата, Event.What устанавливается в evKeyDown и Event.KeyCode устанавливается в cкан-код клавиши. В противном случае, Event.What устанавливается в evNothing. GetKeyEvent вызывается из TProgram.GetEvent.

См. также TProgramm.GetEvent, константы evXXXX, TView.HandleEvent.



Процедура GetMouseEvent Drivers


================================================================= Объявление procedure GetMouseEvent(var Event: TEvent);

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

См. также TProgram.GetEvent, события evXXXX, методы HandleEvent.



Процедура HideMouse Drivers


================================================================= Объявление procedure HideMouse;

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

См. также InitEvents, DoneEvents, ShowMouse



Процедура HistoryAdd HistList


================================================================= Объявление procedure HistoryAdd(Id: Byte; var Str: String);

Функция Добавляет строку Str в список истории, указываемый с помощью Id.



Процедура InitEvents Drivers


================================================================= Объявление procedure InitEvents;

Функция Инициализирует монитор событий Turbo Vision, подключая обработчик прерываний мышки и показывая мышку. Вызывается автоматически TApplication.Init.

См. также DoneEvents.



Процедура InitHistory HistList


================================================================= Объявление InitHistory;

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

См. также TProgram.Init, процедуру DoneHistory.



Процедура InitMemory Memory


================================================================= Объявление procedure InitMemory;

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

См. также DoneMemory.



Процедура InitSysError Drivers


================================================================= Объявление procedure InitSysError;

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

См. также DoneSysError.



Процедура InitVideo Drivers


================================================================= Объявление procedure InitVideo;

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

См. также DoneVideo, SetVideoMode, smXXXX.



Процедура MoveBuf Objects


================================================================= Объявление procedure MoveBuf(var Dest; var Source; Attr: Byte; Count: Word);

Функция Копирует текст в буфер для использования с TView.WriteBuf или TView.WriteLine. Dest должен быть TDrawBuffer (или эквивалентным массивом слов) и Source должен быть массивом байт. Count байт копируются из Source в младшие байты соответствующих слов в Dest. Старшие байты слов в Dest устанавливаются в Attr или остаются неизменными, если Attr - 0.

См. также тип TDrawBuffer, MoveChar, MoveCStr, MoveStr.



Процедура MoveChar Objects


================================================================= Объявление procedure MoveChar(var Dest; C: Char; Attr: Byte; Count: Word);

Функция Копирует символы в буфер для использования с TView.WriteBuf или TView.WriteLine. Dest должен быть TDrawBuffer (или эквивалентным массивом слов). Младшие байты первых Count слов Dest устанавливаются в С или остаются неизменными, если Ord(C) - 0. Старшие байты слов устанавливаются в Attr или остаются неизменными, если Attr - 0.

См. также тип TDrawBuffer, MoveBuf, MoveCStr, MoveStr.



Процедура MoveCStr Objects


================================================================= Объявление procedure MoveCStr(var Dest; Str: String; Attrs: Word);

Функция Копирует строку в буфер для использования с TView.WriteBuf или TView.WriteLine. Dest должен быть TDrawBuffer (или эквивалентным массивом слов). Символы в Str копируются в младшие байты соответствующих слов в Dest. Старшие байты слов устанавливаются в Lo(Attr) или в Hi(Attr). Символы "~" в строке используются для переключения между двумя байтами атрибута, передаваемыми в слове Attr.

См. также тип TDrawBuffer, MoveChar, MoveBuf, MoveStr.



Процедура MoveStr Objects


================================================================= Объявление procedure MoveStr(var Dest; Str: String; Attr: Byte);

Функция Копирует строку в буфер для использования с TView.WriteBuf или TView.WriteLine. Dest должен быть TDrawBuffer (или эквивалентным массивом слов). Символы в Str копируются в младшие байты соответствующих слов в Dest. Старшие байты слов устанавливаются в Attr или остаются неизменными, если Attr - 0.

См. также тип TDrawBuffer, MoveChar, MoveCStr, MoveBuf.



Процедура PrintStr Drivers


================================================================= Объявление procedure PrintStr(S: String);

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



Процедура RegisterDialogs Dialogs


================================================================= Объявление procedure RegisterDialogs;

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

См. также TStreamRec, RegisterTypes.



Процедура RegisterType Objects


================================================================= Объявление procedure RegisterType(var S: TStreamRec);

Функция Тип объекта Turbo Vision должен быть зарегистрирован перед использованием в потоке В/В. Стандартные типы объектов уже зарегистрированы с ObjTypes в резервированном диапазоне 099. RegisterType создает элемент в связанном списке записей TStreamRec.

См. также TStream.Get, TStreamPut, TStreamRec.



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


================================================================= Объявление procedure Sample(AParameter);

Функция Sample выполняет ряд полезных функций с параметром, AParameter.

См. также Функция Example



Процедура SetVideoMode Drivers


================================================================= Объявление procedure SetVideoMode(Mode: Word);

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

См. также InitVideo, константы smXXXX, TApplication.SetScreenMode.



Процедура ShowMouse Drivers


================================================================= Объявление procedure ShowMouse;

Функция ShowMouse уменьшает "счетчик невидимости" в драйвере мышки и делает курсор мышки видимым если счетчик равен 0.

См. также InitEvents, DoneEvents, HideMouse.



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


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

------------------------------------------------------------- Функция Операция ------------------------------------------------------------- LongDiv Деление длинного целого на целое LongMul Умножение двух целых в длинное целое NewStr Распределение строки в куче -------------------------------------------------------------


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

------------------------------------------------------------- Функция Операция ------------------------------------------------------------- HistoryCount Возвращает число строк в списке истории HistoryStr Возвращает отдельную строку из списка истории -------------------------------------------------------------