欢迎来到天天文库
浏览记录
ID:42769796
大小:49.50 KB
页数:11页
时间:2019-09-21
《ATL接口映射宏详解(下)》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、ATL接口映射宏详解(下)五.COM_INTERFACE_ENTRY_AGGREGATE(iid,punk)参ATL例程COMMAP这一节中将介绍ATL中用于聚集对象的宏。聚集对象的概念请参阅其它参考书。现在先看一看这个宏的典型用法:classCAgg:publicIDispatchImpl,publicISupportErrorInfo,publicCComObjectRoot,publicCComCoClass2、LSID_CAgg>{.....};CAgg是一个聚集类,它的实现与一般的ATL组件没有区别,只是注意在它的类定义中不要加入DECLARE_NO_AGGREGATABLE.classCOuter:publicCChainBase,publicIDispatchImpl,publicCComCoClass{HRESULTFinalConstruct();voidFinalRelea3、se();BEGIN_COM_MAP(COuter)COM_INTERFACE_ENTRY_AGGREGATE(IID_IAgg,m_pUnkAgg.p)END_COM_MAP()DECLARE_GET_CONTROLLING_UNKNOWN()CComPtrm_pUnkAgg;};COuter包含了聚合组件CAgg,它包含了几个不同之处:(1)加入了COM_INTERFACE_ENTRY_AGGREGATE(IID_IAgg,m_pUnkAgg.p)宏。#defineCOM4、_INTERFACE_ENTRY_AGGREGATE(iid,punk){&iid,(DWORD)offsetof(_ComMapClass,punk),_Delegate},offsetof我们在上一节中已经见过,可以猜到它求的就是punk在类中的位置。也就是m_pUnkAgg在COuter中的位置。(2)加入了宏DECLARE_GET_CONTROLLING_UNKNOWN(),其定义为:#defineDECLARE_GET_CONTROLLING_UNKNOWN()public:v5、irtualIUnknown*GetControllingUnknown(){returnGetUnknown();}我们也没必要继续深究下去,仅从字面意思就可以看出这个函数将返回组件的IUnknown指针。(3)在COuter中加入一个成员变量:CComPtrm_pUnkAgg;m_pUnkAgg将用于获得被聚集组件的IUnknown指针。(4)重载了FinalConstruct,FinalReleaseHRESULTCOuter::FinalConstruct(){IUn6、known*pUnkOuter=GetControllingUnknown();HRESULThRes=CoCreateInstance(CLSID_CAgg,pUnkOuter,CLSCTX_ALL,IID_IUnknown,(void**)&m_pUnkAgg);returnhRes;}voidCOuter::FinalRelease(){m_pUnkAgg.Release();.....}当创建组件COuter后将会调用FinalConstruct,所以会在这里创建聚集组件。原则上聚集组件7、可以仅在需要的时候才创建,但也可以随着包含它的组件一起创建。聚集组件的创建没什么特别之处,只是要注意它将查询IUnknown指针,并返回给m_pUnkAgg.外部组件将通过m_pUnkAgg操作聚集组件。另外注意到使用pUnkOuter作为CoCreateInstance的参数,这将导致创建CComAggObject对象,内部包含一个CComContainedObject的包含对象。与上一节中的CComCachedTearOff<>类似,CComAggObject8、也不是从COuter派生的,所以真正的组件对象不是CComAggObject对象,而是它内部包含的CComContainedObject对象。同样pUnkOuter得到的将是CComAggObject<>的IUnknown指针,也同样调用它的QueryInterface会转而调用CComContainedObject的_InternalQueryInterface函数(呵呵,现在可都还是我猜的,看我猜的对不对吧)运行pOuter->QueryInterface(I
2、LSID_CAgg>{.....};CAgg是一个聚集类,它的实现与一般的ATL组件没有区别,只是注意在它的类定义中不要加入DECLARE_NO_AGGREGATABLE.classCOuter:publicCChainBase,publicIDispatchImpl,publicCComCoClass{HRESULTFinalConstruct();voidFinalRelea
3、se();BEGIN_COM_MAP(COuter)COM_INTERFACE_ENTRY_AGGREGATE(IID_IAgg,m_pUnkAgg.p)END_COM_MAP()DECLARE_GET_CONTROLLING_UNKNOWN()CComPtrm_pUnkAgg;};COuter包含了聚合组件CAgg,它包含了几个不同之处:(1)加入了COM_INTERFACE_ENTRY_AGGREGATE(IID_IAgg,m_pUnkAgg.p)宏。#defineCOM
4、_INTERFACE_ENTRY_AGGREGATE(iid,punk){&iid,(DWORD)offsetof(_ComMapClass,punk),_Delegate},offsetof我们在上一节中已经见过,可以猜到它求的就是punk在类中的位置。也就是m_pUnkAgg在COuter中的位置。(2)加入了宏DECLARE_GET_CONTROLLING_UNKNOWN(),其定义为:#defineDECLARE_GET_CONTROLLING_UNKNOWN()public:v
5、irtualIUnknown*GetControllingUnknown(){returnGetUnknown();}我们也没必要继续深究下去,仅从字面意思就可以看出这个函数将返回组件的IUnknown指针。(3)在COuter中加入一个成员变量:CComPtrm_pUnkAgg;m_pUnkAgg将用于获得被聚集组件的IUnknown指针。(4)重载了FinalConstruct,FinalReleaseHRESULTCOuter::FinalConstruct(){IUn
6、known*pUnkOuter=GetControllingUnknown();HRESULThRes=CoCreateInstance(CLSID_CAgg,pUnkOuter,CLSCTX_ALL,IID_IUnknown,(void**)&m_pUnkAgg);returnhRes;}voidCOuter::FinalRelease(){m_pUnkAgg.Release();.....}当创建组件COuter后将会调用FinalConstruct,所以会在这里创建聚集组件。原则上聚集组件
7、可以仅在需要的时候才创建,但也可以随着包含它的组件一起创建。聚集组件的创建没什么特别之处,只是要注意它将查询IUnknown指针,并返回给m_pUnkAgg.外部组件将通过m_pUnkAgg操作聚集组件。另外注意到使用pUnkOuter作为CoCreateInstance的参数,这将导致创建CComAggObject对象,内部包含一个CComContainedObject的包含对象。与上一节中的CComCachedTearOff<>类似,CComAggObject
8、也不是从COuter派生的,所以真正的组件对象不是CComAggObject对象,而是它内部包含的CComContainedObject对象。同样pUnkOuter得到的将是CComAggObject<>的IUnknown指针,也同样调用它的QueryInterface会转而调用CComContainedObject的_InternalQueryInterface函数(呵呵,现在可都还是我猜的,看我猜的对不对吧)运行pOuter->QueryInterface(I
此文档下载收益归作者所有