COM中的可连接对象与连接点机制及其MFC程序实现 |
责任编辑:admin 更新日期:2005-8-6 |
本文首先论述可连接对象和连接点机制的原理,然后通过一个示例说明怎样用MFC编程实现可连接对象和内嵌于客户的事件接收器. 1、可连接对象和连接点机制的基本原理 为了在组件对象和客户之间提供更大的交互能力,组件对象也需要主动与客户进行通信。组件对象通过出接口(Outgoing Interface)与客户进行通信。如果一个组件对象定义了一个或者多个出接口则此组件对象叫做可连接点对象。 所谓出接口也是COM接口。每个出接口包含一组成员函数,每个成员函数代表了一个事件、一个通知或者一个请求。但是这些接口是在客户的事件接收器(sink)中实现的,所以叫出接口。事件接收器也是COM对象。 可连接对象必须实现一个IConnectionPointContainer接口用于管理所有的出接口。每个出接口对应一个连接点对象,连接 点对象实现了IConnectionPoint接口。客户正是通过IConnectionPoint接口与可连接对象建立连接。每一个连接用 CONNECTDATA结构描述。 CONNECTDATA包含两个成员:IUnknown* pUnk和DWORD dwCookie。pUnk对应于客户中事件接收器的IUnknown接口指针;dwCookie是由连接点对象生成的用于唯一标识此连接的32位整数。 通过一个由可连接对象实现的枚举器接口IEnumConnectionPoints,客户可以访问可连接对象的所有连接点。但是要获得 IEnumConnectionPoints接口指针,要通过IConnectionPointContainer:: EnumConnectionPoints(IEnumConnectionPoints**)函数,此函数返回枚举器接口指针。 通过另一个有可连接对象实现的枚举器接口IEnumConnections,无论客户还是可连接对象都可以访问一个连接点上的所有连接。通过 IConnectionPoint::EnumConnections(IEnumConnections**)函数可以获得 IEnumConnections接口指针。 综上所述,一个可连接对象必须实现四个接口:IConnectionPointContainer、IConnectionPoint、IEnumConnectionPoints、IEnumConnections。这四个接口的定义请阅读MSDN文档。 现在结合后面的示例简单描述一下可连接对象和客户通信的过程。在后面的示例中,可连接对象ConnObject定义了出接口 IEventSink,对应此出接口,实现了一个连接点对象SampleConnPoint(此对象实现了对应于出接口的连接点接口 IConnectionPoint,接口ID为IID_IEventSink)。 1.客户在获取了可连接对象的IUnknown接口指针m_pIUnknown后,调用m_pIUnknown-> QueryInterface(IID_IConnectionPointContainer,(void**)&pConnPtCont);如 果调用成功,pConnPtCont中将存放可连接对象的IConnectionPointContainer接口指针。如果调用不成功,则表明对象不是 可连接对象。 2.调用pConnPtCont->FindConnectionPoint(IID_IEventSink,& pConnPt)。如果调用成功,pConnPt将存放对应于出接口IEventSink的连接点对象SampleConnPoint所实现的连接点接口 IConnectionPoint指针;如果调用不成功,说明可连接对象不支持出接口IEventSink。 3.调用pConnPt->Advise(pIEventSink,&m_dwCookie)以建立事件接收器 (EventSink)与连接点的连接。其中pIEventSink是客户事件接收器IUnknown接口的指针,此指针通过此函数传递给了可连接对象以 便可连接对象发起对客户的通信;m_dwCookie是连接标识,此值由可连接对象设置由客户保存,客户还要使用此值以断开连接。 4.可连接对象可以通过连接点调用客户事件接收器中的方法。在客户与连接点成功建立连接后,连接点中已经保存了客户事件接收器接口的指针并可以调用pConnPt->GetConnections()来获取。 5.客户调用pConnPt->Unadvise(m_dwCookie)来取消连接,同时调用pConnPt->Release()释放连接点对象。 2、编程实例 现在用MFC实现一个可连接对象,然后写一个极为简单的客户和时间接收器。 需要说明的是,MFC通过CCmdTarget类实现了IConnectionPointContainer和IEnumConnectionPoints接口,此外,通过CConnectionPoint类实现了IConnectionPoint接口 1.可连接对象ConnObject 在这个对象中,实现一个一般的COM接口IEventServer,客户可以使用此接口的方法DoSomething()作一些事情,但主要的是对象将在此处触发事件。SampleConnPoint实现连接点对象。 (1)在GUIDs.h中写入: // {EE888B01-EA9C-11d3-97B5-5254AB191930} static const IID CLSID_ConnObject = //组件ID { 0xee888b01, 0xea9c, 0x11d3, { 0x97, 0xb5, 0x52, 0x54, 0xab, 0x19, 0x19, 0x30 } }; // {EE888B02-EA9C-11d3-97B5-5254AB191930} static const IID IID_IEventServer = //一般的COM接口,客户使用此接口的方法 //DoSomething() { 0xee888b02, 0xea9c, 0x11d3, { 0x97, 0xb5, 0x52, 0x54, 0xab, 0x19, 0x19, 0x30 } }; {EE888B03-EA9C-11d3-97B5-5254AB191930} static const IID IID_IEventSink = //连接点对象所实现的连接点接口ID { 0xee888b03, 0xea9c, 0x11d3, { 0x97, 0xb5, 0x52, 0x54, 0xab, 0x19, 0x19, 0x30 } }; 2. 在IConnObject.h中写入 #include "GUIDs.h" //声明IEventServer接口 DECLARE_INTERFACE_(IEventServer,IUnknown) { STDMETHOD(DoSomething)()PURE; }; //声明出接口,此出接口将由客户的事件接收器实现 DECLARE_INTERFACE_(IEventSink,IUnknown) { STDMETHOD(EventHandle)()PURE; }; |
MFC中实现连接点(上)
最新推荐文章于 2019-03-06 18:54:22 发布