非MFC替换mingw中的Microsoft COM对象的AfxConnectionAdvise

时间:2014-04-18 15:04:27

标签: c++ com mfc mingw

我正在尝试实现一个DDiskFormat2DataEvents类来侦听IDiskFormat2Data的进度事件。我发现连接这两个的唯一例子是使用AfxConnectionAdvise。这个项目是在mingw64中构建的,所以我需要找到这个MFC方法的替代方法,或者如何手动连接com对象的源和接收器。任何的意见都将会有帮助。感谢

1 个答案:

答案 0 :(得分:1)

这是一个非常简单的连接点实现。我发现this(德语链接,但代码很简单) - 需要进行错误检查。

大部分工作是使用ITypeInfo设置IDispatch实现。您可以直接实现GetIDsOfNames和Invoke(不使用ITypeInfo),但我发现将ITypeInfo与事件接口一起使用会更简单(因为已经构建了typeinfo)。

您可能还想查看this question的答案。

// 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); 
}