⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atlcompose.h

📁 The source code samples for chapter 2, 4, 6, and 8 are contained in the EvenChapters project. Those
💻 H
字号:
// atlcompose.h: ATL composition support
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1997-1998, 1998 Chris Sells
// All rights reserved.
//
// 8/14/98
// -Fixed ref-count bug pointed out by Valery Pryamikov.
//  Unfortunately, this means that the interface map composing
//  macros can no longer be used as the first entry in the map.
// -Put _Compose function back so ATL will catch it if you
//  try to make one of the COMPOSE macros first in your map.
//
// 4/15/98
// -Added support for Dual composed interfaces via
//  BEGIN_COMPOSED_CLASS_DUAL and BEGIN_COMPOSED_CLASS_DUAL_EX.
//
// 2/18/98
// -Fixed a bug where the composition macros couldn't
//  be used at the first entry in a COM_MAP
//  (now they can be).
// -Fixed a bug that prevented the This() function
//  from being used to access protected and private
//  members of the composing class.
// -Thanks to Russ for pointing these two bugs out to me.
//
// 2/13/98
// -Replaced _Compose function w/ _ATL_SIMPLEMAPENTRY
//
// NO WARRANTIES ARE EXTENDED. USE AT YOUR OWN RISK.
//
// To contact the author with suggestions or comments, use csells@sellsbrothers.com.
/////////////////////////////////////////////////////////////////////////////
// This set of macros is for using nested compostion in ATL.
// The benefit of composition is that it is easy to implement
// multiple interfaces with methods with the same name
// but that require different behavior, e.g.
//
// interface IArtist : IUnknown {
//   HRESULT Draw();
// }
//
// interface ICowboy : IUnknown {
//   HRESULT Draw();
// }
//
// The benefit of this particular implementation is that it 
// has no object size overhead. Interfaces implemented using
// nested composition have no greater space requirements than
// using multiple-inheritance and no speed hit.
//
// COM_INTERFACE_ENTRY_COMPOSED(itf, classInner)
//  Macro for putting composed interfaces into the interface map.
//
// COM_INTERFACE_ENTRY_COMPOSED_IID(iid, classInner)
//  Macro for putting composed interfaces with an interface different from
//  the name of the interface into the interface map.
//
// BEGIN_COMPOSED_CLASS(classOuter, itf, classInner)
//  Macro for starting the declaration of a composed class.
//
// BEGIN_COMPOSED_CLASS_DUAL(classOuter, itf, libid, classInner)
//  Macro for starting the declaration of a composed class
//  that implements a dual interface.
//
// BEGIN_COMPOSED_CLASS_DUAL_EX(classOuter, itf, libid, major, minor, classInner)
//  Macro for starting the declaration of a composed class
//  that implements a dual interface of some version other than 1.0.
//
// END_COMPOSED_CLASS(classInner)
//  Macro for ending the declaration of a composed class.
//
// This()
//  Method for accessing composing class inside of a composed class method.
//  Returns a pointer to a classOuter type.
//
// Intended usage:
/*
class CAcePowell : ... // code remove for clarity
    public IArtist // ICowboy not in list of interfaces
{
public:
BEGIN_COM_MAP(CAcePowell)
	COM_INTERFACE_ENTRY(IArtist)
    COM_INTERFACE_ENTRY_COMPOSED(ICowboy, XCowboy)
END_COM_MAP()

// IArtist
    STDMETHODIMP Draw()
    {
        MessageBox(0, "Say 'Cheese.'", "IArtist::Draw", MB_SETFOREGROUND);
        return S_OK;
    }

// ICowboy
BEGIN_COMPOSED_CLASS(CAcePowell, ICowboy, XCowboy)

    STDMETHODIMP Draw()
    {
        MessageBox(0, "Reach for the sky.", "ICowboy::Draw", MB_SETFOREGROUND);
        return S_OK;
    }

END_COMPOSED_CLASS(XCowboy)
};
*/
//
// When implementing methods outside of the class declaration, use the classInner
// name as part of the scope resolution, e.g.
//
/*
// AcePowell.h

class CAcePowell : ... // code remove for clarity
{
    ... // more code remove for clarity

// ICowboy
BEGIN_COMPOSED_CLASS(CAcePowell, ICowboy, XCowboy)
    STDMETHODIMP Draw();    // Code not part of the class declaration
END_COMPOSED_CLASS(XCowboy)
};

// AcePowell.cpp

// classInner used as part of the scope resolution
STDMETHODIMP CAcePowell::XCowboy::Draw()
{
    MessageBox(0, "Reach for the sky.", "ICowboy::Draw", MB_SETFOREGROUND);
    return S_OK;
}
*/
//
// When exposing base interfaces from a composed interface, make sure is
// one BEGIN_COMPOSED_CLASS macro for each IID and that the BEGIN_COMPOSED_CLASS
// macro has the name of the most derived interface, e.g.
//
/*
// AcePowell.idl

interface ICowboyEx : ICowboy
{
    HRESULT QuickDraw();
};

// AcePowell.h

class CAcePowell : ... // code remove for clarity
{
public:
BEGIN_COM_MAP(CAcePowell)
	COM_INTERFACE_ENTRY(IArtist)
    COM_INTERFACE_ENTRY_COMPOSED(ICowboy, XCowboy)   // Both ICowboy and ICowboyEx
    COM_INTERFACE_ENTRY_COMPOSED(ICowboyEx, XCowboy) // exposed from XCowboy
END_COM_MAP()

    ... // more code remove for clarity

// ICowboy
BEGIN_COMPOSED_CLASS(CAcePowell, ICowboyEx, XCowboy)
    STDMETHODIMP Draw();
    STDMETHODIMP QuickDraw();
END_COMPOSED_CLASS(XCowboy)
};
*/
//
// BTW, Ace Powell was an artist-cowboy who lived at the turn of the century.
// I'd like to thank Tim Ewald for this example (which I've since beaten to death).
//

#pragma once
#include <stddef.h> // offsetof

inline
HRESULT WINAPI _Compose(void* pvThis, REFIID riid, LPVOID* ppv, DWORD dw)
{
    *ppv = (BYTE*)pvThis + dw;
    reinterpret_cast<IUnknown*>(*ppv)->AddRef();
    return S_OK;
}

#define COM_INTERFACE_ENTRY_COMPOSED(itf, classInner) \
    {&IID_##itf, offsetof(_ComMapClass, m_##classInner), _Compose},

#define COM_INTERFACE_ENTRY_COMPOSED_IID(iid, classInner) \
    {&iid, offsetof(_ComMapClass, m_##classInner), _Compose},

#define BEGIN_COMPOSED_CLASS(classOuter, itf, classInner) \
    class classInner; \
    friend class classInner; \
    class classInner : public itf { \
    private: \
        classOuter* This() \
        { return (classOuter*)((BYTE*)this - offsetof(classOuter, m_##classInner)); } \
    public: \
        STDMETHODIMP QueryInterface(REFIID riid, void** ppv) \
        { return This()->_InternalQueryInterface(riid, ppv); } \
        STDMETHODIMP_(ULONG) AddRef() \
        { return This()->GetUnknown()->AddRef(); } \
        STDMETHODIMP_(ULONG) Release() \
        { return This()->GetUnknown()->Release(); }

#define BEGIN_COMPOSED_CLASS_DUAL(classOuter, itf, libid, classInner) \
    class classInner; \
    friend class classInner; \
    class classInner : public IDispatchImpl<itf, &IID_##itf, &libid> { \
    private: \
        classOuter* This() \
        { return (classOuter*)((BYTE*)this - offsetof(classOuter, m_##classInner)); } \
    public: \
        STDMETHODIMP QueryInterface(REFIID riid, void** ppv) \
        { return This()->_InternalQueryInterface(riid, ppv); } \
        STDMETHODIMP_(ULONG) AddRef() \
        { return This()->GetUnknown()->AddRef(); } \
        STDMETHODIMP_(ULONG) Release() \
        { return This()->GetUnknown()->Release(); }

#define BEGIN_COMPOSED_CLASS_DUAL_EX(classOuter, itf, libid, major, minor, classInner) \
    class classInner; \
    friend class classInner; \
    class classInner : public IDispatchImpl<itf, &IID_##itf, &libid, major, minor> { \
    private: \
        classOuter* This() \
        { return (classOuter*)((BYTE*)this - offsetof(classOuter, m_##classInner)); } \
    public: \
        STDMETHODIMP QueryInterface(REFIID riid, void** ppv) \
        { return This()->_InternalQueryInterface(riid, ppv); } \
        STDMETHODIMP_(ULONG) AddRef() \
        { return This()->GetUnknown()->AddRef(); } \
        STDMETHODIMP_(ULONG) Release() \
        { return This()->GetUnknown()->Release(); }

#define END_COMPOSED_CLASS(classInner) } m_##classInner;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -