Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы Мартын 1(ComCorbaLab2004).doc
Скачиваний:
34
Добавлен:
10.02.2016
Размер:
2 Мб
Скачать
☆

1.7.4 Определение членов cDemoClientView

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

Сначала будут добавлены в класс CDemoClientView две переменные типа CWnd, которые будут содержать реализации двух визуальных компонентов: m_viewWnd и m_controllerWnd. Далее, будут добавлены по одной переменной для каждого класса-оболочки интерфейса, что позволит получать доступ к методам в ответ на сообщения о событиях во время выполнения программы. Также добавлены по одной такой переменной для интерфейсов IDemoModel, IDemoView и IDemoController. Не следует забывать добавлять окончание "Ptr" к названиям интерфейсов, чтобы получить названия классов, сгенерированных директивой #import. Остальные члены, которые необходимо добавить, относятся к механизму точек взаимодействия. Надо добавить еще две переменные: интеллектуальный указатель на интерфейс IConnectionPoint и ключ типа DWORD. Вот эти определения:

class CDemoClientView : public CView

{

public:

CWnd m_viewWnd; // контейнер для компонента представления

CWnd m_controllerWnd; // контейнер для компонента управления

IDemoModelPtr m_pModel; // интеллектуальный указатель на IDemoModel

IDemoViewPtr m_pView; // интеллектуальный указатель на IDemoView

IDemoControllerPtr m_pController; // интеллектуальный указатель

IConnectionPointPtr m_pCP; // интеллектуальный указатель на IConnectionPoint

DWORD m_dwCookie; // содержит ключик для идентификатора

// точки взаимодействия...

}

Далее, переопределяется виртуальная функция OnInitialUpdate() классаCDemoClientView. Это можно сделать, нажав правую кнопку мыши в окне ClassView и выбрав команду Add Virtual Function, а далее выбрав элемент OnInitialUpdate() из предложенного списка функций. После этого нажимаются кнопки Add и Edit для добавления нужного кода и выполняется перемещение в определение функции, чтобы внести необходимые дополнения. Здесь, после вызова функции OnInitialUpdate() базового класса, следует вставить код создания компонентов.

1.7.5 Создание компонентов

Теперь возможноприступить к созданию самих компонентов. Сначаланадо создатьвизуальные компоненты, воспользовавшись только что созданными членами типа CWnd. Для этогоможно применитьфункцию CWnd::CreateControl(). Для указания CLSID компонентов используютсярезультаты работы компилятора при выполнении директивы #import: ключевое слово __uuidof() с именем класса. Вот код создания визуальных компонентов:

// создание управляющих элементов ActiveX

m_viewWnd.CreateControl(__uuidof(DemoView),"View", WS_VISIBLE, CRect(0,0,300,200),this,101);

m_controllerWnd.CreateControl(__uuidof(DemoController),"Controller",

WS_VISIBLE, CRect(0,201,300,350), this, 102);

Если на этом этапе откомпилировать проект и запустить программу DemoClient, она будет выглядеть примерно так, как показано на рис. 1.2. Главное окно содержит клиентскую часть, в которой расположены компоненты представления и отображения. Можно даже воспользоваться элементами управления, но это ни к чему не приведет, поскольку еще не привязаны их изменения к чему-либо.

Рис. 1.2. Приложение DemoClient в работе

Следующий шаг - создание компонента-модели. В данном случае оно выполняется несколько проще, поскольку компонент не требует наличия окна, которое бы его содержало. Для создания компонента можно использовать функцию-член CreateInstance() сгенерированного класса-оболочки, передав ей CLSID компонента, который нужно создать. Эта операция пройдет успешно только в случае, если в указанном компоненте реализован интерфейс, класс-оболочка для которого используется. В противном случае интеллектуальный указатель получит значение NULL. Вот как создается этот компонент:

// создание компонента-модели при помощи класса-оболочки

m_pModel.CreateInstance(__uuidof(DemoModel));

Теперь, когда созданы все компоненты, необходимы указатели на их интерфейсы, чтобы можно было вызывать методы этих интерфейсов и выполнять нужные действия. Что касается компонента-модели, то уже есть то, что нужно: компонент был создан при помощи функции CreateInstance() над самим интеллектуальным указателем, так что указатель уже связан с компонентом через интерфейс, который он представляет (в данном случае IDemoModel). Остальные два компонента были созданы при помощи класса CWnd, поэтому их нужно связать с интеллектуальными указателями отдельно. Благодаря члену класса CWnd и оператору связывания класса оболочки эта операция тоже выполняется достаточно просто.

Чтобы это сделать, нужно результат выполнения функции CWnd::GetControlUnknown() передать оператору связывания класса-оболочки. Функция GetControlUnknown() возвращает указатель на интерфейс IUnknown управляющего элемента ActiveX, содержащегося в CWnd. Оператор связывания получает этот указатель и самостоятельно вызывает функцию QueryInterface(), запрашивая указатель на интерфейс того же типа, который представляет класс-оболочка. При успешном выполнении интеллектуальный указатель получит правильное значение указателя на интерфейс нужного типа. Начиная с этого момента можно использовать методы интерфейса, до тех пор, пока указатель не освободит интерфейс перед своим уничтожением. В случае неуспеха вызова QueryInterface() указатель получит значение NULL.