Сущность технологии СОМ. Библиотека программиста

ОглавлениеДобавить в закладки К обложке

Напомним, что начальная точка входа в класс СОМ проходит через объект этого класса. Чтобы связаться с объектом класса, необходим моникер классового типа (Class Moniker). Это моникеры встроенного типа, предоставляемые моделью СОМ. Классовые моникеры поддерживают CLSID в качестве своего начального состояния и могут быть созданы либо с помощью явной API-функции СОМ CreateClassMoniker.

HRESULT CreateClassMoniker([in] REFCLSID rclsid, [out] IMoniker **ppmk);

либо путем передачи отображаемого имени от Class Moniker в MkParseDisplayName[1]:

clsid:571F1680-CC83-11d0-8C48-0080C73925BA:

Отметим, что префикс «сlsid» является программным идентификатором ProgID для Class Moniker. Следующий код демонстрирует использование МkParseDisplayName для создания Class Moniker, который затем используется для связи с объектом класса Gorilla:

HRESULT GetGorillaClass(IApeClass * &rpgc)

{ rpgc = 0;

// declare the CLSID for Gorilla as a display name

// объявляем CLSID как отображаемое имя для Gorilla

const OLECHAR pwsz[] = OLESTR(«clsid:571F1680-CC83-11d0-8C48-0080C73925BA:»);

// create a new binding context for parsing

// and binding the moniker

// создаем новый связующий контекст

// для анализа и связывания моникера

IBindCtx *pbc = 0;

HRESULT hr = CreateBindCtx(0, &pbc);

if (SUCCEEDED(hr))

{

ULONG cchEaten; IMoniker *pmk = 0;

// ask СОМ to convert the display name to a moniker object

// запрашиваем СОМ преобразовать отображаемое имя

// в объект моникера

hr = MkParseDisplayName(pbc, pwsz, &cchEaten, &pmk);

if (SUCCEEDED(hr))

{

// ask the moniker to find or create the object that it

// refers to // запрашиваем моникер найти или создать объект,

// на который моникер ссылается

hr = pmk->BindToObject(pbc, 0, IID_IApeClass, (void**)&rpgc);

// we now have a pointer to the desired object, so release

// the moniker and the binding context

// теперь у нас есть указатель на желаемый объект, так что

// освобождаем моникер и связующий контекст

pmk->Release();

}

pbc->Release();

}

return hr;

}

Связующий контекст, который передается одновременно в MkParseDisplayName и IMoniker::BindToObject, является просто вспомогательным объектом, который позволяет дополнительным параметрам передаваться алгоритмам синтаксического анализа и связывания моникера. В случае нашего простого примера все, что требуется, – это новый связующий контекст в роли заполнителя (placeholder), который запрашивается путем вызова API-функции СОМ CreateBindCtx[2].

В Windows NT 4.0 введена API-функция, упрощающая вызовы MkParseDisplayName и IMoniker::BindToObject:

HRESULT CoGetObject( [in, string] const OLECHAR *pszName, [in, unique] BIND_OPTS *pBindOptions, [in] REFIID riid, [out, iid_is(riid)] void **ppv);

Эта API-функция реализована следующим образом:

// pseudo-code from OLE32.DLL

// псевдокод из OLE32.DLL

HRESULT CoGetObject(const OLECHAR *pszName, BIND_OPTS *p0pt, REFIID riid, void **ppv)

{

// prepare for failure

// подготовка на случай сбоя

*ppv = 0;

// create a bind context

// создаем контекст связывания

IBindCtx *pbc = 0;

HRESULT hr = CreateBindCtx(0, &pbc);

if (SUCCEEDED(hr))

{

// set bind options if provided

// устанавливаем опции связывания, если они требуются

if (pOpt) hr = pbc->SetBindOptions(pOpt);

if (SUCCEEDED(hr))

{

// convert the display name into a moniker

// преобразуем отображаемое имя в моникер

ULONG cch;

IMoniker *pmk = 0;

hr = MkParseDisplayName(pbc, pszName, &cch, &pmk);

if (SUCCEEDED(hr)) {

// ask the moniker to bind to the named object

// запрашиваем моникер связаться с именованным объектом

hr = pmk->BindToObject(pbc, 0, riid, ppv);

pmk->Release();

}

}

pbc->Release();


Логин
Пароль
Запомнить меня