It's a pretty straightforward connection point implementation. I found this (link in german, but the code's pretty straightforward) - needs error checking, though.
Most of the work is setting up an IDispatch implementation with ITypeInfo. You could directly implement GetIDsOfNames and Invoke (without using ITypeInfo), but I find it's simpler to use ITypeInfo with event interfaces (since the typeinfo is already built).
You might also want to look at the answers to this question, too.
// pConnectTo = IDiscFormat2Data-Interface
// riid = IID_DDiscFormat2DataEvents
// pUnknown = The Event Receiver ( see below)
void connect(IUnknown* pConnectTo, REFIID riid, IUnknown* pUnknown)
{
// QI the container
HRESULT hr = pConnectTo->QueryInterface(IID_IConnectionPointContainer, (void**)&m_connContainer);
// Find the connection point:
hr = m_connContainer->FindConnectionPoint(riid, &m_connPoint);
// Set up advice link
DWORD cookie;
hr = m_connPoint->Advise(pUnknown, &cookie);
// Retain the cookie:
m_dwCookie = cookie;
}
// The Event Receiver (implicitly derives from IDispatch):
class EventReceiver : public DDiscFormat2DataEvents
{
public:
EventReceiver();
virtual HRESULT __stdcall Update(IDispatch* object, IDispatch* progress);
private:
com_ptr_t<ITypeInfo> m_ptinfo;
};
EventReceiver::EventReceiver()
{
m_ptinfo = NULL;
HRESULT hr = 0;
LPTYPELIB ptlib = NULL;
hr = LoadRegTypeLib(LIBID_IMAPILib2, IMAPILib2_MajorVersion, IMAPILib2_MinorVersion, LOCALE_SYSTEM_DEFAULT, &ptlib));
if (!FAILED(hr))
{
hr = ptlib->GetTypeInfoOfGuid(IID_DDiscFormat2DataEvents, &m_ptinfo));
ptlib->Release();
}
}
// boilerplate IDispatch implementation based on Typeinfo
STDMETHODIMP EventReceiver::GetTypeInfoCount(UINT FAR *pctinfo)
{
*pctinfo = 1;
return NOERROR;
}
STDMETHODIMP EventReceiver::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo FAR * FAR *pptinfo)
{
*pptinfo = NULL;
if (itinfo != 0) return ResultFromScode(DISP_E_BADINDEX);
m_ptinfo->AddRef();
*pptinfo = m_ptinfo;
return NOERROR;
}
STDMETHODIMP EventReceiver::GetIDsOfNames(REFIID riid, OLECHAR FAR * FAR *rgszNames, UINT cNames, LCID lcid, DISPID FAR *rgdispid)
{
return DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
}
STDMETHODIMP EventReceiver::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR *pexcepinfo, UINT FAR *puArgErr)
{
return DispInvoke(this, m_ptinfo, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
}