_Undocumented Corner_
by George Shepherd and Scot Wingo

Listing One
class ATL_NO_VTABLE CDefault : 
   public CComObjectRootEx<CComSingleThreadModel>,
   public CComCoClass<CDefault, &CLSID_Default>,
   public IDispatchImpl<IDefault, &IID_IDefault, &LIBID_ATLTESTLib>
{
public:
   CDefault() {
   }
DECLARE_REGISTRY_RESOURCEID(IDR_DEFAULT)
BEGIN_COM_MAP(CDefault)
   COM_INTERFACE_ENTRY(IDefault)
   COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IDefault
public:
};

Listing Two
template <class ThreadModel>
class CComObjectRootEx : public CComObjectRootBase
{
public:
   typedef ThreadModel _ThreadModel;
   typedef _ThreadModel::AutoCriticalSection _CritSec;

   ULONG InternalAddRef() {
      return _ThreadModel::Increment(&m_dwRef);
   }
   ULONG InternalRelease() {
      return _ThreadModel::Decrement(&m_dwRef);
   }
   void Lock() {m_critsec.Lock();}
   void Unlock() {m_critsec.Unlock();}
private:
   _CritSec m_critsec;
};

Listing Three
class CComMultiThreadModelNoCS
{
public:
    static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
    static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
    typedef CComFakeCriticalSection AutoCriticalSection;
    typedef CComFakeCriticalSection CriticalSection;
    typedef CComMultiThreadModelNoCS ThreadModelNoCS;
};
class CComMultiThreadModel
{
public:
    static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
    static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
    typedef CComAutoCriticalSection AutoCriticalSection;
    typedef CComCriticalSection CriticalSection;
    typedef CComMultiThreadModelNoCS ThreadModelNoCS;
};
class CComSingleThreadModel
{
public:
    static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
    static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
    typedef CComFakeCriticalSection AutoCriticalSection;
    typedef CComFakeCriticalSection CriticalSection;
    typedef CComSingleThreadModel ThreadModelNoCS;
};

Listing Four
Class CDefault : public IDispatch,
                        IDefault {
   HRESULT QueryInterface(RIID riid, 
                          void** ppv) {
      if(riid == IID_IDispatch)
         *ppv = (IDispatch*) this;
      else if(riid == IID_IDefault)
         *ppv = (IDefault*) this;
      else {
         *ppv = 0;
         return E_NOINTERFACE;
      }
      ((IUnknown*)(*ppv))->AddRef();
      return NOERROR;
   } 
   // AddRef, Release, and other functions
}; 

Listing Five
#define BEGIN_COM_MAP(x) public: 
  typedef x _ComMapClass; 
  static HRESULT WINAPI _Cache(void* pv,REFIID iid,void** ppvObject,DWORD dw){
     _ComMapClass* p = (_ComMapClass*)pv;
      p->Lock();
      HRESULT hRes = 
         CComObjectRootBase::_Cache(pv, iid, ppvObject, dw);
      p->Unlock();
      return hRes;
   }
   IUnknown* GetUnknown() { 
      _ASSERTE(_GetEntries()[0].pFunc == _ATL_SIMPLEMAPENTRY); 
      return (IUnknown*)((int)this+_GetEntries()->dw); 
   }
   HRESULT _InternalQueryInterface(REFIID iid, void** ppvObject) { 
      return InternalQueryInterface(this, _GetEntries(), iid, ppvObject); 
   } 
   const static _ATL_INTMAP_ENTRY* WINAPI _GetEntries() { 
      static const _ATL_INTMAP_ENTRY _entries[] = { 
                        DEBUG_QI_ENTRY(x)
   ...
   #define END_COM_MAP()   {NULL, 0, 0}};\
    return _entries;}


Listing Six
struct _ATL_INTMAP_ENTRY {
   const IID* piid;       
   DWORD dw;
   _ATL_CREATORARGFUNC* pFunc; 
}

Listing Seven
#define offsetofclass(base,derived)((DWORD)(static_cast<base*>((derived*)8))-8)
#define COM_INTERFACE_ENTRY(x)\
    {&IID_##x, \
    offsetofclass(x, _ComMapClass), \
    _ATL_SIMPLEMAPENTRY},

Listing Eight
const static _ATL_INTMAP_ENTRY* __stdcall _GetEntries() { 
  static const _ATL_INTMAP_ENTRY _entries[] = { 
    {&IID_IDefault, 
    ((DWORD)(static_cast<IDefault*>((_ComMapClass*)8))-8),
    ((_ATL_CREATORARGFUNC*)1)},
    {&IID_IDispatch, 
    ((DWORD)(static_cast<IDispatch*>((_ComMapClass*)8))-8), 
    ((_ATL_CREATORARGFUNC*)1)},
    {0, 0, 0}
  }; 
  return _entries;
}


