请查阅微软的bug报告。
Note that both Microsoft Foundation Classes (MFC) and Active Template Library (ATL) have bugs in their IConnectionPoint::Advise implementation. They both do essentially the following:
HRESULT CConnectionPoint::Advise(IUnknown* pUnkSink, DWORD *pdwCookie)
{
IUnknown* p;
HRESULT hRes = S_OK;
if (SUCCEEDED(pUnkSink->QueryInterface(*m_piid, (void**)&p)))
{
// Add p to the list of sinks;
}
else
{
hRes = CONNECT_E_CANNOTCONNECT; // ATL does this
hRes = E_NOINTERFACE; // MFC does this
}
return hRes;
}
The bug is that they should return whatever the QI call returned instead of mapping to CONNECT_E_CANNOTCONNECT or E_NOINTERFACE. The correct way to implement a connection point is roughly the following:
HRESULT CConnectionPoint::Advise(IUnknown* pUnkSink, DWORD *pdwCookie)
{
IUnknown* p;
HRESULT hRes = pUnkSink->QueryInterface(*m_piid, (void**)&p);
if (SUCCEEDED(hRes))
{
// Add p to the list of sinks, maybe returning
// CONNECT_E_ADVISELIMIT if necessary
}
else if (hRes == E_NOINTERFACE)
{
// The sink does not support *m_piid!
return CONNECT_E_CANNOTCONNECT;
}
return hRes;
}