Programming 版 (精华区)
发信人: lofe ()感激生活(), 信区: Programming
标 题: ATL接口映射宏详解--(9)
发信站: 哈工大紫丁香 (Sun Sep 3 08:17:11 2000), 转信
九、COM_INTERFACE_ENTRY_CHAIN(classname) 参ATL例程COMMAP
先看看它的定义:
#define COM_INTERFACE_ENTRY_CHAIN(classname)\
{NULL,\
(DWORD)&_CComChainData<classname, _ComMapClass>::data,\
_Chain},
典型用法:
class CChain :
public IDispatchImpl<IChain, &IID_IChain, &LIBID_COMMAPLib>,
public ISupportErrorInfo,
public CComObjectRoot
public CComCoClass<CChain,&CLSID_CChain>
{
........
};
它与一般的组件无异。
class COuter :
public CChain,
....
{
BEGIN_COM_MAP(COuter)
......
COM_INTERFACE_ENTRY_CHAIN(CChain)
END_COM_MAP()
};
我们对查询的过程已经很熟悉了,可以直接来看看_Chain的功能。
_Chain()是CComObjectRootBase的成员函数:
static HRESULT WINAPI _Chain(void* pv, REFIID iid, void** ppvObject,DWORD dw)
{
_ATL_CHAINDATA* pcd = (_ATL_CHAINDATA*)dw;
void* p = (void*)((DWORD)pv + pcd->dwOffset);
return InternalQueryInterface(p, pcd->pFunc(), iid, ppvObject);
}
struct _ATL_CHAINDATA
{
DWORD dwOffset;
const _ATL_INTMAP_ENTRY* (WINAPI *pFunc)();
};
我们再看看宏定义中的dw部分:
template <class base, class derived>
_ATL_CHAINDATA _CComChainData<base, derived>::data =
{offsetofclass(base, derived), base::_GetEntries};
基本上我们已经看懂是怎么回事了,void *p将得到基类的指针,InteralQueryInterface
我们已经很熟悉了,_Chain把基类的指针以及基类的接口映射宏传给它,实际上是查询
基类的接口!!!
一般情况下把这个宏放在BEGIN_COM_MAP和END_COM_MAP之间的最后面,这表示只有在当
前类中查不到接口时才去查父类的接口。不过也经常把它放在第一位,这时就是先去查
父类接口,只有父类没有实现这种接口时才查自己。在ATL中组件是以多重继承的方式实
现的,ATL定义了很多类实现了一些常用的接口,这些类经常被做为组件的基类,所以这
个宏被大量使用。
-----------未完待续----------
--
才疏学浅,胡言乱语;不对之处,敬请指正。
路漫漫兮,其修远。
吾将上下而求索。
※ 修改:.haojs 于 Sep 3 08:14:48 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]
--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:5.135毫秒