《《可连接对象》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《可连接对象》PPT课件.ppt(26页珍藏版)》请在三一办公上搜索。
1、COM:可连接对象,潘爱民2003-11-7http:/,复习:COM基础,COM组件,COM客户,IXxx*p;p-,可连接对象(connectable object),内容:可连接对象结构模型实现可连接对象(源对象)客户-源对象-接收器的协作过程可连接对象的程序实现,双向通信机制 客户与可连接对象的关系,两个概念,入接口(incoming interface)组件对象实现入接口,客户通过入接口调用对象提供的功能客户和组件都需要知道接口的类型信息出接口(outgoing interface)客户端提供的COM对象实现出接口组件端的对象通过出接口调用客户提供的功能组件提供接口类型信息,客户实现
2、该接口类似于回调(callback),但是要复杂和灵活得多,出接口,类型信息由组件一方提供客户提供出接口的实现,实现出接口的COM对象被称为接收器对象(sink)sink没有CLSID,也不需要类厂也是一个COM接口,有IID每个成员函数代表了:事件event通知notification请求request,源对象 or 可连接对象,Connectable object,source普通的COM对象,支持一个或者多个出接口提供出接口的类型信息通过IProvideClassInfo2接口通过typelib,客户与可连接对象之间的两种结构,可连接对象的基本结构,可连接对象,如何管理多个出接口每个出接
3、口对应一个连接点对象通过连接点枚举器管理对于每个出接口,如何管理多个客户连接通过连接枚举器管理多个连接,实现可连接对象(源对象)(一),枚举器内部对象,不需要类厂和CLSID其含义就如同指针智能指针枚举器接口模板class IEnum:public IUnknownvirtual HRESULT Next(ULONG celt,ELT_T*rgelt,ULONG*pceltFetched)=0;virtual HRESULT Skip(ULONG celt)=0;virtual HRESULT Reset(void)=0;virtual HRESULT Clone(IEnum*ppenum)=
4、0;,枚举器的用法,class IStringManager:public IUnknown virtual IEnumString*EnumStrings(void)=0;void SomeFunc(IStringManager*pStringMan)String psz;IEnumString*penum;penum=pStringMan-EnumStrings();while(S_OK=penum-Next(1,实现可连接对象(源对象)(二),IConnectionPointContainer接口class IConnectionPointContainer:public IUnknow
5、n virtual HRESULT EnumConnectionPoints(IEnumConnectionPoints*)=0;virtual HRESULT FindConnectionPoint(const IID*,IConnectionPoint*)=0;IEnumConnectionPoints接口class IEnumConnectionPoints:public IUnknownvirtual HRESULT Next(ULONG cConnections,IConnectionPoint*rgpcn,ULONG*pcFetched)=0;virtual HRESULT Ski
6、p(ULONG cConnections)=0;virtual HRESULT Reset(void)=0;virtual HRESULT Clone(IEnumConnectionPoints*ppEnum)=0;,实现可连接对象(源对象)(三),连接点和IConnectionPoint接口class IConnectionPoint:public IUnknown virtual HRESULT GetConnectionInterface(IID*pIID)=0;virtual HRESULT GetConnectionPointContainer(IConnectionPointCon
7、tainer*ppCPC)=0;virtual HRESULT Advise(IUnknown*pUnk,DWORD*pdwCookie)=0;virtual HRESULT Unadvise(DWORD dwCookie)=0;virtual HRESULT EnumConnections(IEnumConnections*ppEnum)=0;连接枚举器 实现IEnumConnections接口允许多个客户连接每个连接用struct CONNECTDATA来描述,回顾:可连接对象的基本结构,客户与源对象建立连接过程,客户请求IConnectionPointContainer接口客户调用ICo
8、nnectionPointContainer:FindConnectionPoint找到连接点对象客户调用IConnectionPoint:Advise建立与接收器的连接最后,客户调用IConnectionPoint:Unadvise取消连接,并释放连接点对象,客户方基本结构,客户方实现接收器对象(sink)支持多个与可连接对象之间的连接一般只实现专用的出接口(IUnknown除外)不需要类厂、CLSID与客户代码紧密连接起来建立连接1 通过IConnectionPointContainer接口找到连接点对象2 通过连接点对象建立连接连接点相当于连接管理器,接收器的实现,class CSome
9、EventSet:public ISomeEventSet private:ULONG m_cRef;/Reference count./other private data members public:DWORD m_dwCookie;/Connection key public:CSomeEventSet();CSomeEventSet(void);/IUnknown members STDMETHODIMP QueryInterface(REFIID,PPVOID);STDMETHODIMP_(DWORD)AddRef(void);STDMETHODIMP_(DWORD)Release
10、(void);STDMETHODIMP SomeEventFunction(.);.;,接收器的用法,ISomeEventSet*gpSomeEventSet;./InitializeCSomeEventSet*pSink=new CSomeEventSet;pSink-QueryInterface(IID_ISomeEventSet,pSomeEventSet);/Reference count is 1./connections the sink object to the connectable object we havehr=pConnectionPoint-Advise(pSome
11、EventSet,/Reference count is 0,事件的激发和处理,BOOL CSourceObject:FireSomeEvent(IConnctionPoint*pConnectionPoint)IEnumConnections*pEnum;CONNECTDATA connectionData;if(FAILED(pConnectionPoint-EnumConnections(,与出接口有关的类型信息,客户如何知道出接口?运行时刻?编译时刻?动态构造接收器对象?动态构造vtable?支持部分成员?类型信息的协商通过IProvideClassInfo2能否用标准的接口作为出接口
12、?,用IDispatch接口作为出接口(一),IDispatch接口class IDispatch:public IUnknown public:virtual HRESULT GetTypeInfoCount(UINT*pctinfo)=0;virtual HRESULT GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo*ppTInfo)=0;virtual HRESULT GetIDsOfNames(REFIID riid,LPOLESTR*rgszNames,UINT cNames,LCID lcid,DISPID*rgDispId)=0;virtu
13、al HRESULT Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS*pDispParams,VARIANT*pVarResult,EXCEPINFO*pExcepInfo,UINT*puArgErr)=0;,用IDispatch接口作为出接口(二),IDispatch出接口的事件激发函数,void CMySourceObj:FireMyMethod(short nInt)COleDispatchDriver driver;POSITION pos=m_xMyEventSet.GetStartPos
14、ition();LPDISPATCH pDispatch;while(pos!=NULL)pDispatch=(LPDISPATCH)m_xMyEventSet.GetNextConnection(pos);ASSERT(pDispatch!=NULL);driver.AttachDispatch(pDispatch,FALSE);TRYdriver.InvokeHelper(eventidMyMethod,DISPATCH_METHOD,VT_EMPTY,NULL,(BYTE*)(VTS_I2),nInt);END_TRYdriver.DetachDispatch();,用连接点机制实现回调的讨论,比传统的回调函数功能强大,灵活可以跨进程、跨机器Tightly coupled vs loosely coupled(COM+)要求客户与组件同步没有第三方的参与,所以双方必须保持共识,VB中使用出接口,使用浏览器控件的事件函数使两个窗口同步,