- Implemented the Sink Class - to receive event notifications from COM Server
 - Event Interface derives from IDispatch
 
I have an issue whereby an IConnectionPoint::Advise call returns E_NOTIMPL. This could be because the connection point only allows one connection - MSDN.
Note:
- COM Server is out-of-process
 - Pure C++ implementation
 
EDIT:
S8.tlh: C++ source equivalent of Win32 type library S8.tlb:
struct __declspec(uuid("090910c3-28c3-45fe-861d-edcf11aa9788"))
IS8SimulationEvents : IDispatch
{
    // Methods:
    HRESULT S8SimulationReset ( );
    HRESULT S8SimulationEndRun ( );
    HRESULT S8SimulationCustomEvent (
        BSTR * TextInfo );
    HRESULT S8SimulationOpened ( );
    HRESULT S8SimulationEndTrial ( );
    HRESULT S8SimulationOEMEvent (
        BSTR * TextInfo );
    HRESULT S8SimulationReadyToClose ( );
    HRESULT S8SimulationUserMessage (
        long * Answer,
        BSTR * TextMsg,
        long ValidAnswers );
};
Implementation of Class Sink - to handle event notifications:
class Sink : public IS8SimulationEvents
{
public:
Sink(){
    m_dwRefCount = 0;
};
~Sink(){};
/*
* IS8SimulationEvent interface functions
*/
HRESULT S8SimulationEndTrial()
{
    cout << "Simulation complete." << endl;
    return S_OK;;
};
HRESULT S8SimulationOpened()
{
    cout << "Simulation open." << endl;
    return S_OK;
};
HRESULT S8SimulationReadyToClose()
{
    cout << "Simulation ready to close" << endl;
    return S_OK;
};
ULONG STDMETHODCALLTYPE AddRef()
{
    m_dwRefCount++;
    return m_dwRefCount;
};
ULONG STDMETHODCALLTYPE Release()
{
    ULONG l;
    l = m_dwRefCount--;
    if (0 == m_dwRefCount)
    {
        delete this;
    }
    return m_dwRefCount;
};
HRESULT STDMETHODCALLTYPE QueryInterface(
                                        REFIID iid ,
                                        void **ppvObject)
{
    m_dwRefCount++;
    *ppvObject = (void *)this;
    return S_OK;
};
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo)
{
    return E_NOTIMPL;
};
HRESULT STDMETHODCALLTYPE GetIDsOfNames( 
                                        REFIID riid,
                                        LPOLESTR *rgszNames,
                                        UINT cNames,
                                        LCID lcid,
                                        DISPID *rgDispId)
{
    return E_NOTIMPL;
};
HRESULT STDMETHODCALLTYPE GetTypeInfo(
                                    unsigned int iTInfo,
                                    LCID lcid,
                                    ITypeInfo FAR* FAR* ppTInfo)
{
    return E_NOTIMPL;
};
HRESULT STDMETHODCALLTYPE Invoke(
                                DISPID dispIdMember,
                                REFIID riid,
                                LCID lcid,
                                WORD wFlags,
                                DISPPARAMS FAR* pDispParams,
                                VARIANT FAR* pVarResult,
                                EXCEPINFO FAR* pExcepInfo,
                                unsigned int FAR* puArgErr)
{
    HRESULT hresult = S_OK;
    if (pDispParams)
    {
        switch (dispIdMember) {
        case 1:
            return S8SimulationEndTrial();
        case 2:
            return S8SimulationOpened();
        case 3:
            return S8SimulationReadyToClose();
        default:
            return E_NOTIMPL;
        }
    }
    return E_NOTIMPL;
}
private:
    DWORD m_dwRefCount;
public:
void SetupConnectionPoint (IS8Simulation *pis8)
{
    HRESULT hresult;
    IConnectionPointContainer *pContainer = NULL;
    IConnectionPoint *pConnection = NULL;
    IUnknown *pSinkUnk = NULL;
    Sink *pSink = NULL;
    DWORD dwAdvise;
    dwAdvise = 0;
    hresult = pis8->QueryInterface(
                        __uuidof(IConnectionPointContainer),
                        (void **) &pContainer);
    if (SUCCEEDED(hresult))
    {
        cout << "IConnectionPointContainer inteface supported." << endl;
    } else {
        cerr << "Error: No such interface supported." << endl;
        exit (hresult);
    }
                                    __uuidof(IS8SimulationEvents),
                                    &pConnection); 
    switch (HRESULT_CODE(hresult)) {
        case NOERROR:
            cout << "Obtained valid interface pointer." << endl;
            break;
        case E_POINTER:
            cerr << "Invalid pointer: the address is not valid." << endl;
            exit (hresult);
            break;
        case CONNECT_E_NOCONNECTION:
            cerr << "This connectable object not support the "
                    "outgoing interface specified." << endl;
            exit (hresult);
            break;
        case E_UNEXPECTED:
        default:
            cerr << "Catastrophic failure." << endl;
            exit (hresult);
            break;
    }
    pContainer->Release();
    hresult = pSink->QueryInterface(
                            __uuidof(IUnknown),
                            (void **)&pSinkUnk);
    if (FAILED(hresult))
    {
        exit (EXIT_FAILURE);
    }
    hresult = pConnection->Advise(
                            pSinkUnk,
                            &dwAdvise);
    switch (HRESULT_CODE(hresult)) {
        case NOERROR:
            cout << "The connection has been established and "
                    "*dwAdvise has the connection token." << endl;
            break;
        case E_POINTER:
            cerr << "Invalid pointer: "
                    "the value pSinkUnk or dwAdvise is not valid." << endl;
            exit (hresult);
            break;
        case CONNECT_E_ADVISELIMIT:
            cerr << "The connection point has already reached "
                    "its limit of connections and cannot accept "
                    "any more." << endl;
            exit (hresult);
            break;
        case CONNECT_E_CANNOTCONNECT:
            cerr << "The sink does not support the interface "
                    "required by this connection point." << endl;
            exit (hresult);
            break;
        case E_NOTIMPL:
            break;
            case E_UNEXPECTED:
            default:
        cerr << "Catastrophic failure." << endl;
        exit (hresult);
        break;
    }
    return;
}
};
EDIT:
Implementation of IUnknown Interface in Sink Class
ULONG STDMETHODCALLTYPE AddRef()
{
    m_dwRefCount++;
    return m_dwRefCount;
};
ULONG STDMETHODCALLTYPE Release()
{
    ULONG l;
    l = m_dwRefCount--;
    if (0 == m_dwRefCount)
    {
        delete this;
    }
    return m_dwRefCount;
};
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
{
    m_dwRefCount++;
    *ppvObject = (void *)this;
    return S_OK;
};
Question:
- How to check if a container supports multiple connections?
 - If more information is required, please comment accordingly.