Смекни!
smekni.com

Особенности программирования для Windows (стр. 4 из 6)

1.3 Структура программ в CA-Visual Objects

1.3.1 Объекты. Связи типа “владение"

Подробно реализация принципов ООП в CA-Visual Objects рассматривается в главе 3. Сейчас же мы коснемся этих вопросов лишь в той мере, в какой это необходимо для уяснения структуры приложений, создаваемых с помощью CA-Visual Objects, и их основных особенностей.

Программа в CA-Visual Objects - это совокупность объектов, способных взаимодействовать друг с другом посредством сигналов (сообщений).

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

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

Получив сообщение X (см. рис.2.1), объект может изменить одно или несколько своих свойств (например, размеры, цвет) и сгенерировать одно или несколько сообщений Y для других объектов.

Характер реакции объекта определяется содержанием входного сообщения X. Отреагировав на очередное сообщение, объект снова переходит в пассивное состояние до тех пор, пока не получит извне новый сигнал.

Рис 1.14. Схематическое представление объекта

Объекты, имеющие общие “родовые” характеристики (т.е. сходные свойства и реакции на входные сообщения), объединяются в классы.

В ООП все возможные сообщения принято делить на две большие группы:

простые сообщения - те, которые имеют отношение к одному конкретному свойству объекта;

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

В CA-Visual Objects, как и в Clipper’е версий 5. х, факт посылки сообщения объекту обозначается символом “: ” (двоеточие). Простые сообщения формируются указанием имени объекта и его конкретного свойства, например:

cColor: = oBar: Color // значение свойства Color объекта oBar

// присвоить переменной cColor

oBox: Width: = 10 // свойству Width объекта oBox

// присвоить значение 10

Сложные сообщения в программах реализуются методами и синтаксически характеризуются наличием пары круглых скобок - “ () ”:


oWindow: Repaint () // Объекту oWindowвыполнить метод // Repaint ()

Реакция объекта на получение сложного сообщения должна быть явно определена в описании соответствующего метода.

Для обеспечения конкретного (адресного) взаимодействия объектов друг с другом посредством сообщений в программе должна быть определена схема их связей. Конечно, описывать связи в виде обобщенной сетевой структуры, когда каждый конкретный объект может непосредственно сообщаться с любым другим, - задача весьма и весьма сложная. Для упрощения процесса программирования в CA-Visual Objects принята существенно более простая, но в то же время весьма гибкая иерархическая структура связей.

Суть иерархической структуры связей в CA-Visual Objects раскрывается следующим основополагающим положением: любой объект программы имеет своего владельца. Эта концепция чрезвычайно важна, поскольку не только позволяет весьма просто организовывать систему связей объектов, но и обеспечивает поддержание динамической целостности программы как единого функционирующего организма. Рассмотрим ее более подробно применительно к среде Windows.

Как уже отмечалось, типовое приложение в Windows визуально представляется главным окном (или, иначе, окном-оболочкой), в рамках которого это приложение может открывать сколь угодно много дочерних окон. Любое дочернее окно содержит в себе те или иные элементы управления. Описанная цепочка легко и естественно укладывается в иерархическую структуру (рис.1.15):


Рис.1.15. Иерархическая структура связей объектов в CA-Visual Objects

Иерархические связи объектов в CA-Visual Objects фиксируются следующим образом. Исходя из принципа владения, в наборе свойств любого объекта всегда имеется свойство с именем Owner (“владелец” - англ), в котором содержится ссылка на объект, владеющий данным объектом. Пользуясь этой ссылкой, каждый объект может связаться с любым другим, в том числе и с равным себе по рангу (в последнем случае - транслируя свое сообщение через своего владельца).

Связи типа “владение" - становой хребет программ, разрабатываемых средствами CA-Visual Objects. Именно с использованием этих связей осуществляется маршрутизация сообщений, формирование подсказок и диагностики и обработка ошибок. Эти связи в объектно-ориентированной программе выполняют роль, аналогичную той, которые играют стеки вызовов в процедурно-ориентированных программах.

1.3.2 Генерация и обработка событий

Рассмотрим более предметно схему генерации и обработки событий, принятую в CA-Visual Objects.

Любые манипуляции пользователя с клавиатурой или мышкой являются для программы в CA-Visual Objects событиями. Важным в схеме обработки событий является то, что первичная обработка любого события осуществляется системой Windows. Она распознает событие и направляет информацию о нем диспетчеру событий системы времени исполнения CA-Visual Objects, которая автоматически подключается к приложению во время его компоновки. Диспетчер событий в соответствии с полученной от Windows информацией определяет окно, в рамках которого событие произошло, и посылает окну соответствующе сообщение. Окно должно своими средствами распознать это сообщение и выполнить необходимые действия.

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

при выборе пользователем из меню какого либо варианта (независимо от того, осуществлен выбор с помощью клавиатуры или мышки);

при “нажатии” пользователем с помощью мышки кнопки, изображенной на панели управления окна;

при нажатии пользователем клавиш-акселераторов;

при “нажатии” пользователем командной кнопки, изображенной в рабочей области окна.

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

Определяется идентификатор события (который назначается разработчиком в виде одного из свойств всем объектам, способным генерировать командные события).

Вначале в программе ищется подкласс окон, имя которого совпадает с идентификатором командного события. Если такой подкласс определен разработчиком, то автоматически создается и отображается на экране новое окно данного подкласса.

Если такого подкласса нет, диспетчер пытается найти подкласс отчетов с тем же именем.

Если и такого подкласса нет, диспетчер приступает к поиску метода с аналогичным именем для окна, которому принадлежит данный управляющий элемент.

Если и в этом случае поиск оказывается безуспешным, диспетчер определяет окно-владелец и, если оно существует, пытается отыскать метод у этого окна. И так далее - вверх по цепочке владения.

Если метод обнаружен, он немедленно запускается на выполнение. В противном случае диспетчер считает, что случившееся командное событие в функциональной обработке приложения не нуждается, и это событие им игнорируется.

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

Поясним сказанное на примере. Допустим, пользователь работает в дочернем окне “Расходная накладная: корректировка" приложения “Корпорация SuperStocks: запасы и взаиморасчеты" (рис.1.16). Разработчик присвоил подклассу таких окон имя DocsOut. Предположим также, что в процессе корректировки отображаемой в дочернем окне накладной ему потребовалось уточнить содержание картотеки учета товарно-материальных ценностей. Для этого он в меню “Файлы” выбирает вариант “Картотека". Пусть разработчик данного приложения связал этот вариант с командным событием Cards. В этом случае диспетчер приложения вначале попытается отыскать в работающей программе описание оконного подкласса с тем же именем. Если разработчик предусмотрел подкласс таких окон, то система времени исполнения автоматически создает экземпляр этого окна, отображает его поверх окна “Расходная накладная: корректировка”и делает активным (рис.1.17). Новое окно с названием “Картотека” имеет собственные меню и элементы управления и полностью готово к работе.

Вернемся к окну, изображенному на рис.1.16, и рассмотрим другой вариант. Пусть теперь пользователь вместо выбора из меню того или иного варианта “нажмет" командную кнопку “Отказ” в правом нижнем углу этого окна. Допустим, разработчик связал эту кнопку с командным событием CancelButton, и по замыслу нажатие этой кнопки должно приводить к отказу от всех сделанных в базе данных изменений и закрытию окна “Расходная накладная: корректировка". Для этого он разработал метод с именем CancelButton () в классе окон DocsOut. После “нажатия” клавиши “Отказ” диспетчер программы попытается найти сначала подкласс окон с именем CancelButton. Потерпев неудачу, диспетчер попытается далее найти подкласс отчетов с тем же именем. Не найдя отчета “CancelButton", диспетчер приступит к поиску метода CancelButton () в классе активного окна (DocsOut). Теперь ему будет сопутствовать удача, поскольку в данном классе метод с таким именем предусмотрен разработчиком. Отыскав метод, диспетчер запустит его на выполнение.