六、COM_INTERFACE_ENTRY_AGGREGATE_BLIND 参ATL例程COMMAP
上一节我们讲了COM_INTERFACE_ENTRY_AGGREGATE,这节要介绍的宏与它很类似。
#define COM_INTERFACE_ENTRY_AGGREGATE_BLIND(punk)/
{NULL,/
(DWORD)offsetof(_ComMapClass, punk),/
_Delegate},
从定义上就可以看出,它与上一节介绍宏的唯一区别就在于,它没有指明接口ID!!
所以在它的定义中第一项也是NULL。
这个宏的用法与我们COM_INTERFACE_ENTRY_AGGREGATE一模一样。大家可以参考上一节
内容以及ATL的例程COMMAP。
我们来看看AtlInternalQueryInterface()中的相关代码。
ATLINLINE ATLAPI AtlInternalQueryInterface(void* pThis,
const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
{
//如果是IUnknown,....
while (pEntries->pFunc != NULL)
{
BOOL bBlind = (pEntries->piid == NULL);
if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid))
{
if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) //offset
{
ATLASSERT(!bBlind);
IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
pUnk->AddRef();
*ppvObject = pUnk;
return S_OK;
}
else
{
HRESULT hRes = pEntries->pFunc(pThis,
iid, ppvObject, pEntries->dw);
if (hRes == S_OK || (!bBlind && FAILED(hRes)))
return hRes;
}
}
pEntries++;
}
return E_NOINTERFACE;
}
}
注意变量bBlind;
BOOL bBlind = (pEntries->piid == NULL);
若没指定接口ID,也继续执行后面的操作,可见即使并非我们所需要的IID,也会执行
_Delegate.
从上可见,这个宏适用于一个聚集组件有多个接口的情况,这样只要是查询这个聚集组
件的接口,就会进入_Delegate函数。但要特别注意的是这个宏的位置!!
比如若是这样的顺序:
BEGIN_COM_MAP
COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pUnkAggBlind.p)
COM_INTERFACE_ENTRY(IOuter)
END_COM_MAP
当查询IOuter接口时就会出错!!!
上一节我们讲了COM_INTERFACE_ENTRY_AGGREGATE,这节要介绍的宏与它很类似。
#define COM_INTERFACE_ENTRY_AGGREGATE_BLIND(punk)/
{NULL,/
(DWORD)offsetof(_ComMapClass, punk),/
_Delegate},
从定义上就可以看出,它与上一节介绍宏的唯一区别就在于,它没有指明接口ID!!
所以在它的定义中第一项也是NULL。
这个宏的用法与我们COM_INTERFACE_ENTRY_AGGREGATE一模一样。大家可以参考上一节
内容以及ATL的例程COMMAP。
我们来看看AtlInternalQueryInterface()中的相关代码。
ATLINLINE ATLAPI AtlInternalQueryInterface(void* pThis,
const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
{
//如果是IUnknown,....
while (pEntries->pFunc != NULL)
{
BOOL bBlind = (pEntries->piid == NULL);
if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid))
{
if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) //offset
{
ATLASSERT(!bBlind);
IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
pUnk->AddRef();
*ppvObject = pUnk;
return S_OK;
}
else
{
HRESULT hRes = pEntries->pFunc(pThis,
iid, ppvObject, pEntries->dw);
if (hRes == S_OK || (!bBlind && FAILED(hRes)))
return hRes;
}
}
pEntries++;
}
return E_NOINTERFACE;
}
}
注意变量bBlind;
BOOL bBlind = (pEntries->piid == NULL);
若没指定接口ID,也继续执行后面的操作,可见即使并非我们所需要的IID,也会执行
_Delegate.
从上可见,这个宏适用于一个聚集组件有多个接口的情况,这样只要是查询这个聚集组
件的接口,就会进入_Delegate函数。但要特别注意的是这个宏的位置!!
比如若是这样的顺序:
BEGIN_COM_MAP
COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pUnkAggBlind.p)
COM_INTERFACE_ENTRY(IOuter)
END_COM_MAP
当查询IOuter接口时就会出错!!!