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毫秒