Win32编程点滴 - 响应ActiveX控件的事件
2010-01-10 09:37:15 来源:WEB开发网在最近的一篇文章中说到了,如何创建ActiveX,这次我们来响应事件。这次,我们将创建一个类:CGeneralEventSink,它能够响应任何Dispatch事件(事件的接口继承与IDispatch)。
首先,我 们来回顾一下ConnectionPoint的概念。任何支持事件的对象(比如,ActiveX控件),都支持 IConnectionPointContainer接口,顾名思义就是一个IConnectionPoint的容器,包含了这个对象支持的 全部事件。IConnectionPoint代表了一组事件,调用IConnectionPoint::Advise并传入我们想要接收事 件的对象指针。而IConnectionPoint::GetConnectionInterface返回的IID,是此接收事件的对象必须实 现的接口,否则Advise会失败。来看一下AxAdviseAll的代码:
//枚举 IConnectionPointContainer中的每个IConnectionPoint,
//对于每个IConnectionPoint新建一个支持iid接口的CGeneralEventSink对象,并Advise。
//pUnk是控件的指针
HRESULT AxAdviseAll(IUnknown * pUnk)
{
HRESULT hr;
IConnectionPointContainer * pContainer = NULL;
IConnectionPoint * pConnectionPoint=NULL;
IEnumConnectionPoints * pEnum = NULL;
hr = pUnk->QueryInterface (IID_IConnectionPointContainer,(void**)&pContainer);
if (FAILED(hr)) goto error1;
hr = pContainer->EnumConnectionPoints(&pEnum);
if (FAILED (hr)) goto error1;
ULONG uFetched;
while(S_OK == (pEnum->Next (1,&pConnectionPoint,&uFetched)) && uFetched>=1)
{
DWORD dwCookie;
IID iid;
hr = pConnectionPoint->GetConnectionInterface (&iid);
if (FAILED(hr)) iid = IID_NULL;
//这里传入pUnk是为了通过pUnk 得到iid的ITypeInfo,进而判断iid是否是Dispatch接口
IUnknown * pSink = new CGeneralEventSink(iid,pUnk);
hr = pConnectionPoint->Advise (pSink,&dwCookie);
pSink->Release();
pConnectionPoint->Release ();
pConnectionPoint = NULL;
pSink = NULL;
}
hr = S_OK;
error1:
if (pEnum)pEnum->Release();
if (pContainer) pContainer->Release();
if (pConnectionPoint) pConnectionPoint->Release();
return hr;
}
然后,来说一下Dispath事件。如果IConnectionPoint::GetConnectionInterface返回的IID代表的接 口是继承于IDispatch的话,这个事件就是一个Dispath事件。当事件发生时,产生事件的对象不会直接 调用pObj->OnEvent(),而会调用pObj->Invoke(…)。例如,Flash控件的事件对象:(通过 vc的#import指令生成的)
struct __declspec(uuid("d27cdb6d-ae6d-11cf-96b8- 444553540000"))
_IShockwaveFlashEvents : IDispatch
{
//
// Wrapper methods for error-handling
//
// Methods:
HRESULT OnReadyStateChange (
long newState );
HRESULT OnProgress (
long percentDone );
HRESULT FSCommand (
_bstr_t command,
_bstr_t args );
HRESULT FlashCall (
_bstr_t request );
};
更多精彩
赞助商链接