Non-MFC replacement for the AfxConnectionAdvise for Microsoft COM objects in mingw

StackOverflow https://stackoverflow.com/questions/23156816

  •  05-07-2023
  •  | 
  •  

Domanda

I am trying to implement a DDiskFormat2DataEvents class to listen to an IDiskFormat2Data's progress events. The only example I found of connecting those two uses AfxConnectionAdvise. This project builds in mingw64 so I need to find an alternative to this MFC method or how to manually connect the com object's source and sink. Any suggestions would be helpful. Thanks

È stato utile?

Soluzione

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); 
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top