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

我知道如何创建一个来自 IDispEventImpl, ,并使用水槽地图简化了此过程。

但是,出于演示目的,我想创建一个使用称为我简单COM对象的类的Win32控制台应用程序,然后用作连接点接收器。

我不知道如何提供 IDispatch - 有人可以推荐有关此文件的文档,因为我找不到任何(我有ATL内部设备,但这似乎都不涵盖我需要的内容)。

这是我已经上过的课:

#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 内部工作。

其他提示

我认为最简单的方法是通过 CreateStdDisPatch

您可以使用 IDISPATCH实现。

这并不是您想要的,但是 火布雷斯 使用IDISPATCHEX和连接点提供IE中运行的ActiveX控件。由于Firebreath是一个抽象,可以允许插件写一次并在所有主要浏览器中使用,因此需要手工编写IDISPATCH接口(包括连接点)。

该代码可能有点令人困惑,因为有一个模板Mixin类用于为两个不同的COM对象类提供IDISPATCH和连接点,但可能会有所帮助。

您已经接受了答案,但也许仍然会有所帮助。抱歉,我没有早点看到这个问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top