home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / include / afxcom_.h < prev    next >
C/C++ Source or Header  |  1998-06-16  |  13KB  |  481 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. /////////////////////////////////////////////////////////////////////////////
  12. // AFXCOM_.H
  13. //
  14. // THIS FILE IS FOR MFC IMPLEMENTATION ONLY.
  15.  
  16. #ifndef __AFXCOM_H__
  17. #define __AFXCOM_H__
  18.  
  19. #ifndef _OBJBASE_H_
  20. #include <objbase.h>
  21. #endif
  22.  
  23. /////////////////////////////////////////////////////////////////////////////
  24.  
  25. #ifdef _AFX_MINREBUILD
  26. #pragma component(minrebuild, off)
  27. #endif
  28. #ifndef _AFX_FULLTYPEINFO
  29. #pragma component(mintypeinfo, on)
  30. #endif
  31.  
  32. /////////////////////////////////////////////////////////////////////////////
  33.  
  34. #ifndef _AFX_NOFORCE_LIBS
  35. #pragma comment(lib, "uuid.lib")
  36. #endif
  37.  
  38. /////////////////////////////////////////////////////////////////////////////
  39.  
  40. #ifdef _AFX_PACKING
  41. #pragma pack(push, _AFX_PACKING)
  42. #endif
  43.  
  44. #ifndef ASSERT
  45. #ifndef _INC_CRTDBG
  46. #include <crtdbg.h>
  47. #endif // _INC_CRTDBG
  48. #define ASSERT(x) _ASSERT(x)
  49. #endif // ASSERT
  50.  
  51. /////////////////////////////////////////////////////////////////////////////
  52.  
  53. template<class _Interface, const IID* _IID>
  54. class _CIP
  55. {
  56. public:
  57.     // Declare interface type so that the type may be available outside
  58.     // the scope of this template.
  59.     typedef _Interface Interface;
  60.  
  61.     // When the compiler supports references in template params,
  62.     // _CLSID will be changed to a reference.  To avoid conversion
  63.     // difficulties this function should be used to obtain the
  64.     // CLSID.
  65.     static const IID& GetIID()
  66.         { ASSERT(_IID != NULL); return *_IID; }
  67.  
  68.     // Construct empty in preperation for assignment.
  69.     _CIP();
  70.  
  71.     // Copy the pointer and AddRef().
  72.     _CIP(const _CIP& cp) : _pInterface(cp._pInterface)
  73.         { _AddRef(); }
  74.  
  75.     // Saves and AddRef()'s the interface
  76.     _CIP(Interface* pInterface) : _pInterface(pInterface)
  77.         { _AddRef(); }
  78.  
  79.     // Copies the pointer.  If bAddRef is TRUE, the interface will
  80.     // be AddRef()ed.
  81.     _CIP(Interface* pInterface, BOOL bAddRef)
  82.         : _pInterface(pInterface)
  83.     {
  84.         if (bAddRef)
  85.         {
  86.             ASSERT(pInterface != NULL);
  87.             _AddRef();
  88.         }
  89.     }
  90.  
  91.     // Calls CoCreateClass with the provided CLSID.
  92.     _CIP(const CLSID& clsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER)
  93.         : _pInterface(NULL)
  94.     {
  95.         CreateObject(clsid, dwClsContext);
  96.     }
  97.  
  98.     // Calls CoCreateClass with the provided CLSID retrieved from
  99.     // the string.
  100.     _CIP(LPOLESTR str, DWORD dwClsContext = CLSCTX_INPROC_SERVER)
  101.         : _pInterface(NULL)
  102.     {
  103.         CreateObject(str, dwClsContext);
  104.     }
  105.  
  106.     // Saves and AddRef()s the interface.
  107.     _CIP& operator=(Interface* pInterface)
  108.     {
  109.         if (_pInterface != pInterface)
  110.         {
  111.             Interface* pOldInterface = _pInterface;
  112.             _pInterface = pInterface;
  113.             _AddRef();
  114.             if (pOldInterface != NULL)
  115.                 pOldInterface->Release();
  116.         }
  117.         return *this;
  118.     }
  119.  
  120.     // Copies and AddRef()'s the interface.
  121.     _CIP& operator=(const _CIP& cp)
  122.         { return operator=(cp._pInterface); }
  123.  
  124.     // Releases any current interface and loads the class with the
  125.     // provided CLSID.
  126.     _CIP& operator=(const CLSID& clsid)
  127.     {
  128.         CreateObject(clsid);
  129.         return *this;
  130.     }
  131.  
  132.     // Calls CoCreateClass with the provided CLSID retrieved from
  133.     // the string.
  134.     _CIP& operator=(LPOLESTR str)
  135.     {
  136.         CreateObject(str);
  137.         return *this;
  138.     }
  139.  
  140.     ~_CIP();
  141.  
  142.     // Saves/sets the interface without AddRef()ing.  This call
  143.     // will release any previously aquired interface.
  144.     void Attach(Interface* pInterface)
  145.     {
  146.         _Release();
  147.         _pInterface = pInterface;
  148.     }
  149.  
  150.     // Saves/sets the interface only AddRef()ing if bAddRef is TRUE.
  151.     // This call will release any previously aquired interface.
  152.     void Attach(Interface* pInterface, BOOL bAddRef)
  153.     {
  154.         _Release();
  155.         _pInterface = pInterface;
  156.         if (bAddRef)
  157.         {
  158.             ASSERT(pInterface != NULL);
  159.             pInterface->AddRef();
  160.         }
  161.     }
  162.  
  163.     // Simply NULL the interface pointer so that it isn't Released()'ed.
  164.     void Detach()
  165.     {
  166.         ASSERT(_pInterface);
  167.         _pInterface = NULL;
  168.     }
  169.  
  170.     // Return the interface.  This value may be NULL
  171.     operator Interface*() const
  172.         { return _pInterface; }
  173.  
  174.     // Queries for the unknown and return it
  175.     operator IUnknown*()
  176.         { return _pInterface; }
  177.  
  178.     // Provides minimal level assertion before use.
  179.     operator Interface&() const
  180.         { ASSERT(_pInterface); return *_pInterface; }
  181.  
  182.     // Allows an instance of this class to act as though it were the
  183.     // actual interface.  Also provides minimal assertion verification.
  184.     Interface& operator*() const
  185.         { ASSERT(_pInterface); return *_pInterface; }
  186.  
  187.     // Returns the address of the interface pointer contained in this
  188.     // class.  This is useful when using the COM/OLE interfaces to create
  189.     // this interface.
  190.     Interface** operator&()
  191.     {
  192.         _Release();
  193.         _pInterface = NULL;
  194.         return &_pInterface;
  195.     }
  196.  
  197.     // Allows this class to be used as the interface itself.
  198.     // Also provides simple assertion verification.
  199.     Interface* operator->() const
  200.         { ASSERT(_pInterface != NULL); return _pInterface; }
  201.  
  202.     // This operator is provided so that simple boolean expressions will
  203.     // work.  For example: "if (p) ...".
  204.     // Returns TRUE if the pointer is not NULL.
  205.     operator BOOL() const
  206.         { return _pInterface != NULL; }
  207.  
  208.     // Returns TRUE if the interface is NULL.
  209.     // This operator will be removed when support for type bool
  210.     // is added to the compiler.
  211.     BOOL operator!()
  212.         { return _pInterface == NULL; }
  213.  
  214.     // Provides assertion verified, Release()ing of this interface.
  215.     void Release()
  216.     {
  217.         ASSERT(_pInterface != NULL);
  218.         _pInterface->Release();
  219.         _pInterface = NULL;
  220.     }
  221.  
  222.     // Provides assertion verified AddRef()ing of this interface.
  223.     void AddRef()
  224.         { ASSERT(_pInterface != NULL); _pInterface->AddRef(); }
  225.  
  226.     // Another way to get the interface pointer without casting.
  227.     Interface* GetInterfacePtr() const
  228.         { return _pInterface; }
  229.  
  230.     // Loads an interface for the provided CLSID.
  231.     // Returns an HRESULT.  Any previous interface is released.
  232.     HRESULT CreateObject(
  233.         const CLSID& clsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER)
  234.     {
  235.         _Release();
  236.         HRESULT hr = CoCreateInstance(clsid, NULL, dwClsContext,
  237.             GetIID(), reinterpret_cast<void**>(&_pInterface));
  238.         ASSERT(SUCCEEDED(hr));
  239.         return hr;
  240.     }
  241.  
  242.     // Creates the class specified by clsidString.  clsidString may
  243.     // contain a class id, or a prog id string.
  244.     HRESULT CreateObject(
  245.         LPOLESTR clsidString, DWORD dwClsContext=CLSCTX_INPROC_SERVER)
  246.     {
  247.         ASSERT(clsidString != NULL);
  248.         CLSID clsid;
  249.         HRESULT hr;
  250.         if (clsidString[0] == '{')
  251.             hr = CLSIDFromString(clsidString, &clsid);
  252.         else
  253.             hr = CLSIDFromProgID(clsidString, &clsid);
  254.         ASSERT(SUCCEEDED(hr));
  255.         if (FAILED(hr))
  256.             return hr;
  257.         return CreateObject(clsid, dwClsContext);
  258.     }
  259.  
  260.     // Performs a QI on pUnknown for the interface type returned
  261.     // for this class.  The interface is stored.  If pUnknown is
  262.     // NULL, or the QI fails, E_NOINTERFACE is returned and
  263.     // _pInterface is set to NULL.
  264.     HRESULT QueryInterface(IUnknown* pUnknown)
  265.     {
  266.         if (pUnknown == NULL) // Can't QI NULL
  267.         {
  268.             operator=(static_cast<Interface*>(NULL));
  269.             return E_NOINTERFACE;
  270.         }
  271.  
  272.         // Query for this interface
  273.         Interface* pInterface;
  274.         HRESULT hr = pUnknown->QueryInterface(GetIID(),
  275.             reinterpret_cast<void**>(&pInterface));
  276.         if (FAILED(hr))
  277.         {
  278.             // If failed intialize interface to NULL and return HRESULT.
  279.             Attach(NULL);
  280.             return hr;
  281.         }
  282.  
  283.         // Save the interface without AddRef()ing.
  284.         Attach(pInterface);
  285.         return hr;
  286.     }
  287.  
  288. private:
  289.     // Releases only if the interface is not null.
  290.     // The interface is not set to NULL.
  291.     void _Release()
  292.     {
  293.         if (_pInterface != NULL)
  294.             _pInterface->Release();
  295.     }
  296.  
  297.     // AddRefs only if the interface is not NULL
  298.     void _AddRef()
  299.     {
  300.         if (_pInterface != NULL)
  301.             _pInterface->AddRef();
  302.     }
  303.  
  304.     // The Interface.
  305.     Interface* _pInterface;
  306. }; // class _CIP
  307.  
  308. template<class _Interface, const IID* _IID>
  309. _CIP<_Interface, _IID>::_CIP<_Interface, _IID>()
  310.     : _pInterface(NULL)
  311. {
  312. }
  313.  
  314. template<class _Interface, const IID* _IID>
  315. _CIP<_Interface, _IID>::~_CIP<_Interface, _IID>()
  316. {
  317.     // If we still have an interface then Release() it.  The interface
  318.     // may be NULL if Detach() has previosly been called, or if it was
  319.     // never set.
  320.  
  321.     _Release();
  322. }
  323.  
  324. template<class _Interface, const IID* _IID>
  325. class CIP : public _CIP<_Interface, _IID>
  326. {
  327. public:
  328.     // Simplified name for base class and provide derived classes
  329.     // access to base type
  330.     typedef _CIP<_Interface, _IID> BC;
  331.  
  332.     // Provideds derived classes access to the interface type.
  333.     typedef _Interface Interface;
  334.  
  335.     // Construct empty in preperation for assignment.
  336.     CIP() { }
  337.     ~CIP();
  338.  
  339.     // Copy the pointer and AddRef().
  340.     CIP(const CIP& cp) : _CIP<_Interface, _IID>(cp) { }
  341.  
  342.     // Saves and AddRef()s the interface.
  343.     CIP(Interface* pInterface) : _CIP<_Interface, _IID>(pInterface) { }
  344.  
  345.     // Saves the interface and AddRef()s only if bAddRef is TRUE.
  346.     CIP(Interface* pInterface, BOOL bAddRef)
  347.         : _CIP<_Interface, _IID>(pInterface, bAddRef) { }
  348.  
  349.     // Queries for this interface.
  350.     CIP(IUnknown* pUnknown)
  351.     {
  352.         if (pUnknown == NULL)
  353.             return;
  354.         Interface* pInterface;
  355.         HRESULT hr = pUnknown->QueryInterface(GetIID(),
  356.             reinterpret_cast<void**>(&pInterface));
  357.         ASSERT(SUCCEEDED(hr));
  358.         Attach(pInterface);
  359.     }
  360.  
  361.     // Creates the interface from the CLSID.
  362.     CIP(const CLSID& clsid) : _CIP<_Interface, _IID>(clsid) { }
  363.  
  364.     // Creates the interface from the CLSID.
  365.     CIP(LPOLESTR str) : _CIP<_Interface, _IID>(str) { }
  366.  
  367.     // Copies and AddRef()'s the interface.
  368.     CIP& operator=(const CIP& cp)
  369.         { _CIP<_Interface, _IID>::operator=(cp); return *this; }
  370.  
  371.     // Saves and AddRef()s the interface.
  372.     CIP& operator=(Interface* pInterface)
  373.         { _CIP<_Interface, _IID>::operator=(pInterface); return *this; }
  374.  
  375.     CIP& operator=(IUnknown* pUnknown)
  376.     {
  377.         HRESULT hr = QueryInterface(pUnknown);
  378.         ASSERT(SUCCEEDED(hr));
  379.         return *this;
  380.     }
  381.  
  382.     // Releases any current interface and loads the class with the
  383.     // provided CLSID.
  384.     CIP& operator=(const CLSID& clsid)
  385.         { _CIP<_Interface, _IID>::operator=(clsid); return *this; }
  386.  
  387.     // Releases any current interface and loads the class with the
  388.     // provided CLSID.
  389.     CIP& operator=(LPOLESTR str)
  390.         { _CIP<_Interface, _IID>::operator=(str); return *this; }
  391. }; // class CIP
  392.  
  393. template<class _Interface, const IID* _IID>
  394. CIP<_Interface, _IID>::~CIP()
  395. {
  396. }
  397.  
  398. #if _MSC_VER > 1020
  399. template<>
  400. #endif
  401. class CIP<IUnknown, &IID_IUnknown> : public _CIP<IUnknown, &IID_IUnknown>
  402. {
  403. public:
  404.     // Simplified name for base class and provide derived classes
  405.     // access to base type
  406.     typedef _CIP<IUnknown, &IID_IUnknown> BC;
  407.  
  408.     // Provideds derived classes access to the interface type.
  409.     typedef IUnknown Interface;
  410.  
  411.     // Construct empty in preperation for assignment.
  412.     CIP() { }
  413.  
  414.     // Copy the pointer and AddRef().
  415.     CIP(const CIP& cp) : _CIP<IUnknown, &IID_IUnknown>(cp) { }
  416.  
  417.     // Saves and AddRef()s the interface.
  418.     CIP(Interface* pInterface)
  419.         : _CIP<IUnknown, &IID_IUnknown>(pInterface) { }
  420.  
  421.     // Saves and then AddRef()s only if bAddRef is TRUE.
  422.     CIP(Interface* pInterface, BOOL bAddRef)
  423.         : _CIP<IUnknown, &IID_IUnknown>(pInterface, bAddRef) { }
  424.  
  425.     // Creates the interface from the CLSID.
  426.     CIP(const CLSID& clsid) : _CIP<IUnknown, &IID_IUnknown>(clsid) { }
  427.  
  428.     // Creates the interface from the CLSID.
  429.     CIP(LPOLESTR str) : _CIP<IUnknown, &IID_IUnknown>(str) { }
  430.  
  431.     // Copies and AddRef()'s the interface.
  432.     CIP& operator=(const CIP& cp)
  433.         { _CIP<IUnknown, &IID_IUnknown>::operator=(cp); return *this; }
  434.  
  435.     // Saves and AddRef()s the interface.  The previously saved
  436.     // interface is released.
  437.     CIP& operator=(Interface* pInterface)
  438.         { _CIP<IUnknown, &IID_IUnknown>::operator=(pInterface); return *this; }
  439.  
  440.     // Releases any current interface and loads the class with the
  441.     // provided CLSID.
  442.     CIP& operator=(const CLSID& clsid)
  443.         { _CIP<IUnknown, &IID_IUnknown>::operator=(clsid); return *this; }
  444.  
  445.     // Releases any current interface and loads the class with the
  446.     // provided CLSID.
  447.     CIP& operator=(LPOLESTR str)
  448.         { _CIP<IUnknown, &IID_IUnknown>::operator=(str); return *this; }
  449.  
  450.     // Queries for the unknown and return it
  451.     operator IUnknown*()
  452.         { return GetInterfacePtr(); }
  453.  
  454.     // Verifies that pUnknown is not null and performs assignment.
  455.     HRESULT QueryInterface(IUnknown* pUnknown)
  456.     {
  457.         _CIP<IUnknown, &IID_IUnknown>::operator=(pUnknown);
  458.         return pUnknown != NULL ? S_OK : E_NOINTERFACE;
  459.     }
  460. };  // CIP<IUnknown, &IID_IUnknown>
  461.  
  462. #define IPTR(x) CIP<x, &IID_##x>
  463. #define DEFINE_IPTR(x) typedef IPTR(x) x##Ptr;
  464.  
  465. /////////////////////////////////////////////////////////////////////////////
  466.  
  467. #ifdef _AFX_PACKING
  468. #pragma pack(pop)
  469. #endif
  470.  
  471. #ifdef _AFX_MINREBUILD
  472. #pragma component(minrebuild, on)
  473. #endif
  474. #ifndef _AFX_FULLTYPEINFO
  475. #pragma component(mintypeinfo, off)
  476. #endif
  477.  
  478. #endif // __AFXCOM_H__
  479.  
  480. /////////////////////////////////////////////////////////////////////////////
  481.