BEGIN_INTERFACE_PART(TestInterface, IMyTest) //声明实现接口IMyTest的嵌套类
STDMETHOD(Test)();
END_INTERFACE_PART(FontNotify2)
(2)CSampleView类实现中加入以下代码:
BEGIN_INTERFACE_MAP(CSampleView, CCmdTarget)
INTERFACE_PART(CSampleView, IID_IMyTest, TestInterface)
END_INTERFACE_MAP()
STDMETHODIMP_(ULONG) CSampleView::XTestInterface::AddRef( )
{
METHOD_PROLOGUE_EX(CSampleView, TestInterface)
return (ULONG)pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) CSampleView::XTestInterface::Release( )
{
METHOD_PROLOGUE_EX(CSampleView, TestInterface)
return (ULONG)pThis->ExternalRelease();
}
STDMETHODIMP CSampleView::XTestInterface::QueryInterface( REFIID iid, LPVOID FAR* ppvObj )
{
METHOD_PROLOGUE_EX(CSampleView, TestInterface)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj) ;
}
STDMETHODIMP CSampleView::XTestInterface::Test()
{
METHOD_PROLOGUE_EX(CSampleView, TestInterface)
// do something you like
return S_OK ;
}
揭开宏的神秘面纱,看看它到底是什么东西。以下都是简化的版本。
(1)DECLARE_INTERFACE_MAP
struct AFX_INTERFACEMAP_ENTRY
{
const void* piid;
// the interface id (IID) (NULL for aggregate)
size_t nOffset;
// offset of the interface vtable from m_unknown
};
struct AFX_INTERFACEMAP
{
const AFX_INTERFACEMAP* (PASCAL* pfnGetBaseMap)(); // NULL is root class
const AFX_INTERFACEMAP_ENTRY* pEntry; // map for this class
};
#define DECLARE_INTERFACE_MAP() \
private: \
static const AFX_INTERFACEMAP_ENTRY _interfaceEntries[]; \
protected: \
static AFX_DATA const AFX_INTERFACEMAP interfaceMap; \
static const AFX_INTERFACEMAP* PASCAL _GetBaseInterfaceMap(); \
virtual const AFX_INTERFACEMAP* GetInterfaceMap() const; \
(2)BEGIN_INTERFACE_PART/END_INTERFACE_PART
#define BEGIN_INTERFACE_PART(localClass, baseClass) \// 定义了一个嵌套类
class X##localClass : public baseClass \
{ \
public: \
STDMETHOD_(ULONG, AddRef)(); \
STDMETHOD_(ULONG, Release)(); \
STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppvObj); \
#define END_INTERFACE_PART(localClass) \
} m_x##localClass; \
friend class X##localClass; \
(3)BEGIN_INTERFACE_MAP/INTERFACE_PART/END_INTERFACE_MAP
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#define BEGIN_INTERFACE_MAP(theClass, theBase) \
const AFX_INTERFACEMAP* PASCAL theClass::_GetBaseInterfaceMap() \
{ return &theBase::interfaceMap; } \
const AFX_INTERFACEMAP* theClass::GetInterfaceMap() const \
{ return &theClass::interfaceMap; } \
AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP theClass::interfaceMap = \
{ &theClass::_GetBaseInterfaceMap, &theClass::_interfaceEntries[0], }; \
AFX_COMDAT const AFX_DATADEF AFX_INTERFACEMAP_ENTRY theClass::_interfaceEntries[] = \
{ \
#define INTERFACE_PART(theClass, iid, localClass) \
{ &iid, offsetof(theClass, m_x##localClass) }, \
#define END_INTERFACE_MAP() \
{ NULL, (size_t)-1 } \
}; \
(4)METHOD_PROLOGUE_EX
#define METHOD_PROLOGUE_EX(theClass, localClass) \
METHOD_PROLOGUE(theClass, localClass) \
#define METHOD_PROLOGUE(theClass, localClass) \
theClass* pThis = \
((theClass*)((BYTE*)this - offsetof(theClass, m_x##localClass))); \
AFX_MANAGE_STATE(pThis->m_pModuleState) \
pThis; // avoid warning from compiler \
METHOD_PROLOGUE最大的作用就是得到pThis指针。该宏用在嵌套类的成员函数中,pThis是其父类的指针,这里也即是CSampleView的this指针。