Question

I've written a simple COM DLL inproc server with a single simple COM object. The COM object implements a connection point.

I know how to create an ATL client that derives from IDispEventImpl, and uses a sink map to simplify this process.

But, for the purposes of demonstration, I'd like to create a win32 console application that uses a class that calls my simple COM object, then acts as a connection point sink.

I've got no idea how to provide an implementation of IDispatch - can someone recommend documentation on this, as I can't find any (I've got ATL Internals, but this doesn't seem to cover what I need ).

Here's the class I've already got:

#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;
        }
};
Was it helpful?

Solution

Since you already have ATL you can examine its sources and see how IDispatchImpl does all that stuff. IDispatch methods are implemented therehby reading data from the type library in the same module since it's the easiest and most reliable way when a type library is already present.

It's also worth noting that it's a rather hard topic for making a demonstration on it - you'll need to write a lot of code that doesn't really bring any insight. IMO you'll be much better off if you implement an events interface that doesn't inherit from IDispatch but rather inherits directly from IUnknown - this will demonstrate how events work without dragging too much of attention to IDispatch inner workings.

OTHER TIPS

I think the easiest way of doing this is through CreateStdDispatch

You can use this IDispatch implementation.

It's not exactly what you're looking for, but FireBreath uses IDispatchEx and connection points to provide an ActiveX control that runs in IE. Because FireBreath is an abstraction to allow plugins to be written once and used in all major browsers, the IDispatch interface needed to be written by hand -- including connection points.

The code may be a little confusing, since there is a templated mixin class used to provide IDispatch and ConnectionPoints to two different COM object classes, but it may help.

You've already accepted an answer, but perhaps it will still help. Sorry I didn't see the question sooner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top