Предоставление реализации IDispatch для клиента точки подключения - PullRequest
1 голос
/ 04 ноября 2010

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

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

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

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

#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;
        }
};

Ответы [ 4 ]

2 голосов
/ 04 ноября 2010

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

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

1 голос
/ 11 мая 2011

Вы можете использовать эту реализацию IDispatch.

1 голос
/ 04 ноября 2010

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

0 голосов
/ 28 мая 2011

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

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

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

...