荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Deny (冬天来咯), 信区: Program
标  题: 九、COM_INTERFACE_ENTRY_CHAIN(classname)
发信站: 荔园晨风BBS站 (Thu Nov 15 20:11:13 2001), 转信

九、COM_INTERFACE_ENTRY_CHAIN(classname) 参ATL例程COMMAP

先看看它的定义:
#define COM_INTERFACE_ENTRY_CHAIN(classname)\
{NULL,\
(DWORD)&_CComChainData::data,\
_Chain},

典型用法:
class CChain :
public IDispatchImpl,
public ISupportErrorInfo,
public CComObjectRoot
public CComCoClass
{
........
};
它与一般的组件无异。
class COuter :
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
_ATL_CHAINDATA _CComChainData::data =
{offsetofclass(base, derived), base::_GetEntries};
基本上我们已经看懂是怎么回事了,void *p将得到基类的指针,
InteralQueryInterface
我们已经很熟悉了,_Chain把基类的指针以及基类的接口映射宏传给它,实际上是
查询
基类的接口!!!

一般情况下把这个宏放在BEGIN_COM_MAP和END_COM_MAP之间的最后面,这表示只有
在当
前类中查不到接口时才去查父类的接口。不过也经常把它放在第一位,这时就是先
去查
父类接口,只有父类没有实现这种接口时才查自己。在ATL中组件是以多重继承的
方式实
现的,ATL定义了很多类实现了一些常用的接口,这些类经常被做为组件的基类,
所以这
个宏被大量使用。



所有重要的宏我们都已经讲过了,剩下的都是些很简单的宏了.呵呵,还是把它们都
罗列一
下,善始善终嘛.
--
Deny就要毕业了,^_^编程资料:1.201/study/my document/,也许有你要的东西╭──你?
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
├────你尽指着天上的星星☆说~~天天跑步引体向上───────┤
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤
╰─你还说:我是一个乖孩子_      前  路  漫  漫  任  我  闯    ╱
                           ╲_︵_︵_︵_︵_︵_︵_︵_︵╱

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.1.201]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店