用SDK玩转ActiveX
2006-04-11 22:54:07 来源:WEB开发网p->SetSink( &sink );
p->DoSomething();
delete p;
如你所见,ISomeInterface并不是一个严格意义上的“接口”,而是一个实实在在的类,不过既然这是段模拟代码,所以我也没有必要做得惟妙惟肖了——同样,你也可以把new和delete的过程看作一个接口CoCreateInstance和Release的过程。CSink类则是用来处理ISomeInterface类回调事件的,在COM中我们称之为“接收器”。那么,ISomeInterface::SetSink就是设置连接点的“连接”过程,CSink::DoSomeOtherThings()则是接收器的事件处理实现。
接收器的实现
现在,我们就要开始本文最核心的部分了。通常对于COM接收器来讲,我们可以将它理解为一个没有CLSID的COM组件类,也就是说,我们只需要给出它的实现,并提供它的指针给服务器就足够了。而且对于我们的实现语言——C++来说,这个实现过程其实和编写一个C++类没有什么两样。那么,首先让我把这个实现完整地呈现给你,然后再逐一解释吧。
// 处理连接点事件的接收器实现
class CSink : public IDispatch
{
public:
// 构造/析构函数
CSink() : m_uRef( 0 ) {}
virtual ~CSink() {}
// IUnknown接口实现
STDMETHODIMP QueryInterface( REFIID iid, void **ppvObject )
{
if ( iid == __uuidof( _AgentEvents ) )
{
*ppvObject = (_AgentEvents *)this;
AddRef();
return S_OK;
}
if ( iid == IID_IUnknown )
{
*ppvObject = (IUnknown *)this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE AddRef()
{
m_uRef++;
return m_uRef;
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG u = m_uRef--;
if ( 0 == m_uRef )
{
delete this;
}
return u;
}
// IDispatch接口实现
STDMETHODIMP GetTypeInfoCount( UINT *pctinfo )
{
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
return E_NOTIMPL;
}
STDMETHODIMP Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr )
{
HRESULT hr = S_OK;
if ( NULL != pDispParams && 7 == dispIdMember )
{
if ( 2 == pDispParams->cArgs )
{
if ( VT_I2 == pDispParams->rgvarg[0].vt && VT_BSTR == pDispParams->rgvarg[1].vt )
{
OnHide( pDispParams->rgvarg[1].bstrVal, pDispParams->rgvarg[0].iVal );
}
else // 类型错误
{
hr = DISP_E_TYPEMISMATCH;
}
}
else // 参数个数错误
{
hr = DISP_E_BADPARAMCOUNT;
}
}
return hr;
}
// 要处理的_AgentEvents事件
STDMETHODIMP OnHide( _bstr_t CharacterID, short Cause )
{
PostMessage( g_hDlgMain, WM_CLOSE, 0, 0 );
return S_OK;
}
private:
ULONG m_uRef;
};
更多精彩
赞助商链接