全部博文(20)
分类: WINDOWS
2008-05-05 14:40:40
class CMyComponent : public CUnknown, public ISomeInterface
{
public:
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if( riid == IID_ISomeInterface )
{
return GetInterface((ISomeInterface*)this, ppv);
}
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
CMyComponent(TCHAR *tszName, LPUNKNOWN pUnk, HRESULT *phr)
: CUnknown(tszName, pUnk, phr)
{
/* Other initializations */
};
// More declarations will be added later.
};
调用QueryInterface和NonDelegatingQueryInterface的几种形式:
QueryInterfacethis-> NonDelegatingQueryInterface(INonDelegatingUnknown *)this-> NonDelegatingQueryInterface(IUnknown *)(INonDelegatingUnknown *)this-> QueryInterfaceNonDelegatingQueryInterface。CMyComponent类如何查询接口:CMyComponent *pCMyComponent = new CMyComponent (L”MyComponent”,NULL,NULL);ISomeInterface *pSomeInterface = NULL;pMyComponent->QueryInterface(IID_ISomeInterface,(void**)&pSomeInterface)在这里使用的是“this-> QueryInterface”方式调用QueryInterface函数。 对象要查询接口,首先调用QueryInterface成员函数进行查询, CMyComponent类通过DECLARE_IUNKNOWN宏定义了QueryInterface成员函数,DECLARE_IUNKNOWN的定义如下:MyComponent.QueryInterface(IID_ISomeInterface,(void**)&pSomeInterface)(IID_ISomeInterface,(void**)&pSomeInterface)CMyComponent::CMyComponent(IUnknown *pOuterUnkown)
{
if (pOuterUnknown == NULL)
m_pUnknown = (IUnknown *)(INonDelegatingUnknown *)this;
else
m_pUnknown = pOuterUnknown;
[ ... more constructor code ... ]
}
CMyComponent)所属对象的IUnknown接口的指针,如果该对象(CMyComponent)是聚合对象,它的拥有者是外部对象(m_pUnknown = pOuterUnknown),否则,此对象拥有自己(m_pUnknown = (IUnknown *)(INonDelegatingUnknown *)this)。 m_pUnknown = (IUnknown *)(INonDelegatingUnknown *)this;也将this转换成了IUnknown *对象。HRESULT QueryInterface(REFIID iid, void **ppv)
{
return m_pUnknown->QueryInterface(iid, ppv);
}
(IUnknown *)(INonDelegatingUnknown *)this-> QueryInterface”方式调用,实际上调用的是NonDelegatingQueryInterface。因为m_pUnknown是通过语句m_pUnknown = (IUnknown *)(INonDelegatingUnknown *)this;转换过来的。 注意:这里不是“this-> QueryInterface”,而是“(IUnknown *)(INonDelegatingUnknown *)this-> QueryInterface”,这两者有本质的区别:如果是“this-> QueryInterface”,这样调用的是DECLARE_IUNKNOWN宏中定义的QueryInterface, 如下所示: (INonDelegatingUnknown *)this-> QueryInterface,将导致编译错误,因为INonDelegatingUnknown接口没有QueryInterface函数。语
句(IUnknown *)(INonDelegatingUnknown
*)this先将this转换成INonDelegatingUnknown指针,因为this和INonDelegatingUnknown之间存在继
承关系,所以经过转换得到的指针将指向this物体中的INonDelegatingUnknown部分,然后再将
INonDelegatingUnknown指针转换成IUnknown指针,因为INonDelegatingUnknown和IUnknown之间不
存在继承关系,所以指针实际上还是指向this物体中的INonDelegatingUnknown部分,而这样做的目的是用一条语句使对于聚合和非聚合
都适应,如果是非聚合,m_pUnknown 等于(IUnknown *)(INonDelegatingUnknown
*)this,所以m_pUnknown-> QueryInterface将调用INonDelegatingUnknown接口的 NonDelegatingQueryInterface,而如果是聚合m_pUnknown等于外部对象IUnknown接口指针,则m_pUnknown-> QueryInterface调用的是外部对象IUnknown接口的QueryInterfaceNonDelegatingQueryInterface的定义:STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if( riid == IID_ISomeInterface )
{
return GetInterface((ISomeInterface*)this, ppv);
}
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
m_pUnknown-> AddRef();调用的是NonDelegatingAddRef();