Средства разработки приложений


Часть 2: Наследование классов и наследование интерфейсов - часть 9


5. Выполнить компиляцию и линковку. Не забудьте зарегистрировать вашу COM DLL через RegSvr32.

Прежде чем продемонстрировать работу COM plug-in на клиенте, давайте посмотрим что мы построили. Классы BaseLevelGetter и HotTubLevelGetter оба являются потомками CCmdTarget. Когда мы создавали HotTubLevelGetter, мы указали Class Wizard наследовать его от CCmdTarget. Напомним, что каждый класс, созданный Class Wizard как прямой потомок CCmdTarget, поддерживает собственные CLSID и интерфейс IDispatch. Когда мы изменяем базовый класс HotTubLevelGetter с CCmdTarget на BaseLevelGetter, HotTubLevelGetter наследует виртуальные методы BaseLevelGetter.

Когда клиенту необходим доступ к HotTubLevelGetter, он выполняет обычный CoCreateInstance(...) - передавая CLSID HotTubLevelGetter и IID_ILevelGetter, и вызывая методы ILevelGetter. Когда выполняется какой-либо метод, например, GetCurrentLevel, METHOD_PROLOGUE_EX_ берет значение pThis из offset table, и pThis действительно указывает на instance HotTubLevelGetter. То же вещь происходит, когда мы используем m_pOwner (он также указывает на instance HotTubLevelGetter); это немного легче для понимания из-за того, что мы можем наблюдать как выполняется метод m_xLevelGetter.SetOwner( this ). Давайте посмотрим на клиентское приложение и установим некоторые точки прерывания.

Откройте LevelViewer в папке LevelViewer2. Этот проект почти идентичен первому варианту LevelViewer. OnFish позиционирован в BaseLevelGetter, а OnGas - в HotTubLevelGetter, как показано далее.

//----------------------------------------------------------- void CLevelViewerDlg::OnFish() //mapped to BaseLevelGetter { m_sLastCalled = _T("CheckedFish"); CLSID clsid; HRESULT hRes = AfxGetClassIDFromString("BaseLevelGetterDLL.BaseLevelGetter", &clsid); if(SUCCEEDED(hRes)) SetNewData(clsid, IID_ILevelGetter); } //------------------------------------------------------------ void CLevelViewerDlg::OnGas() //mapped to HotTubLevelGetter { m_sLastCalled = _T("CheckedGas"); CLSID clsid; HRESULT hRes = AfxGetClassIDFromString("HotTubLevelGetterDLL.HotTubLevelGetter", &clsid); if(SUCCEEDED(hRes)) SetNewData(clsid, IID_ILevelGetter); }

Обе функции вызывают SetNewData, передавая CLSID, созданный Class Wizard, и IID_ILevelGetter, описанный в ILevelGetter.H и включенный вLevelViewerDlg.H.




Начало  Назад  Вперед