ИНФО: Пример моникера для объектов в ROT
От: Vi2 Удмуртия http://www.adem.ru
Дата: 25.09.02 04:40
Оценка: 104 (8)
Это в действительности не пример реального моникера, а его имитация. А ещё вернее, создание пространства имён. В моём случае — пространства monv:хххх.

Делаете обычный ATL проект (у меня monv), добавляете простой ATL объект (у меня Manager, т.е. CManager, IManager и т.п.). И делаете косметику в классе и фабрике класса. Для моих целей класс не играет роли, он может быть реально действующим, но я использую только фабрику класса. Фактически ничего более и не надо.

В Manager.rgs файле, чтобы иметь короткое имя monv вместо monv.manager,
...
    Monv = s 'Manager Moniker Class'
    {
        CLSID = s 'такое же как у Monv.Manager'
    }
    Monv.Manager = s 'Manager Class'
...

В Manager.h файле изменяем CManager и добавляем CComClassFactoryMoniker
class ATL_NO_VTABLE CManager :
...
{
...
DECLARE_CLASSFACTORY_EX(CComClassFactoryMoniker<CManager>)
...
};

И в начало этого файла добиваете определение фабрики класса
template <class T>
class CComClassFactoryMoniker : public CComClassFactory,
    public IParseDisplayName
{
public:
BEGIN_COM_MAP(CComClassFactoryMoniker)
    COM_INTERFACE_ENTRY(IClassFactory)
    COM_INTERFACE_ENTRY(IParseDisplayName)
END_COM_MAP()

//IParseDisplayName
STDMETHOD(ParseDisplayName)( /*[in]*/ IBindCtx* pbc, /*[in]*/ LPOLESTR pszDisplayName,
                /*[out]*/ ULONG* pchEaten, /*[out]*/ IMoniker* *ppmkOut)
{
    if( !ppmkOut || !pchEaten )
        return E_POINTER;

    HRESULT hr = MK_E_NOOBJECT;
    ppmkOut[0] = NULL;
        
    LPOLESTR psz1 = wcschr(pszDisplayName,':')+1; // It's always here
    pchEaten[0] = wcslen(pszDisplayName);
        
    if( psz1[0] == '{' ) // "{CLSID}"
    {
// Использование техники моникеров
if( 0 ) // 0 или 1 - выбирайте, какая нравится. Соотвественно, другой код можно выбросить
{
        CComPtr<IMoniker> pmk;
        hr = CreateItemMoniker( L"!", psz1, &pmk ); // Создаём моникер !{CLSID}
        hr = pmk->IsRunning(pbc,NULL,NULL);
        if( hr == S_OK )
        {
            CComPtr<IRunningObjectTable> pROT;
            hr = pbc->GetRunningObjectTable( &pROT );
            CComPtr<IUnknown> pObj;
            hr = pROT->GetObject( pmk, &pObj );
            // Here it can be used the CreateObjrefMoniker, but I don't have it
            hr = CreatePointerMoniker( pObj, ppmkOut );
        }
        else
            hr = MK_E_NOOBJECT;
}
// Использование функции GetActiveObject
else
{
        CLSID clsid;
        hr = CLSIDFromString(psz1, &clsid);
        if( hr == S_OK )
        {
            CComPtr<IUnknown> pObj;
            hr = GetActiveObject(clsid, NULL, &pObj);  
            // Here it can be used the CreateObjrefMoniker, but I don't have it
            hr = CreatePointerMoniker( pObj, ppmkOut );
        }
        else
            hr = MK_E_NOOBJECT;
}
    }
    else // Здесь можно добавить дополнительные обработки - задавать через ProgID и т.п.
        hr = MK_E_UNAVAILABLE;
    return hr;
}
};

Использование: "monv:{CLSID}" или "monv.manager:{CLSID}". Например, для запущенного Excel "monv:{00024500-0000-0000-C000-000000000046}". Извращение, конечно, но для демонстрации же. Вот пример на VB для поднятия этого Excel.
Private Sub Form_Load()
  Dim v
  Set v = GetObject("monv:{00024500-0000-0000-C000-000000000046}")
  Unload Me
End Sub
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.