Figure 1    Standard IDL

 import "oaidl.idl";
 
 [
     uuid(7FBB6A23-1425-11d2-8CAA-85047AB53E46),
     object,
     helpstring("Standard COM Interface")
 ]
 interface ILoveCOM: IUnknown
 {
     HRESULT DevelopInterface(void);
     HRESULT ThenDevelopImplementation(void);
 }
 
 [
     uuid(7FBB6A25-1425-11d2-8CAA-85047AB53E46),
     object,
     helpstring("Another standard COM Interface")
 ]
 interface IUseAnyTool: IUnknown
 {
     HRESULT UseCPP(void);
     HRESULT UseMFC(void);
     HRESULT UseATL(void);
     HRESULT UseVB(void);
     HRESULT UseJava(void);
 }
 
 [
     uuid(7FBB6A26-1425-11d2-8CAA-85047AB53E46),
     helpstring("Tao Of COM Library"),
     version(1.0),
     lcid(0)
 ]
 library TaoOfCOMLib
 {
     importlib("stdole32.tlb");
     [
         uuid(7FBB6A27-1425-11d2-8CAA-85047AB53E46),
         helpstring("The Tao Of COM")
     ]
     coclass CoTaoOfCOM
     {
         interface IUnknown;
         interface ILoveCOM;
         interface IUseAnyTool;
     }
 }

Figure 2   A C++ COM Class


 class CoTaoOfCPP : public ILoveCOM,
               IUseAnyTool {
 
     long m_cRef;
 
 public:
     CoTaoOfCPP();
 
     // IUnknown
     STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
     STDMETHODIMP_(ULONG) AddRef(void);
     STDMETHODIMP_(ULONG) Release(void);
 
     // ILoveCOM
     STDMETHODIMP DevelopInterface(void);
     STDMETHODIMP ThenDevelopImplementation(void);
 
     // IUseAnyTool
     STDMETHODIMP UseCPP(void);
     STDMETHODIMP UseMFC(void);
     STDMETHODIMP UseATL(void);
     STDMETHODIMP UseVB(void);
     STDMETHODIMP UseJava(void);
 };

Figure 3   Implementing IUnknown in C++


 STDMETHODIMP CoTaoOfCPP::QueryInterface(REFIID riid, void **ppv) {
     if (riid == IID_ILoveCOM)
         *ppv = static_cast<ILoveCOM*>(this);
     else if (riid == IID_IUseAnyTool)
         *ppv = static_cast<IUseAnyTool*>(this);
     else if (riid == IID_IUnknown)
         *ppv = static_cast<ILoveCOM*>(this);
     else {
         *ppv = 0;
         return E_NOINTERFACE;
     }
 
     reinterpret_cast<IUnknown*>(*ppv)->AddRef();
     return S_OK;
 }
 
 STDMETHODIMP_(ULONG) CoTaoOfCPP::AddRef(void) {
     return InterlockedIncrement(&m_cRef);
 }
 
 STDMETHODIMP_(ULONG) CoTaoOfCPP::Release(void) {
     InterlockedDecrement(&m_cRef);
     if(m_cRef == 0) {
         delete this;
         return 0;
     } else
         return m_cRef;
 }

Figure 4   Declaring CTaoOfMFC


 #include "taoofcom.h"
 #include "taoofcom_i.c"
 
 ////////////////////////////////////////////////////////////////
 // CTaoOfMFC command target
 class CTaoOfMFC : public CCmdTarget
 {
     // declares the class object:
     DECLARE_OLECREATE(CTaoOfMFC)
 
     // add the queryinterface lookup table
     DECLARE_INTERFACE_MAP()
 
     // declare the nested classes
     BEGIN_INTERFACE_PART(LoveCOMObj, ILoveCOM)
     STDMETHODIMP DevelopInterface(void);
     STDMETHODIMP ThenDevelopImplementation(void);
     END_INTERFACE_PART(LoveCOMObj)
 
     BEGIN_INTERFACE_PART(UseAnyToolObj, IUseAnyTool)
     STDMETHODIMP UseCPP(void);
     STDMETHODIMP UseMFC(void);
     STDMETHODIMP UseATL(void);
     STDMETHODIMP UseVB(void);
     STDMETHODIMP UseJava(void);
     END_INTERFACE_PART(UseAnyToolObj)
 
     // ClassWizard stuff goes next…
 
 };

Figure 5   Implementing CTaoOfMFC


 IMPLEMENT_OLECREATE(CTaoOfMFC, "CTaoOfMFC",
                     0xCAB4A966, 0xA1C4, 0x11d1,
                     0x8C, 0xAA, 0xBF, 0x73, 0x5D, 0xC4, 0x0B, 0x69);
 
 BEGIN_INTERFACE_MAP(CTaoOfMFC, CCmdTarget)
     INTERFACE_PART(CTaoOfMFC, IID_ILoveCOM, LoveCOMObj)
     INTERFACE_PART(CTaoOfMFC, IID_IUseAnyTool, UseAnyToolObj)
 END_INTERFACE_MAP()
 
 STDMETHODIMP_(ULONG)
 CTaoOfMFC::XLoveCOMObj::AddRef(void)
 {
     METHOD_PROLOGUE(CTaoOfMFC, LoveCOMObj)
     return pThis->ExternalAddRef();
 }
 
 STDMETHODIMP_(ULONG)
 CTaoOfMFC::XLoveCOMObj::Release(void)
 {
     METHOD_PROLOGUE(CTaoOfMFC, LoveCOMObj)
     return pThis->ExternalRelease();
 }
 
 STDMETHODIMP
 CTaoOfMFC::XLoveCOMObj::QueryInterface(REFIID riid,
     void **ppv) {
     METHOD_PROLOGUE(CTaoOfMFC, LoveCOMObj)
     return pThis->ExternalQueryInterface(&riid, ppv);
 }
 
 STDMETHODIMP_(ULONG)
 CTaoOfMFC::XUseAnyToolObj::AddRef(void)
 {
     METHOD_PROLOGUE(CTaoOfMFC, UseAnyToolObj)
     return pThis->ExternalAddRef();
 }
 
 STDMETHODIMP_(ULONG)
 CTaoOfMFC::XUseAnyToolObj::Release(void)
 {
     METHOD_PROLOGUE(CTaoOfMFC, UseAnyToolObj)
     return pThis->ExternalRelease();
 }
 
 STDMETHODIMP
 CTaoOfMFC::XUseAnyToolObj::QueryInterface(REFIID riid,
     void **ppv) {
     METHOD_PROLOGUE(CTaoOfMFC, UseAnyToolObj)
     return pThis->ExternalQueryInterface(&riid, ppv);
 }

Figure 6   ATL-implemented Interfaces


 #include "taoofcom.h"
 #include "taoofcom_i.c"
 
 ///////////////////////////////////////////////////////////////
 // CTaoOfATL
 class ATL_NO_VTABLE CTaoOfATL :
     public CComObjectRootEx<CComSingleThreadModel>,
     public CComCoClass<CTaoOfATL, &CLSID_TaoOfATL>,
     public ILoveCOM,
     public IUseAnyTool,
     public IDispatchImpl<ITaoOfATL, &IID_ITaoOfATL, &LIBID_TAOOFATLLib>
 {
 public:
     CTaoOfATL()
     {
     }
 
 DECLARE_REGISTRY_RESOURCEID(IDR_TAOOFATL)
 
 DECLARE_PROTECT_FINAL_CONSTRUCT()
 
 BEGIN_COM_MAP(CTaoOfATL)
     COM_INTERFACE_ENTRY(ITaoOfATL)
     COM_INTERFACE_ENTRY(IDispatch)
     COM_INTERFACE_ENTRY(ILoveCOM)
     COM_INTERFACE_ENTRY(IUseAnyTool)
 END_COM_MAP()
 
 // ITaoOfATL
 public:
 
     STDMETHODIMP DevelopInterface(void);
     STDMETHODIMP ThenDevelopImplementation(void);
 
     // IUseAnyTool
     STDMETHODIMP UseCPP(void);
     STDMETHODIMP UseMFC(void);
     STDMETHODIMP UseATL(void);
     STDMETHODIMP UseVB(void);
     STDMETHODIMP UseJava(void);
 };

Figure 8   Interfaces in Visual Basic


 Private Sub ILoveCOM_DevelopInterface()
     MsgBox "I love to develop the interface first."
 End Sub
 Private Sub ILoveCOM_ThenDevelopImplementation()
     MsgBox "then develop the implementation."
 End Sub
 Private Sub IUseAnyTool_UseCPP()
     MsgBox "Nothing escapes the eye of the C++ developer"
 End Sub
 Private Sub IUseAnyTool_UseMFC()
     MsgBox "I hate macros"
 End Sub
 Private Sub IUseAnyTool_UseATL()
     MsgBox "ATL takes care of grunge"
 End Sub
 Private Sub IUseAnyTool_UseVB()
     MsgBox "Push the button and go"
 End Sub
 Private Sub IUseAnyTool_UseJava()
     MsgBox "Yet another way to make COM classes"
 End Sub