向CCmdTarget的派生类添加一个接口的实现,向CCmdTarget的派生类添加一个接口的实现
【 tulaoshi.com - C语言心得技巧 】
DECLARE_INTERFACE_MAP() //声明接口映射(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::inter
                        
来源:http://www.tulaoshi.com/n/20160129/1487159.html
看过《向CCmdTarget的派生类添加一个接口的实现》的人还看了以下文章 更多>>