Предоставление реализации IDispatch для клиента точки подключения

StackOverflow https://stackoverflow.com/questions/4097544

Вопрос

Я написал простую COM DLL INPROC Server с одним простым COM-объектом. COM-объект реализует точку подключения.

Я знаю, как создать клиент ATL, который вытекает из IDispEventImpl, и использует карту раковины, чтобы упростить этот процесс.

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

Я понятия не имею, как предоставить реализацию IDispatch - Может ли кто-то рекомендовать документацию по этому поводу, так как я не могу найти (у меня есть внутренние внутренние органы, но это не оказывает, что мне нужно).

Вот класс, который у меня уже есть:

#pragma once
#include <iostream>
using namespace std;

// Because we're implementing a connection points sink (_IPogFarmEvents) 
// in a non-ATL class, we must provide implementations for IUnknown and IDispatch.

class KidWithAPogFarm : public _IPogFarmEvents
{
    private:
        DWORD   m_dwRefCount;
        LONG    m_lNumPogs;

    public:
        KidWithAPogFarm() :
        m_dwRefCount    (0),
        m_lNumPogs  (0)
        {
        }

        ~KidWithAPogFarm()
        {
        }


        // -- IUnknown 
        HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
        {
            if (iid == DIID__IPogFarmEvents)
            {
                m_dwRefCount++;
                *ppvObject = (void *)this;
                return S_OK;
            }
            if (iid == IID_IUnknown)
            {
                m_dwRefCount++;
                *ppvObject = (void *)this;
                return S_OK;
            }
            return E_NOINTERFACE;
        }

        ULONG STDMETHODCALLTYPE AddRef()
        {
            m_dwRefCount++;
            return m_dwRefCount;
        }

        ULONG STDMETHODCALLTYPE Release()
        {
            ULONG l;
            l  = m_dwRefCount--;

            if ( 0 == m_dwRefCount)
                delete this;

            return l;
        }


        // -- IDispatch
        STDMETHODIMP GetTypeInfoCount(UINT *pctinfo)
        {       
            return E_NOTIMPL;
        }

        STDMETHODIMP GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo )
        {
            return E_NOTIMPL;
        }

        STDMETHODIMP GetIDsOfNames(const IID &riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId )
        {
            return E_NOTIMPL;
        }
        STDMETHODIMP Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr )
        {
            return E_NOT_IMPL;
        }   

        // -- IAntFarmEvents
        STDMETHODIMP OnFarmCreated(LONG lInitialPopulation)
        {
            m_lNumPogs = lInitialPopulation;

            cout << "The kid has a pog farm with " << m_lNumPogs << " pogs " << endl;
            return S_OK;
        }
};
Это было полезно?

Решение

Так как у вас уже есть ATL Вы можете изучить его источники и посмотреть, как IDispatchImpl делает все это. IDispatch Методы реализованы здесь, чтение данных из библиотеки типа в том же модуле, поскольку это самый простой и самый надежный способ, когда библиотека типа уже присутствует.

Также стоит отметить, что это довольно сложная тема для демонстрации на нем - вам нужно будет написать много кода, который на самом деле не приносит никакого понимания. IMO вы будете намного лучше, если вы реализуете интерфейс событий, которые не наследуют от IDispatch а скорее наследует непосредственно от IUnknown - Это продемонстрирует, как работают события, не тянув слишком много внимания IDispatch внутренние работы.

Другие советы

Я думаю, что самый простой способ сделать это через Createestddispatch.

Ты можешь использовать это Реализация Idespatch.

Это не совсем то, что вы ищете, но Firebreath Использует IDISPATCEX и точки подключения для обеспечения управления ActiveX, который работает в IE. Поскольку Firebrath - это абстракция, позволяющая записывать плагины один раз и использовать во всех основных браузерах, интерфейс IDispatch, необходимый для того, чтобы быть записан вручную, включая точки подключения.

Код может быть немного запутанным, поскольку есть шаблонный класс Mixin, используемый для обеспечения идиспатч и точек соединения с двумя разными классами объекта COM, но это может помочь.

Вы уже приняли ответ, но, возможно, это все равно поможет. Извините, я не видел вопрос раньше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top