home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / comip.h < prev    next >
C/C++ Source or Header  |  2000-02-01  |  25KB  |  980 lines

  1. /***
  2. * comip.h - Native C++ compiler COM support - COM interface pointers header
  3. *
  4. *    Copyright (C) 1996-1997 Microsoft Corporation
  5. *    All rights reserved.
  6. *
  7. ****/
  8.  
  9. #if !defined(_INC_COMIP)
  10. #pragma option push -b -a8 -pc -A- -w-inl /*P_O_Push __BORLANDC__: This file was forgotten in the PSDK so it was taken from the VC++ 6.0 */
  11. #define _INC_COMIP
  12.  
  13.  
  14. #if _MSC_VER > 1000
  15. #pragma once
  16. #endif
  17.  
  18. #include <ole2.h>
  19. #include <malloc.h>
  20.  
  21. #include <comutil.h>
  22.  
  23. #pragma warning(push)
  24. #pragma warning(disable: 4290)
  25.  
  26. class _com_error;
  27. void __stdcall _com_issue_error(HRESULT)
  28. #ifdef __BORLANDC__
  29. throw(_com_error)
  30. #endif
  31. ;
  32.  
  33.  
  34. struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
  35.  
  36. // Provide Interface to IID association
  37. //
  38. template<typename _Interface , const IID* _IID /*= &__uuidof(_Interface)*/ > class _com_IIID {
  39. public:
  40.     typedef _Interface Interface;
  41.  
  42.     static _Interface* GetInterfacePtr() throw()
  43.     {
  44.         return NULL;
  45.     }
  46.  
  47.     static _Interface& GetInterface() throw()
  48.     {
  49.         return *GetInterfacePtr();
  50.     }
  51.  
  52.     static const IID& GetIID() throw()
  53.     {
  54. #ifdef __BORLANDC__
  55.         return __uuidof( _Interface );
  56. #else
  57.         return *_IID;
  58. #endif
  59.     }
  60. };
  61.  
  62. #ifdef __BORLANDC__
  63.   #define _COM_SMARTPTR_SPECIALIZE(Interface) \
  64.   template<> template<>                                                                                                       \
  65.   Interface ## Ptr ::_com_ptr_t( Interface ## Ptr * const & p) throw(_com_error)                                              \
  66.   {                                                                                          \
  67.     if (p != NULL) {                                                                              \
  68.         _com_issue_error(E_POINTER);                                                                      \
  69.     }                                                                                      \
  70.     else {                                                                                      \
  71.         m_pInterface = p->m_pInterface;                                                                      \
  72.         AddRef();                                                                              \
  73.     }                                                                                      \
  74.   }                                                                                                                           \
  75.   template<> template<>                                                                                                       \
  76.   Interface ## Ptr ::_com_ptr_t(const _variant_t& varSrc) throw(_com_error)                                                   \
  77.         : m_pInterface(NULL)                                                  \
  78.   {                                                                      \
  79.       HRESULT hr = QueryStdInterfaces(varSrc);                                              \
  80.       if (FAILED(hr) && (hr != E_NOINTERFACE)) {                                              \
  81.           _com_issue_error(hr);                                                      \
  82.       }                                                                  \
  83.   };                                                                      \
  84.   template<> template<>                                                                                                       \
  85.   Interface ## Ptr & Interface ## Ptr ::operator=(const _variant_t& varSrc) throw(_com_error)                          \
  86.   {                                                                  \
  87.       HRESULT hr = QueryStdInterfaces(varSrc);                                          \
  88.                                                                     \
  89.       if (FAILED(hr) && (hr != E_NOINTERFACE)) {                                          \
  90.           _com_issue_error(hr);                                                  \
  91.       }                                                              \
  92.                                                                     \
  93.       return *this;                                                          \
  94.   }                                                                  \
  95.   template<> template<>                                                          \
  96.   bool Interface ## Ptr ::operator==( Interface* p) throw(_com_error)                                  \
  97.   {                                                                  \
  98.       return (m_pInterface == p) ? true : _CompareUnknown(p) == 0;                                  \
  99.   }                                                                  \
  100.   template<> template<>                                                          \
  101.   bool Interface ## Ptr::operator==(int null) throw(_com_error)                                      \
  102.   {                                                                  \
  103.       if (null != 0) {                                                      \
  104.           _com_issue_error(E_POINTER);                                              \
  105.       }                                                              \
  106.                                                                     \
  107.       return m_pInterface == NULL;                                                  \
  108.   }                                                                  \
  109.   template<> template<>                                                          \
  110.   bool Interface ## Ptr::operator!=(Interface* p) throw(_com_error)                                  \
  111.   {                                                                  \
  112.       return !(operator==(p));                                                  \
  113.   }                                                                  \
  114.   template<> template<>                                                          \
  115.   bool Interface ## Ptr::operator!=(_com_ptr_t& p) throw(_com_error)                                  \
  116.   {                                                                  \
  117.       return !(operator==(p));                                                  \
  118.   }                                                                  \
  119.   template<> template<>                                                          \
  120.   bool Interface ## Ptr::operator!=(int null) throw(_com_error)                                      \
  121.   {                                                                  \
  122.       return !(operator==(null));                                                  \
  123.   }                                                                  \
  124.  
  125. #endif                                                                  
  126.  
  127. template<typename _IIID> class _com_ptr_t {
  128. public:
  129.     // Declare interface type so that the type may be available outside
  130.     // the scope of this template.
  131.     //
  132.     typedef _IIID ThisIIID;
  133.     typedef typename _IIID::Interface Interface;
  134.  
  135.     // When the compiler supports references in template parameters,
  136.     // _CLSID will be changed to a reference.  To avoid conversion
  137.     // difficulties this function should be used to obtain the
  138.     // CLSID.
  139.     //
  140.     static const IID& GetIID() throw()
  141.     { 
  142.         return ThisIIID::GetIID(); 
  143.     }
  144.  
  145.     // Constructs a smart-pointer from any interface pointer.
  146.     //
  147.     template<typename _InterfacePtr> _com_ptr_t(const _InterfacePtr& p) throw(_com_error)
  148.         : m_pInterface(NULL)
  149.     {
  150.         if (p) {
  151.             HRESULT hr = _QueryInterface(p);
  152.  
  153.             if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  154.                 _com_issue_error(hr);
  155.             }
  156.         }
  157.     }
  158.  
  159. #ifndef __BORLANDC__
  160.     // Disable conversion using _com_ptr_t* specialization of
  161.     // template<typename _InterfacePtr> _com_ptr_t(const _InterfacePtr& p)
  162.     template<> explicit _com_ptr_t(_com_ptr_t* const & p) throw(_com_error)
  163.     {
  164.         if (p != NULL) {
  165.             _com_issue_error(E_POINTER);
  166.         }
  167.         else {
  168.             m_pInterface = p->m_pInterface;
  169.             AddRef();
  170.         }
  171.     }
  172. #endif
  173.  
  174.     // Default constructor.
  175.     //
  176.     _com_ptr_t() throw()
  177.         : m_pInterface(NULL)
  178.     {
  179.     }
  180.  
  181.     // This constructor is provided to allow NULL assignment. It will issue
  182.     // an error if any value other than null is assigned to the object.
  183.     //
  184.     _com_ptr_t(int null) throw(_com_error)
  185.         : m_pInterface(NULL)
  186.     {
  187.         if (null != 0) {
  188.             _com_issue_error(E_POINTER);
  189.         }
  190.     }
  191.  
  192. #ifndef __BORLANDC__
  193.     // Copy the pointer and AddRef().
  194.     //
  195.     template<> _com_ptr_t(const _com_ptr_t& cp) throw()
  196.         : m_pInterface(cp.m_pInterface)
  197. #else
  198.     // template specialization conflicts (throw specification)
  199.     // with builtin copy constructor
  200.     explicit _com_ptr_t(const _com_ptr_t & cp) throw()
  201.       : m_pInterface(cp.m_pInterface)
  202. #endif
  203.     { 
  204.         _AddRef(); 
  205.     }
  206.  
  207.     // Saves the interface.
  208.     //
  209.     _com_ptr_t(Interface* pInterface) throw()
  210.         : m_pInterface(pInterface)
  211.     { 
  212.         _AddRef(); 
  213.     }
  214.  
  215.     // Copies the pointer. If fAddRef is TRUE, the interface will
  216.     // be AddRef()ed.
  217.     //
  218.     _com_ptr_t(Interface* pInterface, bool fAddRef) throw()
  219.         : m_pInterface(pInterface)
  220.     {
  221.         if (fAddRef) {
  222.             _AddRef();
  223.         }
  224.     }
  225.  
  226. #ifndef __BORLANDC__
  227.     // Construct a pointer for a _variant_t object.
  228.     //
  229.     template<> _com_ptr_t(const _variant_t& varSrc) throw(_com_error)
  230.         : m_pInterface(NULL)
  231.     {
  232.         HRESULT hr = QueryStdInterfaces(varSrc);
  233.  
  234.         if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  235.             _com_issue_error(hr);
  236.         }
  237.     }
  238. #endif
  239.  
  240.     // Calls CoCreateClass with the provided CLSID.
  241.     //
  242.     explicit _com_ptr_t(const CLSID& clsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw(_com_error)
  243.         : m_pInterface(NULL)
  244.     {
  245.         HRESULT hr = CreateInstance(clsid, pOuter, dwClsContext);
  246.  
  247.         if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  248.             _com_issue_error(hr);
  249.         }
  250.     }
  251.  
  252.     // Calls CoCreateClass with the provided CLSID retrieved from
  253.     // the string.
  254.     //
  255.     explicit _com_ptr_t(LPOLESTR str, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw(_com_error)
  256.         : m_pInterface(NULL)
  257.     {
  258.         HRESULT hr = CreateInstance(str, pOuter, dwClsContext);
  259.  
  260.         if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  261.             _com_issue_error(hr);
  262.         }
  263.     }
  264.  
  265.     // Calls CoCreateClass with the provided SBCS CLSID retrieved from
  266.     // the string.
  267.     //
  268.     explicit _com_ptr_t(LPCSTR str, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw(_com_error)
  269.         : m_pInterface(NULL)
  270.     {
  271.         HRESULT hr = CreateInstance(str, pOuter, dwClsContext);
  272.  
  273.         if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  274.             _com_issue_error(hr);
  275.         }
  276.     }
  277.  
  278.     // Queries for interface.
  279.     //
  280.     template<typename _InterfacePtr> _com_ptr_t& operator=(const _InterfacePtr& p) throw(_com_error)
  281.     {
  282.         HRESULT hr = _QueryInterface(p);
  283.  
  284.         if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  285.             _com_issue_error(hr);
  286.         }
  287.  
  288.         return *this;
  289.     }
  290.  
  291.     // Saves the interface.
  292.     //
  293.     _com_ptr_t& operator=(Interface* pInterface) throw()
  294.     {
  295.         if (m_pInterface != pInterface) {
  296.             Interface* pOldInterface = m_pInterface;
  297.  
  298.             m_pInterface = pInterface;
  299.  
  300.             _AddRef();
  301.  
  302.             if (pOldInterface != NULL) {
  303.                 pOldInterface->Release();
  304.             }
  305.         }
  306.  
  307.         return *this;
  308.     }
  309.  
  310. #ifndef __BORLANDC__
  311.     // Copies and AddRef()'s the interface.
  312.     //
  313.     template<> _com_ptr_t& operator=(const _com_ptr_t& cp) throw()
  314. #else
  315.     _com_ptr_t & operator=( const _com_ptr_t & cp ) throw()
  316. #endif
  317.     { 
  318.         return operator=(cp.m_pInterface); 
  319.     }
  320.  
  321.     // This operator is provided to permit the assignment of NULL to the class.
  322.     // It will issue an error if any value other than NULL is assigned to it.
  323.     //
  324.     _com_ptr_t& operator=(int null) throw(_com_error)
  325.     {
  326.         if (null != 0) {
  327.             _com_issue_error(E_POINTER);
  328.         }
  329.  
  330.         return operator=(reinterpret_cast<Interface*>(NULL));
  331.     }
  332.  
  333. #ifndef __BORLANDC__
  334.     // Construct a pointer for a _variant_t object.
  335.     //
  336.     template<> _com_ptr_t& operator=(const _variant_t& varSrc) throw(_com_error)
  337.     {
  338.         HRESULT hr = QueryStdInterfaces(varSrc);
  339.  
  340.         if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  341.             _com_issue_error(hr);
  342.         }
  343.  
  344.         return *this;
  345.     }
  346. #endif
  347.  
  348.     // If we still have an interface then Release() it. The interface
  349.     // may be NULL if Detach() has previously been called, or if it was
  350.     // never set.
  351.     //
  352.     ~_com_ptr_t() throw()
  353.     { 
  354.         _Release(); 
  355.     }
  356.  
  357.     // Saves/sets the interface without AddRef()ing. This call
  358.     // will release any previously acquired interface.
  359.     //
  360.     void Attach(Interface* pInterface) throw()
  361.     {
  362.         _Release();
  363.         m_pInterface = pInterface;
  364.     }
  365.  
  366.     // Saves/sets the interface only AddRef()ing if fAddRef is TRUE.
  367.     // This call will release any previously acquired interface.
  368.     //
  369.     void Attach(Interface* pInterface, bool fAddRef) throw()
  370.     {
  371.         _Release();
  372.         m_pInterface = pInterface;
  373.  
  374.         if (fAddRef) {
  375.             if (pInterface != NULL) {
  376.                 pInterface->AddRef();
  377.             }
  378.         }
  379.     }
  380.  
  381.     // Simply NULL the interface pointer so that it isn't Released()'ed.
  382.     //
  383.     Interface* Detach() throw()
  384.     {
  385.         Interface* const old=m_pInterface;
  386.         m_pInterface = NULL;
  387.         return old;
  388.     }
  389.  
  390.     // Return the interface. This value may be NULL.
  391.     //
  392.     operator Interface*() const throw()
  393.     { 
  394.         return m_pInterface; 
  395.     }
  396.  
  397.     // Queries for the unknown and return it
  398.     // Provides minimal level error checking before use.
  399.     //
  400.     operator Interface&() const throw(_com_error)
  401.     { 
  402.         if (m_pInterface == NULL) {
  403.             _com_issue_error(E_POINTER);
  404.         }
  405.  
  406.         return *m_pInterface; 
  407.     }
  408.  
  409.     // Allows an instance of this class to act as though it were the
  410.     // actual interface. Also provides minimal error checking.
  411.     //
  412.     Interface& operator*() const throw(_com_error)
  413.     { 
  414.         if (m_pInterface == NULL) {
  415.             _com_issue_error(E_POINTER);
  416.         }
  417.  
  418.         return *m_pInterface; 
  419.     }
  420.  
  421.     // Returns the address of the interface pointer contained in this
  422.     // class. This is useful when using the COM/OLE interfaces to create
  423.     // this interface.
  424.     //
  425.     Interface** operator&() throw()
  426.     {
  427.         _Release();
  428.         m_pInterface = NULL;
  429.         return &m_pInterface;
  430.     }
  431.  
  432.     // Allows this class to be used as the interface itself.
  433.     // Also provides simple error checking.
  434.     //
  435.     Interface* operator->() const throw(_com_error)
  436.     { 
  437.         if (m_pInterface == NULL) {
  438.             _com_issue_error(E_POINTER);
  439.         }
  440.  
  441.         return m_pInterface; 
  442.     }
  443.  
  444.     // This operator is provided so that simple boolean expressions will
  445.     // work.  For example: "if (p) ...".
  446.     // Returns TRUE if the pointer is not NULL.
  447.     //
  448.     operator bool() const throw()
  449.     { 
  450.         return m_pInterface != NULL; 
  451.     }
  452.  
  453.     // Compare two pointers
  454.     //
  455.     template<typename _InterfacePtr> bool operator==(_InterfacePtr p) throw(_com_error)
  456.     {
  457.         return _CompareUnknown(p) == 0;
  458.     }
  459.  
  460. #ifndef __BORLANDC__
  461.     // Compare with other interface
  462.     //
  463.     template<> bool operator==(Interface* p) throw(_com_error)
  464.     {
  465.         return (m_pInterface == p) ? true : _CompareUnknown(p) == 0;
  466.     }
  467. #endif
  468.  
  469. #ifndef __BORLANDC__
  470.     // Compares 2 _com_ptr_t's
  471.     //
  472.     template<> bool operator==(_com_ptr_t& p) throw()
  473. #else
  474.     bool operator==( const _com_ptr_t & p) throw()
  475. #endif
  476.     {
  477.         return operator==(p.m_pInterface);
  478.     }
  479.  
  480. #ifndef __BORLANDC__
  481.     // For comparison to NULL
  482.     //
  483.     template<> bool operator==(int null) throw(_com_error)
  484.     {
  485.         if (null != 0) {
  486.             _com_issue_error(E_POINTER);
  487.         }
  488.  
  489.         return m_pInterface == NULL;
  490.     }
  491. #endif
  492.  
  493.     // Compare two pointers
  494.     //
  495.     template<typename _InterfacePtr> bool operator!=(_InterfacePtr p) throw(_com_error)
  496.     {
  497.         return !(operator==(p));
  498.     }
  499.  
  500. #ifndef __BORLANDC__
  501.     // Compare with other interface
  502.     //
  503.     template<> bool operator!=(Interface* p) throw(_com_error)
  504.     {
  505.         return !(operator==(p));
  506.     }
  507. #endif
  508.  
  509. #ifndef __BORLANDC__
  510.     // Compares 2 _com_ptr_t's
  511.     //
  512.     template<> bool operator!=(_com_ptr_t& p) throw(_com_error)
  513.     {
  514.         return !(operator==(p));
  515.     }
  516. #endif
  517.  
  518. #ifndef __BORLANDC__
  519.     // For comparison to NULL
  520.     //
  521.     template<> bool operator!=(int null) throw(_com_error)
  522.     {
  523.         return !(operator==(null));
  524.     }
  525. #endif
  526.  
  527.     // Compare two pointers
  528.     //
  529.     template<typename _InterfacePtr> bool operator<(_InterfacePtr p) throw(_com_error)
  530.     {
  531.         return _CompareUnknown(p) < 0;
  532.     }
  533.  
  534.     // Compare two pointers
  535.     //
  536.     template<typename _InterfacePtr> bool operator>(_InterfacePtr p) throw(_com_error)
  537.     {
  538.         return _CompareUnknown(p) > 0;
  539.     }
  540.  
  541.     // Compare two pointers
  542.     //
  543.     template<typename _InterfacePtr> bool operator<=(_InterfacePtr p) throw(_com_error)
  544.     {
  545.         return _CompareUnknown(p) <= 0;
  546.     }
  547.  
  548.     // Compare two pointers
  549.     //
  550.     template<typename _InterfacePtr> bool operator>=(_InterfacePtr p) throw(_com_error)
  551.     {
  552.         return _CompareUnknown(p) >= 0;
  553.     }
  554.  
  555.     // Provides error-checking Release()ing of this interface.
  556.     //
  557.     void Release() throw(_com_error)
  558.     {
  559.         if (m_pInterface == NULL) {
  560.             _com_issue_error(E_POINTER);
  561.         }
  562.  
  563.         m_pInterface->Release();
  564.         m_pInterface = NULL;
  565.     }
  566.  
  567.     // Provides error-checking AddRef()ing of this interface.
  568.     //
  569.     void AddRef() throw(_com_error)
  570.     { 
  571.         if (m_pInterface == NULL) {
  572.             _com_issue_error(E_POINTER);
  573.         }
  574.  
  575.         m_pInterface->AddRef(); 
  576.     }
  577.  
  578.     // Another way to get the interface pointer without casting.
  579.     //
  580.     Interface* GetInterfacePtr() const throw()
  581.     { 
  582.         return m_pInterface; 
  583.     }
  584.  
  585.     // Loads an interface for the provided CLSID.
  586.     // Returns an HRESULT.  Any previous interface is released.
  587.     //
  588.     HRESULT CreateInstance(const CLSID& rclsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
  589.     {
  590.         HRESULT hr;
  591.  
  592.         _Release();
  593.  
  594.         if (dwClsContext & (CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)) {
  595.             IUnknown* pIUnknown;
  596.  
  597.             hr = CoCreateInstance(rclsid, pOuter, dwClsContext, __uuidof(IUnknown), reinterpret_cast<void**>(&pIUnknown));
  598.  
  599.             if (FAILED(hr)) {
  600.                 return hr;
  601.             }
  602.  
  603.             hr = OleRun(pIUnknown);
  604.  
  605.             if (SUCCEEDED(hr)) {
  606.                 hr = pIUnknown->QueryInterface(GetIID(), reinterpret_cast<void**>(&m_pInterface));
  607.             }
  608.  
  609.             pIUnknown->Release();
  610.         }
  611.         else {
  612.             hr = CoCreateInstance(rclsid, pOuter, dwClsContext, GetIID(), reinterpret_cast<void**>(&m_pInterface));
  613.         }
  614.  
  615.         return hr;
  616.     }
  617.  
  618.     // Creates the class specified by clsidString.  clsidString may
  619.     // contain a class id, or a prog id string.
  620.     //
  621.     HRESULT CreateInstance(LPOLESTR clsidString, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
  622.     {
  623.         if (clsidString == NULL) {
  624.             return E_INVALIDARG;
  625.         }
  626.  
  627.         CLSID clsid;
  628.         HRESULT hr;
  629.  
  630.         if (clsidString[0] == '{') {
  631.             hr = CLSIDFromString(clsidString, &clsid);
  632.         }
  633.         else {
  634.             hr = CLSIDFromProgID(clsidString, &clsid);
  635.         }
  636.  
  637.         if (FAILED(hr)) {
  638.             return hr;
  639.         }
  640.  
  641.         return CreateInstance(clsid, pOuter, dwClsContext);
  642.     }
  643.  
  644.     // Creates the class specified by SBCS clsidString.  clsidString may
  645.     // contain a class id, or a prog id string.
  646.     //
  647.     HRESULT CreateInstance(LPCSTR clsidStringA, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
  648.     {
  649.         if (clsidStringA == NULL) {
  650.             return E_INVALIDARG;
  651.         }
  652.  
  653.         int size = lstrlenA(clsidStringA) + 1;
  654.         LPOLESTR clsidStringW = static_cast<LPOLESTR>(_alloca(size * 2));
  655.  
  656.         clsidStringW[0] = '\0';
  657.  
  658.         if (MultiByteToWideChar(CP_ACP, 0, clsidStringA, -1, clsidStringW, size) == 0) {
  659.             return HRESULT_FROM_WIN32(GetLastError());
  660.         }
  661.  
  662.         return CreateInstance(clsidStringW, pOuter, dwClsContext);
  663.     }
  664.  
  665.     // Attach to the active object specified by rclsid.
  666.     // Any previous interface is released.
  667.     //
  668.     HRESULT GetActiveObject(const CLSID& rclsid) throw()
  669.     {
  670.         _Release();
  671.  
  672.         IUnknown* pIUnknown;
  673.  
  674.         HRESULT hr = ::GetActiveObject(rclsid, NULL, &pIUnknown);
  675.  
  676.         if (FAILED(hr)) {
  677.             return hr;
  678.         }
  679.  
  680.         hr = pIUnknown->QueryInterface(GetIID(), reinterpret_cast<void**>(&m_pInterface));
  681.  
  682.         if (FAILED(hr)) {
  683.             return hr;
  684.         }
  685.  
  686.         pIUnknown->Release();
  687.  
  688.         return hr;
  689.     }
  690.  
  691.     // Attach to the active object specified by clsidString.
  692.     // First convert the LPOLESTR to a CLSID.
  693.     //
  694.     HRESULT GetActiveObject(LPOLESTR clsidString) throw()
  695.     {
  696.         if (clsidString == NULL) {
  697.             return E_INVALIDARG;
  698.         }
  699.  
  700.         CLSID clsid;
  701.         HRESULT hr;
  702.  
  703.         if (clsidString[0] == '{') {
  704.             hr = CLSIDFromString(clsidString, &clsid);
  705.         }
  706.         else {
  707.             hr = CLSIDFromProgID(clsidString, &clsid);
  708.         }
  709.  
  710.         if (FAILED(hr)) {
  711.             return hr;
  712.         }
  713.  
  714.         return GetActiveObject(clsid);
  715.     }
  716.  
  717.     // Attach to the active object specified by clsidStringA.
  718.     // First convert the LPCSTR to a LPOLESTR.
  719.     //
  720.     HRESULT GetActiveObject(LPCSTR clsidStringA) throw()
  721.     {
  722.         if (clsidStringA == NULL) {
  723.             return E_INVALIDARG;
  724.         }
  725.  
  726.         int size = lstrlenA(clsidStringA) + 1;
  727.         LPOLESTR clsidStringW = static_cast<LPOLESTR>(_alloca(size * 2));
  728.  
  729.         clsidStringW[0] = '\0';
  730.  
  731.         if (MultiByteToWideChar(CP_ACP, 0, clsidStringA, -1, clsidStringW, size) == 0) {
  732.             return HRESULT_FROM_WIN32(GetLastError());
  733.         }
  734.  
  735.         return GetActiveObject(clsidStringW);
  736.     }
  737.     // Performs the QI for the specified IID and returns it in p.
  738.     // As with all QIs, the interface will be AddRef'd.
  739.     //
  740.     template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType*& p) throw ()
  741.     {
  742.         if (m_pInterface != NULL) {
  743.             return m_pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p));
  744.         }
  745.  
  746.         return E_POINTER;
  747.     }
  748.     // Performs the QI for the specified IID and returns it in p.
  749.     // As with all QIs, the interface will be AddRef'd.
  750.     //
  751.     template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType** p) throw()
  752.     {
  753.         return QueryInterface(iid, *p);
  754.     }
  755.  
  756. private:
  757.     // The Interface.
  758.     //
  759.     Interface* m_pInterface;
  760.  
  761.     // Releases only if the interface is not null.
  762.     // The interface is not set to NULL.
  763.     //
  764.     void _Release() throw()
  765.     {
  766.         if (m_pInterface != NULL) {
  767.             m_pInterface->Release();
  768.         }
  769.     }
  770.  
  771.     // AddRefs only if the interface is not NULL
  772.     //
  773.     void _AddRef() throw()
  774.     {
  775.         if (m_pInterface != NULL) {
  776.             m_pInterface->AddRef();
  777.         }
  778.     }
  779.     // Performs a QI on pUnknown for the interface type returned
  780.     // for this class.  The interface is stored.  If pUnknown is
  781.     // NULL, or the QI fails, E_NOINTERFACE is returned and
  782.     // _pInterface is set to NULL.
  783.     //
  784.     template<typename _InterfacePtr> HRESULT _QueryInterface(const _InterfacePtr& p) throw()
  785.     {
  786.         HRESULT hr;
  787.  
  788.         // Can't QI NULL
  789.         //
  790.         if (p) {
  791.             // Query for this interface
  792.             //
  793.             Interface* pInterface;
  794.             hr = p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface));
  795.  
  796.             if (FAILED(hr)) {
  797.                 // If failed initialize interface to NULL and return HRESULT.
  798.                 //
  799.                 Attach(NULL);
  800.                 return hr;
  801.             }
  802.  
  803.             // Save the interface without AddRef()ing.
  804.             //
  805.             Attach(pInterface);
  806.         }
  807.         else {
  808.             operator=(static_cast<Interface*>(NULL));
  809.             hr = E_NOINTERFACE;
  810.         }
  811.  
  812.         return hr;
  813.     }
  814.     // Compares the provided pointer with this by obtaining IUnknown interfaces
  815.     // for each pointer and then returning the difference.
  816.     //
  817.     template<typename _InterfacePtr> int _CompareUnknown(_InterfacePtr p) throw(_com_error)
  818.     {
  819.         IUnknown* pu1, *pu2;
  820.  
  821.         if (m_pInterface != NULL) {
  822.             HRESULT hr = m_pInterface->QueryInterface(__uuidof(IUnknown), reinterpret_cast<void**>(&pu1));
  823.  
  824.             if (FAILED(hr)) {
  825.                 _com_issue_error(hr);
  826.             }
  827.  
  828.             pu1->Release();
  829.         }
  830.         else {
  831.             pu1 = NULL;
  832.         }
  833.  
  834.         if (p) {
  835.             HRESULT hr = p->QueryInterface(__uuidof(IUnknown), reinterpret_cast<void**>(&pu2));
  836.  
  837.             if (FAILED(hr)) {
  838.                 _com_issue_error(hr);
  839.             }
  840.  
  841.             pu2->Release();
  842.         }
  843.         else {
  844.             pu2 = NULL;
  845.         }
  846.  
  847.         return pu1 - pu2;
  848.     }
  849.  
  850.     // Try to extract either IDispatch* or an IUnknown* from
  851.     // the VARIANT
  852.     //
  853.     HRESULT QueryStdInterfaces(const _variant_t& varSrc) throw()
  854.     {
  855.         if (V_VT(&varSrc) == VT_DISPATCH) {
  856.             return _QueryInterface(V_DISPATCH(&varSrc));
  857.         }
  858.  
  859.         if (V_VT(&varSrc) == VT_UNKNOWN) {
  860.             return _QueryInterface(V_UNKNOWN(&varSrc));
  861.         }
  862.  
  863.         // We have something other than an IUnknown or an IDispatch.
  864.         // Can we convert it to either one of these?
  865.         // Try IDispatch first
  866.         //
  867.         VARIANT varDest;
  868.         VariantInit(&varDest);
  869.  
  870.         HRESULT hr = VariantChangeType(&varDest, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)), 0, VT_DISPATCH);
  871.         if (SUCCEEDED(hr)) {
  872.             hr = _QueryInterface(V_DISPATCH(&varSrc));
  873.         }
  874.  
  875.         if (FAILED(hr) && (hr == E_NOINTERFACE)) {
  876.             // That failed ... so try IUnknown
  877.             //
  878.             VariantInit(&varDest);
  879.             hr = VariantChangeType(&varDest, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)), 0, VT_UNKNOWN);
  880.             if (SUCCEEDED(hr)) {
  881.                 hr = _QueryInterface(V_UNKNOWN(&varSrc));
  882.             }
  883.         }
  884.  
  885.         VariantClear(&varDest);
  886.         return hr;
  887.     }
  888. };
  889.  
  890. // Reverse comparison operators for _com_ptr_t
  891. //
  892. template<typename _InterfaceType> bool operator==(int null, _com_ptr_t<_InterfaceType>& p) throw(_com_error)
  893. {
  894.     if (null != 0) {
  895.         _com_issue_error(E_POINTER);
  896.     }
  897.  
  898.     return p == NULL;
  899. }
  900.  
  901. template<typename _Interface, typename _InterfacePtr> bool operator==(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  902. {
  903.     return p == i;
  904. }
  905.  
  906. template<typename _Interface> bool operator!=(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  907. {
  908.     if (null != 0) {
  909.         _com_issue_error(E_POINTER);
  910.     }
  911.  
  912.     return p != NULL;
  913. }
  914.  
  915. template<typename _Interface, typename _InterfacePtr> bool operator!=(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  916. {
  917.     return p != i;
  918. }
  919.  
  920. template<typename _Interface> bool operator<(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  921. {
  922.     if (null != 0) {
  923.         _com_issue_error(E_POINTER);
  924.     }
  925.  
  926.     return p > NULL;
  927. }
  928.  
  929. template<typename _Interface, typename _InterfacePtr> bool operator<(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  930. {
  931.     return p > i;
  932. }
  933.  
  934. template<typename _Interface> bool operator>(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  935. {
  936.     if (null != 0) {
  937.         _com_issue_error(E_POINTER);
  938.     }
  939.  
  940.     return p < NULL;
  941. }
  942.  
  943. template<typename _Interface, typename _InterfacePtr> bool operator>(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  944. {
  945.     return p < i;
  946. }
  947.  
  948. template<typename _Interface> bool operator<=(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  949. {
  950.     if (null != 0) {
  951.         _com_issue_error(E_POINTER);
  952.     }
  953.  
  954.     return p >= NULL;
  955. }
  956.  
  957. template<typename _Interface, typename _InterfacePtr> bool operator<=(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  958. {
  959.     return p >= i;
  960. }
  961.  
  962. template<typename _Interface> bool operator>=(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  963. {
  964.     if (null != 0) {
  965.         _com_issue_error(E_POINTER);
  966.     }
  967.  
  968.     return p <= NULL;
  969. }
  970.  
  971. template<typename _Interface, typename _InterfacePtr> bool operator>=(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  972. {
  973.     return p <= i;
  974. }
  975.  
  976. #pragma warning(pop)
  977.  
  978. #pragma option pop /*P_O_Pop*/
  979. #endif // _INC_COMIP
  980.