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

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

Если программа спроектирована правильно и видимые элементы требуют взаимодействия между собой, можно создать объект-посредник. Типичным примером такого объекта является внутренний буфер Clipboard диалоговой среды Турбо Паскаля (опция Edit). Для передачи фрагмента текста из одного окна редактора в другое фрагмент помещается в буфер командными клавишами Shift-Del или Ctrl-Ins, затем вызывается другое окно и фрагмент вставляется в нужное место командой Shift-Ins. Вы можете организовать такого рода буфер и в Вашей программе, так как с помощью Turbo Vision Вам доступны все средства диалоговой среды Турбо Паскаля. Преимуществом создания объекта-посредника является то, что с его помощью легко решается проблема взаимодействия сразу нескольких объектов друг с другом. Например, если Вы создаете сложную интегрированную систему, включающую текстовый редактор, систему управления базами данных, электронную таблицу и сервисные средства, промежуточный буфер позволит передать данные из текстового редактора в базу данных, или из базы данных в электронную таблицу и т.д.

Другим способом организации взаимодействия элементов является использование событий-сообщений. Эти события создаются с помощью глобальной функции Message. Функция Message описана в интерфейсной части модуля Views следующим образом:

Function Message (Receiver: Pview; What, Command: Word;

InfoPtr: Pointer): Pointer;

Первым параметром указывается ссылка на экземпляр объекта, которому адресуется сообщение. Остальные параметры используются для создания записи TEvent. Функция создает запись события и, если это возможно, вызывает метод Receiver^ .HandleEvent для обработки этого события. Если адресат не существует или при обращении к функции указан параметр Receiver = NIL, функция возвращает NIL - это означает, что событие не было обработано. Если событие успешно обработано (Receiver^. HandleEvent возвращает событие с полем What = evNothing), функция вернет указатель Event.InfoPtr.

Как уже говорилось в п. 18.6.2, стандартный метод ClearEvent очищает событие, устанавливая Event. What = evNothing и Event.InfoPtr = @Self. Таким образом, объект, обработавший и очистивший событие, оставляет в Event.InfoPtr указатель на свою таблицу виртуальных методов. Этот указатель позволяет полностью идентифицировать объект-получатель сообщения и организовать связь с ним.

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

AreYouThere := Message(DeskTop,evBroadcast, cmFindWatchWindow, NIL);

В методе HandleEvent окна отладки есть проверка на команду cmFindWatchWindow:

if (Event.What = evBroadcast) and

(Event.Command = cmFindWatchWindow) then 

ClearEvent(Event);

Если окно существует, оно очистит событие и оставит в нем свою «подпись», поэтому сразу за передачей сообщения реализуется такая проверка:

if AreYouThere = NIL then

CreateWatchWindow {Создать новое окно} 

else

AreYouThereA.Select; {Поместить существующее окно наверх}

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

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

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

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