comObjLib.h
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:23k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* comObjLib.h - template-based COM-object construction library (VxCOM) */
  2. /* Copyright (c) 1999 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 02n,04oct01,dbs  add macros to export coclasses in shlibs
  7. 02m,24sep01,nel  SPR#70528. Fix memory leak in CComBSTR.
  8. 02l,31jul01,dbs  allow override of InternalAddRef/Release methods
  9. 02k,28jun01,dbs  use safe inc/dec funcs, remove VxMutex dependency
  10. 02j,21jun01,dbs  make use of VxMutex class
  11. 02i,09apr01,nel  SPR#65606. Correct minor formating errors.
  12. 02h,28feb01,nel  SPR#35792. Add more ATL defs to bring into line with T2.
  13. 02g,16aug00,nel  Add CComBSTR(char *) to CComStr to make MathDemo example work
  14.                  under vxworks.
  15. 02f,30may00,nel  Add more variant support
  16. 02e,28feb00,nel  Remove VxComTrack dependency on hard coded idl stuff
  17. 02d,01feb00,nel  Added VxComTrack code and Fix for singleton operation
  18. 02c,15oct99,dbs  fix comments to refer to proper classnames
  19. 02b,18aug99,dbs  remove extraneous ptr-conversion operator in CComPtr
  20. 02a,13aug99,drm  Bux fix.
  21. 01z,13aug99,dbs  fix copy-ctor in CComPtr
  22. 01y,29jul99,aim  changed mutex types to void*
  23. 01x,28jul99,drm  Changing g_defaultServerPriority to g_defaultServerPriority.
  24. 01w,28jul99,dbs  remove PS_CLNT_ASSIGNED enum value
  25. 01v,26jul99,dbs  fix typo in COM_INTERFACE_ENTRY macros
  26. 01u,30jun99,dbs  add const operator-> to CComPtr
  27. 01t,28jun99,dbs  remove obsolete ptrAssign function
  28. 01s,04jun99,dbs  fix registry calls
  29. 01r,03jun99,dbs  remove comSyncLib and VxMutex class
  30. 01q,26may99,dbs  add further ATL compatibility
  31. 01p,20may99,dbs  move class-object functionality into CComCoClass
  32.                  class so explicit template instantiation works
  33. 01o,04may99,dbs  check return value of alloc in CreateInstance
  34. 01n,03may99,drm  adding priority scheme support
  35. 01m,27apr99,dbs  add alloc helper funcs
  36. 01l,23apr99,dbs  make mutex publically available thru CComObject methods
  37. 01k,23apr99,dbs  improve QI implementation, remove virtualness,
  38.                  enforce locking in CComObject class
  39. 01j,22apr99,dbs  remove potential leaks, remove extraneous debugging
  40.                  code (will be replaced with official DEBUG-lib in
  41.  future), simplify locking strategy (we don't need to
  42.  provide a VxNoLock class at all).
  43. 01i,14apr99,dbs  put incr and decr methods into VxMutex class
  44. 01h,31mar99,dbs  add CComPtr and CComBSTR classes
  45. 01g,03feb99,dbs  use STDMETHOD macros
  46. 01f,20jan99,dbs  fix file names - vxcom becomes com
  47. 01e,11jan99,dbs  change classnames to be ATL compatible
  48. 01d,21dec98,dbs  changes for VXCOM
  49. 01c,15dec98,dbs  add singleton support
  50. 01b,11dec98,dbs  simplify registry
  51. 01a,17nov98,dbs  created
  52. */
  53. /*
  54.   DESCRIPTION:
  55.   This file contains template classes for creating COM objects using
  56.   multiple inheritance to implement multiple interfaces. Classes
  57.   created with these templates feature class-factories, thread-safe
  58.   reference counting, etc...
  59.   They are source-level compatible with ATL, and use the same
  60.   COM_MAP() style of interface mapping, although the implementation is
  61.   somewhat different.
  62.   */
  63. #ifndef __INCcomObjLib_h__
  64. #define __INCcomObjLib_h__
  65. #include "comCoreLib.h"
  66. #include "comLib.h"
  67. #include <stdio.h>
  68. #define DECLARE_CLASSFACTORY_SINGLETON() enum {singleton=1};
  69. #define DECLARE_REGISTRY_RESOURCE(x)
  70. #define DECLARE_REGISTRY(class, pid, vpid, nid, flags)
  71. #ifndef VXDCOM_COMTRACK_LEVEL
  72. #define VXDCOM_COMTRACK_LEVEL 0
  73. #endif
  74. #if (VXDCOM_COMTRACK_LEVEL == 0)
  75. #define COMTRACK_ADD_CLS(c)
  76. #define COMTRACK_ADD_IID(c) 
  77. #define COMTRACK_UPDATE()
  78. #else
  79. #include "comShow.h"
  80. #define COMTRACK_ADD_CLS(c) if (VxComTrack::theInstance()->addClassInstance ((void *)this, (char *)vxcomGUID2String (GetObjectCLSID ()), #c, m_dwRefCount, GetObjectCLSID ()) != NULL) _qi_impl (IID_IUnknown, NULL)
  81. #define COMTRACK_ADD_IID(c) VxComTrack::theInstance()->addInterface ((void *)this, (char *)vxcomGUID2String (IID_##c), "IID_"#c, IID_##c)
  82. #define COMTRACK_UPDATE() VxComTrack::theInstance()->updateClassInstance (this, m_dwRefCount)
  83. #endif
  84. //////////////////////////////////////////////////////////////////////////
  85. //
  86. // CComObjectRoot - the base class of all the VxDCOM classes. It
  87. // provides basic IUnknown support, plus support for COM aggregation
  88. // and reference-counting...
  89. //
  90. class CComObjectRoot
  91.     {
  92.   public:
  93.     enum { singleton=0 };
  94.     CComObjectRoot (IUnknown *punk=0)
  95.       : m_dwRefCount (0),
  96. m_pUnkOuter (punk)
  97. {
  98. }
  99.     virtual ~CComObjectRoot ()
  100. {
  101. }
  102.     // IUnknown implementation support - these methods provide the
  103.     // basis upon which the IUnknown methods are built...
  104.     ULONG InternalAddRef ()
  105. {
  106.         ULONG n = comSafeInc (&m_dwRefCount);
  107. return n;
  108. }
  109.     ULONG InternalRelease ()
  110. {
  111.         ULONG n = comSafeDec (&m_dwRefCount);
  112. COMTRACK_UPDATE ();
  113. if (n)
  114.     return n;
  115. // Must delete this object, so we temporarily set its
  116. // ref-count to 1 so we don't get circular destruction
  117. // chains...
  118. m_dwRefCount = 1;
  119. delete this;
  120. return 0;
  121. }
  122.     
  123.   protected:
  124.     long m_dwRefCount; // reference-count
  125.     IUnknown* m_pUnkOuter; // aggregating outer
  126.     };
  127. //////////////////////////////////////////////////////////////////////////
  128. //
  129. // CComClassFactory - implements IClassFactory to allow objects to
  130. // be created at runtime...
  131. //
  132. template <class T> class CComClassFactory
  133.     : public CComObjectRoot,
  134.       public IClassFactory
  135.     
  136.     {
  137.     enum { singleton_factory=T::singleton };
  138.     
  139.   public:
  140.     CComClassFactory () {}
  141.     
  142.     // IUnknown implementation for class-factory
  143.     ULONG STDMETHODCALLTYPE AddRef ()
  144.         { return InternalAddRef (); }
  145.     ULONG STDMETHODCALLTYPE Release ()
  146.         { 
  147.         ULONG result = InternalRelease ();
  148.         return result;
  149.         }
  150.     HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void ** ppv)
  151. {
  152.         if (! ppv)
  153.             return E_POINTER;
  154.         if ((riid == IID_IClassFactory) || (riid == IID_IUnknown))
  155.             {
  156.             *ppv = static_cast<IClassFactory*> (this);
  157.             InternalAddRef ();
  158.             return S_OK;
  159.             }
  160. *ppv = 0;
  161.         return E_NOINTERFACE;
  162.         }
  163.     // IClassFactory implementation
  164.     HRESULT STDMETHODCALLTYPE CreateInstance
  165. (
  166. IUnknown* pUnkOuter,
  167. REFIID riid,
  168. void** ppv
  169. );
  170.         
  171.     HRESULT STDMETHODCALLTYPE LockServer (BOOL bLock)
  172.         { return S_OK; }
  173.     };
  174. //////////////////////////////////////////////////////////////////////////
  175. //
  176. // CComCoClass - represents the 'coclass' or component-object
  177. // itself. The 'coclass' represents the whole object, not any
  178. // particular one of its exposed interfaces, and is only required when
  179. // an object/class must be 'externally' createable via
  180. // CoCreateinstance(). Hence, the functions required by
  181. // CComClassFactory and the registration mechanism are wrapped in this
  182. // template-class. It should be mixed in with the user's class when
  183. // this functionality is required.
  184. //
  185. template <class T, const CLSID* pclsid> class CComCoClass
  186.     {
  187.     typedef CComClassFactory<T> ClassFactory_t;
  188.   public:
  189.     static const CLSID& GetObjectCLSID () { return *pclsid; }
  190.     
  191.     // classObjectGet - gets the class' class-object (factory)...
  192.     static HRESULT classObjectGet
  193. (
  194. REFCLSID clsid,
  195. REFIID iid,
  196. void** ppv
  197. )
  198.         {
  199. // Validate CLSID
  200. if (*pclsid != clsid)
  201.     return CLASS_E_CLASSNOTAVAILABLE;
  202. // Create new factory...     
  203.         ClassFactory_t* pCF = new ClassFactory_t;
  204. // Bump up CF ref count to 1
  205. pCF->AddRef ();
  206. // QI for requested interface - if successful it will leave
  207. // ref-count at 2, if not, then it will be 1 still...
  208. HRESULT hr = pCF->QueryInterface (iid, ppv);
  209. // release one reference - if QI failed this will destroy the
  210. // factory, but if successful will leave it around...
  211. pCF->Release ();
  212. return hr;
  213.         }
  214.     // classRegister - this function is used by the auto-registration
  215.     // macro AUTOREGISTER_COCLASS to add the CLSID to the Registry
  216.     static HRESULT classRegister 
  217.         (
  218.         VXDCOMPRIORITYSCHEME scheme, // priority scheme to use
  219.         int priority      // priority - not used by all schemes 
  220.         )
  221. {
  222.         int priorityToRegister; // prio to register is determined by sheme
  223.         switch (scheme)
  224.             {
  225.             case PS_DEFAULT:
  226.                 // Set priority to system default; ignore priority argument
  227.                 priorityToRegister = g_defaultServerPriority;
  228.                 break;
  229.             
  230.             case PS_SVR_ASSIGNED:
  231.                 // Set priority to given priority
  232.                 priorityToRegister = priority;
  233.                 break;
  234.             case PS_CLNT_PROPAGATED:
  235.                 // Set priority to given priority for cases where the priority
  236.                 // is not provided by the client (as in Win32).  If the
  237.                 // provided priority is < 0, then use the default system
  238.                 // priority.
  239.                 if (priority < 0)
  240.                     priorityToRegister = g_defaultServerPriority;
  241.                 else
  242.                     {
  243.                     if ((priority >=0) && (priority <=255))
  244.                         priorityToRegister = priority;
  245.                     else
  246.                         priorityToRegister = g_defaultServerPriority;
  247.                     }
  248.                 break;
  249.             default:
  250.                 // Unknown or unsupported priority scheme.  Return an error.
  251.                 return E_UNEXPECTED;
  252.                 break;
  253.             }
  254.         // Register the structure against the CLSID
  255. return comClassRegister (*pclsid,
  256.                                  CLSCTX_INPROC_SERVER,
  257.                                  &classObjectGet,
  258.                                  scheme,
  259.                                  priorityToRegister);
  260.         }
  261.     };
  262. //////////////////////////////////////////////////////////////////////////
  263. //
  264. // wotlQIHelper -- templated on the same implementation class as 
  265. // CComObject, this function provides a type-safe way of invoking
  266. // the class' _qi_impl() method.
  267. //
  268. template <class T>
  269. HRESULT wotlQIHelper (T* pThis, REFIID riid, void** ppv)
  270.     {
  271.     return pThis->_qi_impl (riid, ppv);
  272.     }
  273. //////////////////////////////////////////////////////////////////////////
  274. //
  275. // CComObject - the main class for creating objects. The class 'T'
  276. // must derive from CComObjectRoot (in order to gain an IUnknown
  277. // implementation and other support functionality).
  278. //
  279. template <class T> class CComObject : public T
  280.     {
  281.   public:
  282.     // CreateInstance() creates a single instance, no aggregation, no
  283.     // specific COM interface...
  284.     static HRESULT CreateInstance (CComObject<T>** pp);
  285.     // CreateInstance - does the business of creating an instance of
  286.     // the class, and finding the requested interface on it...
  287.     static HRESULT CreateInstance
  288. (
  289. IUnknown* punkOuter,
  290. REFIID riid,
  291. void**  ppv
  292. )
  293.         {
  294. // Validate args
  295.         if (!ppv)
  296.             return E_POINTER;
  297. // Create an instance (refcount will be zero)
  298.         CComObject* pObj = new CComObject;
  299. if (! pObj)
  300.     return E_OUTOFMEMORY;
  301. // preset return value in case we fail to QI
  302. *ppv = 0;
  303. // save aggregate IUnknown ptr
  304. pObj->m_pUnkOuter = punkOuter;
  305. // QI for desired interface - if it fails, we must get rid of
  306. // the recently-allocated instance before returning. If it
  307. // succeeds, returned interface-ptr will have one ref...
  308.         HRESULT hr = pObj->_qi_impl (riid, ppv);
  309. if (FAILED (hr))
  310.     delete pObj;
  311. return hr;
  312.         }
  313.     
  314.     // over-ride the base-class 'internal_qi' method so we can
  315.     // implement QI via the COM_MAP macros...
  316.     HRESULT internal_qi (REFIID riid, void** ppv)
  317. {
  318. return _qi_impl (riid, ppv);
  319. }
  320.     // IUnknown implementation - these methods are used by each of the
  321.     // multiply-inherited base interfaces as their own IUnknown
  322.     // methods.
  323.     
  324.     ULONG STDMETHODCALLTYPE AddRef ()
  325. {
  326. if (m_pUnkOuter)
  327.     return m_pUnkOuter->AddRef ();
  328. return InternalAddRef ();
  329. }
  330.     
  331.     ULONG STDMETHODCALLTYPE Release ()
  332. {
  333. if (m_pUnkOuter)
  334.     return m_pUnkOuter->Release ();
  335.         return InternalRelease ();
  336. }
  337.     
  338.     HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void ** ppv)
  339.         {
  340. if (m_pUnkOuter)
  341.     return m_pUnkOuter->QueryInterface (riid, ppv);
  342. return wotlQIHelper<T> (this, riid, ppv);
  343. }
  344.   private:
  345.     static DWORD m_dwRegToken;
  346.     
  347.     };
  348. template <class T>
  349. HRESULT CComObject<T>::CreateInstance (CComObject<T>** pp)
  350.     {
  351.     if (0 != pp)
  352.         {
  353.         *pp = new CComObject<T> ();
  354.         if (0 != *pp)
  355.             return S_OK;
  356.         return E_OUTOFMEMORY;
  357.         }
  358.     return E_POINTER;
  359.     }
  360. template <class T> DWORD CComObject<T>::m_dwRegToken;
  361. template <class T>
  362. HRESULT CComClassFactory<T>::CreateInstance
  363.     (
  364.     IUnknown* pUnkOuter,
  365.     REFIID riid,
  366.     void** ppv
  367.     )
  368.     {
  369.     HRESULT hr;
  370.     static IUnknown* m_punkTheInstance = 0;
  371.     if (singleton_factory)
  372. {
  373. if (pUnkOuter)
  374.     return CLASS_E_NOAGGREGATION;
  375. if (! m_punkTheInstance)
  376.     {
  377.     hr = CComObject<T>::CreateInstance
  378.  (0, IID_IUnknown, (void**) &m_punkTheInstance);
  379.     if (FAILED (hr))
  380. return hr;
  381. // This is a singleton so we will never want to delete it, 
  382. // therefore we increment the ref count.
  383.         AddRef ();
  384.     }
  385. return m_punkTheInstance->QueryInterface (riid, ppv);
  386. }
  387.     
  388.     return CComObject<T>::CreateInstance (pUnkOuter, riid, ppv);
  389.     }
  390. //////////////////////////////////////////////////////////////////////////
  391. //
  392. // CComPtr --  a smart-ptr class (like that of ATL) for holding COM
  393. // interface pointers, and performing automatic ref-counting. We don't 
  394. // provide the CComQIPtr class.
  395. //
  396. template <class Itf> class CComPtr
  397.     {
  398.     Itf* m_ptr;
  399.     
  400.   public:
  401.     CComPtr () : m_ptr (0) {}
  402.     
  403.     CComPtr (Itf* p) : m_ptr (p)
  404. {
  405. if (m_ptr)
  406.     m_ptr->AddRef ();
  407. }
  408.    
  409.     CComPtr (const CComPtr<Itf>& sp) : m_ptr (sp.m_ptr)
  410. {
  411. if (m_ptr)
  412.     m_ptr->AddRef ();
  413. }
  414.     
  415.     ~CComPtr ()
  416. {
  417. if (m_ptr)
  418.     m_ptr->Release ();
  419. m_ptr = 0;
  420. }
  421.     
  422.     void Release ()
  423. {
  424. if (m_ptr)
  425.     m_ptr->Release ();
  426. m_ptr = 0;
  427. }
  428.     
  429.     operator Itf* () const
  430. {
  431. return m_ptr;
  432. }
  433.     
  434.     Itf** operator& ()
  435. {
  436. return &m_ptr;
  437. }
  438.     
  439.     Itf* operator-> ()
  440. {
  441. return m_ptr;
  442. }
  443.     
  444.     const Itf* operator-> () const
  445. {
  446. return m_ptr;
  447. }
  448.     
  449.     Itf* operator= (Itf* p)
  450. {
  451. if (p)
  452.     p->AddRef ();
  453. if (m_ptr)
  454.     m_ptr->Release ();
  455. m_ptr = p;
  456. return m_ptr;
  457. }
  458.     
  459.     Itf* operator= (const CComPtr<Itf>& sp)
  460. {
  461. if (sp.m_ptr)
  462.     sp.m_ptr->AddRef ();
  463. if (m_ptr)
  464.     m_ptr->Release ();
  465. m_ptr = sp.m_ptr;
  466. return m_ptr;
  467. }
  468.     
  469.     bool operator! () const
  470. {
  471. return (m_ptr == 0);
  472. }
  473.     void Attach (Itf *p2)
  474.         {
  475.         if (0 != m_ptr)
  476.             {
  477.             m_ptr->Release ();
  478.             }
  479.         m_ptr = p2;
  480.         }
  481.     Itf *Detach()
  482.         {
  483.         Itf *pt = m_ptr;
  484.         m_ptr = 0;
  485.         return pt;
  486.         }
  487.     
  488.     HRESULT CopyTo (Itf **ppT)
  489.         {
  490.         if (0 == ppT)
  491.             {
  492.             return E_POINTER;
  493.             }
  494.         *ppT = m_ptr;
  495.         if (0 != p)
  496.             {
  497.             p->AddRef ();
  498.             }
  499.         return S_OK;
  500.         }
  501.     };
  502. ///////////////////////////////////////////////////////////////////////
  503. //
  504. // CComBSTR --  a class that wraps up the BSTR data type...
  505. //
  506. class CComBSTR
  507.     {
  508.     BSTR m_str;
  509.     
  510.   public:
  511.     CComBSTR () : m_str (0) {}
  512.     explicit CComBSTR (int nSize, LPCOLESTR sz = 0)
  513. {
  514. m_str = ::SysAllocStringLen (sz, nSize);
  515. }
  516. CComBSTR (const char * pstr)
  517. {
  518. OLECHAR * wsz = new OLECHAR [(strlen (pstr) + 1) * 2];
  519. comAsciiToWide (wsz, pstr, strlen (pstr) + 1);
  520. m_str = ::SysAllocString (wsz);
  521. delete [] wsz;
  522. }
  523.     explicit CComBSTR (LPCOLESTR psz)
  524. {
  525. m_str = ::SysAllocString (psz);
  526. }
  527.     
  528.     explicit CComBSTR (const CComBSTR& src)
  529. {
  530. m_str = src.Copy ();
  531. }
  532.     
  533.     CComBSTR& operator= (const CComBSTR& cbs);
  534.     CComBSTR& operator= (LPCOLESTR pSrc);
  535.     
  536.     ~CComBSTR()
  537. {
  538. Empty ();
  539. }
  540.     
  541.     unsigned int Length () const
  542. {
  543. return ::SysStringLen (m_str);
  544. }
  545.     
  546.     operator BSTR () const
  547. {
  548. return m_str;
  549. }
  550.     
  551.     BSTR* operator& ()
  552. {
  553. return &m_str;
  554. }
  555.     BSTR Copy() const
  556. {
  557. return ::SysAllocStringLen (m_str, ::SysStringLen (m_str));
  558. }
  559.     
  560.     void Attach (BSTR src)
  561. {
  562. m_str = src;
  563. }
  564.     
  565.     BSTR Detach ()
  566. {
  567. BSTR s = m_str;
  568. m_str = 0;
  569. return s;
  570. }
  571.     
  572.     void Empty ()
  573. {
  574. if (m_str)
  575.     ::SysFreeString (m_str);
  576. m_str = 0;
  577. }
  578.     
  579.     bool operator! () const
  580. {
  581. return (m_str == NULL);
  582. }
  583.     void Append (const CComBSTR& cbs)
  584. {
  585. Append (cbs.m_str, ::SysStringLen (cbs.m_str));
  586. }
  587.     
  588.     void Append  (LPCOLESTR lpsz)
  589. {
  590. Append (lpsz, ::comWideStrLen (lpsz));
  591. }
  592.     
  593.     void AppendBSTR (BSTR bs)
  594. {
  595. Append (bs, ::SysStringLen (bs));
  596. }
  597.     
  598.     void Append (LPCOLESTR lpsz, int nLen);
  599.     CComBSTR& operator+= (const CComBSTR& cbs)
  600. {
  601. AppendBSTR (cbs.m_str);
  602. return *this;
  603. }
  604.     };
  605. //////////////////////////////////////////////////////////////////////////
  606. //
  607. // CComVariant support
  608. //
  609. class CComVariant : public tagVARIANT
  610. {
  611. // Constructors
  612. public:
  613.     CComVariant()
  614. {
  615. ::VariantInit(this);
  616. }
  617.     ~CComVariant()
  618. {
  619. Clear();
  620. }
  621.     CComVariant(const VARIANT& varSrc)
  622. {
  623. ::VariantInit(this);
  624. InternalCopy(&varSrc);
  625. }
  626.     CComVariant(const CComVariant& varSrc)
  627. {
  628.         ::VariantInit(this);
  629.         InternalCopy(&varSrc);
  630. }
  631.     CComVariant(BSTR bstrSrc)
  632. {
  633.         ::VariantInit(this);
  634.         *this = bstrSrc;
  635. }
  636.     CComVariant(LPCOLESTR lpszSrc)
  637. {
  638.         ::VariantInit(this);
  639.         *this = lpszSrc;
  640. }
  641.     CComVariant(bool bSrc)
  642. {
  643.         ::VariantInit(this);
  644.         vt = VT_BOOL;
  645.         boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
  646. }
  647.     CComVariant(int nSrc)
  648. {
  649.         ::VariantInit(this);
  650.         vt = VT_I4;
  651.         lVal = nSrc;
  652. }
  653.     CComVariant(BYTE nSrc)
  654. {
  655.         ::VariantInit(this);
  656.         vt = VT_UI1;
  657.         bVal = nSrc;
  658. }
  659.     CComVariant(short nSrc)
  660. {
  661.         ::VariantInit(this);
  662.         vt = VT_I2;
  663.         iVal = nSrc;
  664. }
  665.     CComVariant(long nSrc, VARTYPE vtSrc = VT_I4)
  666. {
  667.         ::VariantInit(this);
  668.         vt = vtSrc;
  669.         lVal = nSrc;
  670. }
  671.     CComVariant(float fltSrc)
  672. {
  673.         ::VariantInit(this);
  674.         vt = VT_R4;
  675.         fltVal = fltSrc;
  676. }
  677.     CComVariant(double dblSrc)
  678. {
  679.         ::VariantInit(this);
  680.         vt = VT_R8;
  681.         dblVal = dblSrc;
  682. }
  683.     CComVariant(CY cySrc)
  684. {
  685.         ::VariantInit(this);
  686.         vt = VT_CY;
  687.         cyVal = cySrc;
  688. }
  689.     CComVariant(IUnknown* pSrc)
  690. {
  691.         ::VariantInit(this);
  692.         vt = VT_UNKNOWN;
  693.         punkVal = pSrc;
  694.         if (punkVal != NULL)
  695.             {
  696.             punkVal->AddRef();
  697.             }
  698. }
  699.     CComVariant& operator=(const CComVariant& varSrc)
  700. {
  701.         InternalCopy(&varSrc);
  702.         return *this;
  703. }
  704.     CComVariant& operator=(const VARIANT& varSrc)
  705. {
  706.         InternalCopy(&varSrc);
  707.         return *this;
  708. }
  709.     CComVariant& operator=(BSTR bstrSrc);
  710.     CComVariant& operator=(LPCOLESTR lpszSrc);
  711.     CComVariant& operator=(bool bSrc);
  712.     CComVariant& operator=(int nSrc);
  713.     CComVariant& operator=(BYTE nSrc);
  714.     CComVariant& operator=(short nSrc);
  715.     CComVariant& operator=(long nSrc);
  716.     CComVariant& operator=(float fltSrc);
  717.     CComVariant& operator=(double dblSrc);
  718.     CComVariant& operator=(CY cySrc);
  719.     CComVariant& operator=(IUnknown* pSrc);
  720.     bool operator==(const VARIANT& varSrc);
  721.     bool operator!=(const VARIANT& varSrc) {return !operator==(varSrc);}
  722.     HRESULT Clear() 
  723.         { 
  724.         return ::VariantClear(this); 
  725.         }
  726.     HRESULT Copy(const VARIANT* pSrc) 
  727.         { 
  728.         return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); 
  729.         }
  730.     HRESULT Attach(VARIANT* pSrc);
  731.     HRESULT Detach(VARIANT* pDest);
  732.     HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = NULL);
  733.     HRESULT InternalClear();
  734.     void InternalCopy(const VARIANT* pSrc);
  735. };
  736. //////////////////////////////////////////////////////////////////////////
  737. //
  738. // Macros for making QueryInterface work.
  739. //
  740. // The COM_MAP macros define a function called _qi_impl() which does
  741. // runtime casts to obtain the requested interface pointer.
  742. //
  743. // Other than that, the layout of the COM_MAP in the user's class is
  744. // identical to an ATL map, but only allows for COM_INTERFACE_ENTRY
  745. // and COM_INTERFACE_ENTRY_IID entries, not any of the other more
  746. // fanciful types.
  747. //
  748. // The default IUnknown is always the first COM_INTERFACE_ENTRY in the
  749. // table, so (by definition) this must be derived from IUnknown or the
  750. // static_cast() will fail...
  751. //
  752. #define BEGIN_COM_MAP(cls) HRESULT _qi_impl (REFIID riid, void** ppv) { 
  753.        COMTRACK_ADD_CLS(cls);
  754. #define COM_INTERFACE_ENTRY(itf)                            
  755.     if (ppv == NULL)                                        
  756. {COMTRACK_ADD_IID (itf);} else {     
  757.     if ((IID_##itf == riid) || (IID_IUnknown == riid)) {    
  758.         *ppv = static_cast<itf*> (this);                    
  759.         InternalAddRef ();                                  
  760.         COMTRACK_UPDATE ();                                 
  761.         return S_OK; } }
  762. #define COM_INTERFACE_ENTRY_IID(iid,itf)                    
  763.     if (ppv == NULL)                                        
  764.         {COMTRACK_ADD_IID (itf);} else {                    
  765.     if (riid == iid) {                                      
  766.         *ppv = static_cast<itf*> (this);                    
  767.         InternalAddRef ();                                  
  768.         COMTRACK_UPDATE ();                                 
  769.         return S_OK; }}
  770. #define END_COM_MAP()                                       
  771.     if (ppv != 0) *ppv = 0;                                 
  772.     return E_NOINTERFACE; }
  773. //////////////////////////////////////////////////////////////////////////
  774. //
  775. //        AUTOREGISTER_COCLASS(cls,name)
  776. //
  777. // This macro must be included in the object-implementation C++ source
  778. // file after the object's class definition. It associates the C++
  779. // class 'cls' with the CLSID and registers the module
  780. // name in the VxRegistry, against the object's CLSID.
  781. //
  782. //////////////////////////////////////////////////////////////////////////
  783. #define AUTOREGISTER_COCLASS(cls,priorityScheme, priority)
  784.     struct cls ## _autoreg {                             
  785.         cls ## _autoreg () {                             
  786.             CComObject<cls>::classRegister (priorityScheme,
  787.                                             priority); } };
  788.     static cls ## _autoreg  __autoreg_ ## cls;
  789. //////////////////////////////////////////////////////////////////////////
  790. //
  791. // BEGIN_COCLASS_TABLE, EXPORT_COCLASS, END_COCLASS_TABLE
  792. //
  793. // Macros for exporting coclasses from shared-libraries. They should
  794. // be used like so:-
  795. //
  796. // BEGIN_COCLASS_TABLE
  797. //   EXPORT_COCLASS(CoMyClass)
  798. // END_COCLASS_TABLE
  799. //
  800. // where CoMyClass is a coclass (i.e. inherits CComCoClass) and thus
  801. // has a static method 'classObjectGet' conforming to the typedef
  802. // PFN_GETCLASSOBJECT as defined in comCoreLib.h
  803. //
  804. //////////////////////////////////////////////////////////////////////////
  805. #define BEGIN_COCLASS_TABLE                                     
  806. extern "C" HRESULT DllGetClassObject                            
  807.     (REFCLSID clsid, REFIID iid, void** ppv) {
  808. #define EXPORT_COCLASS(coclass)                                 
  809.     if (clsid == coclass::GetObjectCLSID ())                    
  810.         { return coclass::classObjectGet (clsid, iid, ppv); }
  811. #define END_COCLASS_TABLE                                       
  812.     return CLASS_E_CLASSNOTAVAILABLE; }
  813. #endif /* __INCcomObjLib_h__ */