Взаимодействие видимых элементов
Иерархия объектов 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 указатель на собственную таблицу виртуальных методов. Это даст возможность получателю сообщения при необходимости обратиться к методам объекта-отправителя.
Организовать взаимодействие можно также с помощью прямого вызова обработчика событий нужного объекта. Для этого экземпляр объекта-адресата (переменная типа объект или указатель на него) должен быть инициирован предыдущим обращением к конструктору и программа должна "видеть" его, т.е. он должны быть глобальным по отношению к инициатору взаимодействия.