我已经用一个简单的COM对象编写了一个简单的COM DLL inproc服务器。 COM对象实现一个连接点。

我知道如何创建一个从IDispEventImpl派生的ATL客户端,并使用接收器映射来简化此过程。

但是,出于演示目的,我想创建一个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;
        }
};

最佳答案

由于您已经有了ATL,因此可以检查其来源并查看IDispatchImpl如何完成所有这些工作。通过在同一模块中从类型库中读取数据来实现IDispatch方法,因为这是已经存在类型库的最简单,最可靠的方法。

还值得注意的是,这是一个很难进行演示的主题-您需要编写很多代码并没有真正带来任何见识。如果您实现的事件接口(interface)不是从IDispatch继承而是直接从IUnknown继承,则IMO会更好。这将演示事件如何工作,而不会过多地关注IDispatch内部工作原理。

10-08 11:38