unkimp.h
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:23k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. //
  36. //
  37. // Macro implementation of IUnknown
  38. //
  39. //  Description:
  40. // This file defines classes and Macro's to simplify the implementation 
  41. // of IUnknown in RMA objects.
  42. // It also implements object creation methods 
  43. // (CreateObject, CreateInstance)
  44. //
  45. //  Usage Tips:
  46. //
  47. // Never use the new operator to create a class instance!!
  48. //     Instead use CreateObject if you need to use non-interface
  49. //     methods and CreateInstance otherwise.
  50. //
  51. //  Class(es) Defined in this file:
  52. //
  53. // CUnknownIMP
  54. //     The COM Object implementation must inherit from this class.
  55. //
  56. // CAggregateImpl
  57. //     Used internally to support Aggregation.
  58. //
  59. //  Macros Defined in this file:
  60. //
  61. // DECLARE_UNKNOWN(THIS_CLASS)
  62. //     This must be in the class declaration.
  63. //
  64. // BEGIN_INTERFACE_LIST(THIS_CLASS)
  65. //     This must be in the class implementation.
  66. //
  67. // END_INTERFACE_LIST
  68. //     This must be in the class implementation.
  69. //
  70. // INTERFACE_LIST_ENTRY(INTERFACE_IID, INTERFACE_CLASS)
  71. //     Defines the QI of a locally implemented interface.
  72. //     Optional: if used must be in the class implementation.
  73. //
  74. // INTERFACE_LIST_ENTRY2(DERIVED_CLASS, BASE_INTERFACE_IID, BASE_CLASS)
  75. //     Defines the QI of a locally implemented interface that must be 
  76. //     disambiguated. DERIVED_CLASS is the intermediate class used to 
  77. //     achieve the disambiguation.
  78. //
  79. // INTERFACE_LIST_ENTRY_DELEGATE(INTERFACE_IID, DELEGATE_QI_FUNCTION)
  80. //     Defines the QI of a single interface supported by an aggregated 
  81. //     object.
  82. //     Optional: if used must be in the class implementation.
  83. //
  84. // INTERFACE_LIST_ENTRY_DELEGATE_BLIND(DELEGATE_QI_FUNCTION)
  85. //     Defines the QI of all interfaces supported by an aggregated object.
  86. //     Optional: if used must be in the class implementation.
  87. //
  88. // INTERFACE_LIST_ENTRY_BASE
  89. //     Specifies a base class whose query interface function should be called.
  90. //
  91. //  Example:
  92. //
  93. //  rmabuffer.h
  94. // #include <unkimp.h>
  95. //
  96. // class CHXBuffer 
  97. //     : public CUnknownIMP
  98. //     , public IHXBuffer
  99. // {
  100. //     DECLARE_UNKNOWN(CHXBuffer)
  101. // public:
  102. //     STDMETHOD(FinalConstruct)();
  103. //     void FinalRelease();
  104. //
  105. //     // List of IHXBuffer Methods..
  106. //
  107. // private:
  108. //     // List of private members..
  109. //     DECLARE_SMART_POINTER_UNKNOWN m_spunkOther;
  110. //     DECLARE_SMART_POINTER_UNKNOWN m_spunkYetAnother;
  111. // };
  112. //
  113. //  rmabuffer.cpp
  114. // #include "rmabuffer.h"
  115. //
  116. // BEGIN_INTERFACE_LIST(CHXBuffer)
  117. //     INTERFACE_LIST_ENTRY(IID_IHXBuffer, IHXBuffer)
  118. //     INTERFACE_LIST_ENTRY_DELEGATE
  119. //     (
  120. // IID_IHXOther, 
  121. // m_spunkOther.QueryInterface
  122. //     )
  123. //     INTERFACE_LIST_ENTRY_DELEGATE_BLIND
  124. //     (
  125. // m_spunkYetAnother.QueryInterface
  126. //     )
  127. // END_INTERFACE_LIST
  128. //
  129. // STDMETHODIMP CHXBuffer::FinalConstruct()
  130. // {
  131. //     // Create the Aggregated objects here..
  132. //     //
  133. //     if 
  134. //     (
  135. // SUCCEEDED
  136. // (
  137. //     CIHXOther::CreateInstance
  138. //     (
  139. // GetControllingUnknown(),
  140. // &m_spunkOther
  141. //     )
  142. // )
  143. // &&
  144. // SUCCEEDED
  145. // (
  146. //     CIHXYetAnother::CreateInstance
  147. //     (
  148. // GetControllingUnknown(),
  149. // &m_spunkYetAnother
  150. //     )
  151. // )
  152. //     )
  153. //     {
  154. // return HXR_OK;
  155. //     }
  156. //     return HXR_FAIL;
  157. // }
  158. //
  159. // void CHXBuffer::FinalRelease()
  160. // {
  161. //     // If we were not using SmartPointers, we would 
  162. //     // release the Aggregated objects here.
  163. // }
  164. //
  165. // // Implement IHXBuffer methods..
  166. //  
  167. #ifndef __CUnknownIMP_H__
  168. #define __CUnknownIMP_H__
  169. #include "hxcom.h"
  170. #include "hxassert.h"
  171. #ifdef INCLUDE_DEBUG_LIFETIME
  172. #include <io.h>
  173. #include <fcntl.h>
  174. #include "chxdataf.h"
  175. #include "hxtrace.h"
  176. #include "hxstring.h"
  177. #endif // INCLUDE_DEBUG_LIFETIME
  178. #ifdef ENABLE_UNKIMP_TRACKER
  179. #include "ihxiunknowntracker.h"
  180. #endif
  181. class CUnknownIMP : public IUnknown
  182. {
  183. public:
  184.     CUnknownIMP() : m_lCount(0), m_punkOuter(NULL)
  185. #ifdef INCLUDE_DEBUG_LIFETIME
  186.     ,m_pRaFileDebugLifetime(NULL)
  187. #endif
  188.     {
  189. m_punkControlling = this;
  190.     }
  191.     virtual ~CUnknownIMP()
  192.     {}
  193.     /*
  194.      * IUnknown methods
  195.      */
  196.     STDMETHOD(QueryInterface)
  197.     (
  198. THIS_
  199. REFIID riid,
  200. void** ppvObj
  201.     )
  202.     {
  203. if(m_punkOuter)
  204. {
  205.     return m_punkOuter->QueryInterface(riid, ppvObj);
  206. }
  207. return _ActualQI(riid, ppvObj);
  208.     }
  209.     STDMETHOD_(ULONG32,AddRef) (THIS)
  210.     {
  211. if(m_punkOuter)
  212. {
  213.     return m_punkOuter->AddRef();
  214. }
  215. return ActualAddRef();
  216.     }
  217.     STDMETHOD_(ULONG32,Release) (THIS)
  218.     {
  219. if(m_punkOuter)
  220. {
  221.     return m_punkOuter->Release();
  222. }
  223. return ActualRelease();
  224.     }
  225.     const IUnknown* GetUnknown() const
  226.     {
  227. return this;
  228.     }
  229.     IUnknown* GetUnknown()
  230.     {
  231. return this;
  232.     }
  233.     IUnknown* GetControllingUnknown()
  234.     {
  235. return m_punkControlling;
  236.     }
  237.     STDMETHOD(SetupAggregation)( IUnknown* pvOuterObj, IUnknown** pvResult );
  238.     
  239. #ifdef ENABLE_UNKIMP_TRACKER
  240.     static void SetIUnknownTracker( IHXIUnknownTracker* pIUnknownTracker )
  241.     {
  242. if (pIUnknownTracker != ms_pIUnknownTracker)
  243. {
  244.     if (ms_pIUnknownTracker)
  245.     {
  246. IHXIUnknownTracker* pIOldUnknownTracker = ms_pIUnknownTracker;
  247. ms_pIUnknownTracker = NULL;
  248. HX_RELEASE(pIOldUnknownTracker);
  249.     }
  250.     if (pIUnknownTracker)
  251.     {
  252. pIUnknownTracker->AddRef();
  253. ms_pIUnknownTracker = pIUnknownTracker;
  254.     }
  255. }
  256.     }
  257. #endif
  258. protected:
  259.     // This is overriden in the derived object to provide
  260.     // an object specific imp.
  261.     STDMETHOD(_ActualQI)(REFIID riid, void** ppvObj) PURE;
  262. #ifdef INCLUDE_DEBUG_LIFETIME
  263.     CHXDataFile* m_pRaFileDebugLifetime;
  264.     CHXString m_StringFilename;
  265.     void InitFilename(const char* pFilename)
  266.     {
  267. m_StringFilename = pFilename;
  268.     }
  269.     STDMETHOD_(ULONG32,ActualAddRef) ()
  270.     {
  271. if (m_pRaFileDebugLifetime)
  272. {
  273.     char buf[80]; /* Flawfinder: ignore */
  274.     sprintf(buf, "*** AddRef %d ***rn", m_lCount+1); /* Flawfinder: ignore */
  275.     m_pRaFileDebugLifetime->Write(buf, strlen(buf));
  276.     UINT32* pBinaryStackTrace = NULL;
  277.     if (GetStack(&pBinaryStackTrace))
  278.     {
  279. char* pCharStackTrace = NULL;
  280. if (GetStackSymbols(pBinaryStackTrace, &pCharStackTrace))
  281. {
  282.     m_pRaFileDebugLifetime->Write
  283.     (
  284. pCharStackTrace,
  285. strlen(pCharStackTrace)
  286.     );
  287. }
  288. HX_VECTOR_DELETE(pCharStackTrace);
  289.     }
  290.     HX_VECTOR_DELETE(pBinaryStackTrace);
  291. }
  292. return InterlockedIncrement(&m_lCount);
  293.     }
  294.     STDMETHOD_(ULONG32,ActualRelease) ()
  295.     {
  296. if (m_pRaFileDebugLifetime)
  297. {
  298.     char buf[80]; /* Flawfinder: ignore */
  299.     sprintf(buf, "*** Release %d ***rn", m_lCount-1); /* Flawfinder: ignore */
  300.     m_pRaFileDebugLifetime->Write(buf, strlen(buf));
  301.     UINT32* pBinaryStackTrace = NULL;
  302.     if (GetStack(&pBinaryStackTrace))
  303.     {
  304. char* pCharStackTrace = NULL;
  305.      if (GetStackSymbols(pBinaryStackTrace, &pCharStackTrace))
  306. {
  307.     m_pRaFileDebugLifetime->Write
  308.     (
  309. pCharStackTrace,
  310. strlen(pCharStackTrace)
  311.     );
  312. }
  313. HX_VECTOR_DELETE(pCharStackTrace);
  314.     }
  315.     HX_VECTOR_DELETE(pBinaryStackTrace);
  316. }
  317. HX_ASSERT(m_lCount>0);
  318. if (InterlockedDecrement(&m_lCount) > 0)
  319. {
  320.     return m_lCount;
  321. }
  322. FinalRelease();
  323. delete this;
  324. return 0;
  325.     }
  326.     STDMETHOD(FinalConstruct)()
  327.     {
  328. if (m_StringFilename.IsEmpty())
  329. {
  330.     return HXR_OK;
  331. }
  332. char szTemp[32]; /* Flawfinder: ignore */
  333. m_StringFilename.GetBuffer(0)[4] = '';
  334. m_StringFilename.ReleaseBuffer();
  335. ltoa((UINT32)this, szTemp, 16);
  336. m_StringFilename += szTemp;
  337. m_StringFilename.GetBuffer(0)[8] = '.';
  338. if (m_StringFilename.GetLength() > 12)
  339. {                           
  340.     m_StringFilename.GetBuffer(0)[11] = '';
  341.     m_StringFilename.ReleaseBuffer();
  342. }                           
  343. m_pRaFileDebugLifetime = CHXDataFile::Construct();
  344. m_pRaFileDebugLifetime->Open(m_StringFilename, _O_CREAT | _O_RDWR);
  345. m_pRaFileDebugLifetime->Write
  346. (
  347.     "*** Created new class instance ***rn",
  348.     sizeof("*** Created new class instance ***rn")
  349. );
  350. UINT32* pBinaryStackTrace = NULL;
  351. if (GetStack(&pBinaryStackTrace))
  352. {
  353.     char* pCharStackTrace = NULL;
  354.     if (GetStackSymbols(pBinaryStackTrace, &pCharStackTrace))
  355.     {
  356. m_pRaFileDebugLifetime->Write
  357. (
  358.     pCharStackTrace,
  359.     strlen(pCharStackTrace)
  360. );
  361.     }
  362.     HX_VECTOR_DELETE(pCharStackTrace);
  363. }
  364. HX_VECTOR_DELETE(pBinaryStackTrace);
  365. return HXR_OK;
  366.     }
  367.     virtual void FinalRelease()
  368.     {
  369. if (m_pRaFileDebugLifetime)
  370. {
  371.     m_pRaFileDebugLifetime->Write("*** Deleted ***rn", 17);
  372.     UINT32* pBinaryStackTrace = NULL;
  373.     if (GetStack(&pBinaryStackTrace))
  374.     {
  375. char* pCharStackTrace = NULL;
  376. if (GetStackSymbols(pBinaryStackTrace, &pCharStackTrace))
  377. {
  378.     m_pRaFileDebugLifetime->Write
  379.     (
  380. pCharStackTrace,
  381. strlen(pCharStackTrace)
  382.     );
  383. }
  384.         HX_VECTOR_DELETE(pCharStackTrace);
  385.     }
  386.     HX_VECTOR_DELETE(pBinaryStackTrace);
  387.     m_pRaFileDebugLifetime->Close();
  388. }
  389. HX_DELETE(m_pRaFileDebugLifetime);
  390.     }
  391. #else
  392.     // These can be overriden in the derived object to provide
  393.     // an object specific imp.
  394.     STDMETHOD_(ULONG32,ActualAddRef) (THIS)
  395.     {
  396. #ifdef ENABLE_UNKIMP_TRACKER
  397. ULONG32 postAddRefRefCount = InterlockedIncrement(&m_lCount);
  398. if (ms_pIUnknownTracker)
  399. {
  400.     ms_pIUnknownTracker->OnIUnknownAddRef( this, postAddRefRefCount );
  401. }
  402. return postAddRefRefCount;
  403. #else
  404. return InterlockedIncrement(&m_lCount);
  405. #endif
  406.     }
  407.     STDMETHOD_(ULONG32,ActualRelease) (THIS)
  408.     {
  409. HX_ASSERT(m_lCount>0);
  410. #ifdef ENABLE_UNKIMP_TRACKER
  411. ULONG32 preReleaseRefCount = m_lCount;
  412. if (ms_pIUnknownTracker)
  413. {
  414.     ms_pIUnknownTracker->OnIUnknownRelease( this, preReleaseRefCount );
  415. }
  416. #endif
  417. if (InterlockedDecrement(&m_lCount) > 0)
  418. {
  419.     return m_lCount;
  420. }
  421. FinalRelease();
  422. delete this;
  423. return 0;
  424.     }
  425.     STDMETHOD(FinalConstruct)()
  426.     {
  427. return HXR_OK;
  428.     }
  429.     virtual void FinalRelease()
  430.     {
  431.     }
  432. #endif
  433.     LONG32 m_lCount;
  434.     IUnknown* m_punkOuter;
  435.     IUnknown* m_punkControlling;
  436.     friend class CAggregateImpl;
  437. private:
  438.     CUnknownIMP(CUnknownIMP&) : IUnknown () {}
  439.     
  440. #ifdef ENABLE_UNKIMP_TRACKER
  441.     static IHXIUnknownTracker* ms_pIUnknownTracker;
  442. #endif
  443. };
  444. #ifdef INCLUDE_DEBUG_LIFETIME
  445. #define INIT_DEBUG_LIFETIME(CLASS)
  446. CUnknownIMP::InitFilename(#CLASS);
  447. #else
  448. #define INIT_DEBUG_LIFETIME(CLASS)
  449. #endif
  450. #ifdef ENABLE_UNKIMP_TRACKER
  451. #define INIT_UNKIMP_TRACKER 
  452. IHXIUnknownTracker* CUnknownIMP::ms_pIUnknownTracker = NULL;
  453. #endif
  454. class CAggregateImpl : public IUnknown
  455. {
  456. public:
  457.     CAggregateImpl( CUnknownIMP* pobjAggregated )
  458. : m_lCount( 0 )
  459. , m_pobjAggregated( pobjAggregated )
  460.     {}
  461.     virtual ~CAggregateImpl()
  462.     {
  463. delete m_pobjAggregated;
  464.     }
  465.     /*
  466.      * IUnknown methods
  467.      */
  468.     STDMETHOD(QueryInterface)
  469.     (
  470. THIS_
  471. REFIID riid,
  472. void** ppvObj
  473.     )
  474.     {
  475. return m_pobjAggregated->_ActualQI(riid, ppvObj);
  476.     }
  477.     STDMETHOD_(ULONG32,AddRef) (THIS)
  478.     {
  479. #ifdef ENABLE_UNKIMP_TRACKER
  480. ULONG32 postAddRefRefCount = InterlockedIncrement(&m_lCount);
  481. if (CUnknownIMP::ms_pIUnknownTracker)
  482. {
  483.     CUnknownIMP::ms_pIUnknownTracker->OnIUnknownAddRef( m_pobjAggregated, postAddRefRefCount );
  484. }
  485. return postAddRefRefCount;
  486. #else
  487. return InterlockedIncrement(&m_lCount);
  488. #endif
  489.     }
  490.     STDMETHOD_(ULONG32,Release) (THIS)
  491.     {
  492. HX_ASSERT(m_lCount>0);
  493. #ifdef ENABLE_UNKIMP_TRACKER
  494. ULONG32 preReleaseRefCount = m_lCount;
  495. if (CUnknownIMP::ms_pIUnknownTracker)
  496. {
  497.     CUnknownIMP::ms_pIUnknownTracker->OnIUnknownRelease( m_pobjAggregated, preReleaseRefCount );
  498. }
  499. #endif
  500. if (InterlockedDecrement(&m_lCount) > 0)
  501. {
  502.     return m_lCount;
  503. }
  504. delete this;
  505. return 0;
  506.     }
  507. private:
  508.     LONG32 m_lCount;
  509.     CUnknownIMP* m_pobjAggregated;
  510.     CAggregateImpl(){}
  511.     CAggregateImpl(CAggregateImpl&) : IUnknown () {}
  512. };
  513. inline STDMETHODIMP
  514. CUnknownIMP::SetupAggregation( IUnknown* pvOuterObj, IUnknown** pvResult )
  515. {
  516.     if( !pvResult )
  517. return HXR_POINTER;
  518.     // Initial result code, initialize out parameter
  519.     HX_RESULT result = HXR_FAIL;
  520.     *pvResult = NULL;
  521.     // This can only happen before any calls to AddRef()
  522.     HX_ASSERT( 0 == m_lCount );
  523.     if( !m_lCount )
  524.     {
  525. if(pvOuterObj)
  526. {
  527.     m_punkOuter = pvOuterObj;
  528.     m_punkControlling = new CAggregateImpl( this );
  529.     m_punkControlling->AddRef();
  530.     result = HXR_OK;
  531. }
  532. else
  533. {
  534.     result = QueryInterface( IID_IUnknown, (void**) &m_punkControlling );
  535.     HX_ASSERT( SUCCEEDED( result ) );
  536. }
  537.     }
  538.     if( SUCCEEDED( result ) )
  539. *pvResult = m_punkControlling;
  540.     return result;
  541. }
  542. #define DECLARE_UNKNOWN(THIS_CLASS)
  543. DECLARE_COM_CREATE_FUNCS(THIS_CLASS)
  544.     public:
  545. STDMETHOD(QueryInterface)
  546. (
  547.     THIS_
  548.     REFIID riid,
  549.     void** ppvObj
  550. );
  551. STDMETHOD_(ULONG32, AddRef)(THIS);
  552. STDMETHOD_(ULONG32, Release)(THIS);
  553.     protected:
  554. STDMETHOD(_ActualQI)(REFIID riid, void** ppvObj);
  555.     public:
  556. #define DECLARE_UNKNOWN_NOCREATE(THIS_CLASS)
  557.     public:
  558. STDMETHOD(QueryInterface)
  559. (
  560.     THIS_
  561.     REFIID riid,
  562.     void** ppvObj
  563. );
  564. STDMETHOD_(ULONG32, AddRef)(THIS);
  565. STDMETHOD_(ULONG32, Release)(THIS);
  566.     protected:
  567. STDMETHOD(_ActualQI)(REFIID riid, void** ppvObj);
  568.     public:
  569. #define BEGIN_INTERFACE_LIST(THIS_CLASS)
  570. IMPLEMENT_COM_CREATE_FUNCS(THIS_CLASS)
  571. STDMETHODIMP THIS_CLASS::QueryInterface
  572. (
  573.     THIS_
  574.     REFIID riid,
  575.     void** ppvObj
  576. )
  577. {return CUnknownIMP::QueryInterface(riid, ppvObj);}
  578. STDMETHODIMP_(ULONG32) THIS_CLASS::AddRef(THIS)
  579. {return CUnknownIMP::AddRef();}
  580. STDMETHODIMP_(ULONG32) THIS_CLASS::Release(THIS)
  581. {return CUnknownIMP::Release();}
  582. STDMETHODIMP THIS_CLASS::_ActualQI(REFIID riid, void** ppvObj)
  583. {
  584.     if (!ppvObj)
  585. return HXR_POINTER;
  586.     if (IsEqualIID(IID_IUnknown, riid))
  587.     {
  588. AddRef();
  589. *ppvObj = CUnknownIMP::GetUnknown();
  590. return HXR_OK;
  591.     }
  592. #define BEGIN_INTERFACE_LIST_NOCREATE(THIS_CLASS)
  593. STDMETHODIMP THIS_CLASS::QueryInterface
  594. (
  595.     THIS_
  596.     REFIID riid,
  597.     void** ppvObj
  598. )
  599. {return CUnknownIMP::QueryInterface(riid, ppvObj);}
  600. STDMETHODIMP_(ULONG32) THIS_CLASS::AddRef(THIS)
  601. {return CUnknownIMP::AddRef();}
  602. STDMETHODIMP_(ULONG32) THIS_CLASS::Release(THIS)
  603. {return CUnknownIMP::Release();}
  604. STDMETHODIMP THIS_CLASS::_ActualQI(REFIID riid, void** ppvObj)
  605. {
  606.     if (!ppvObj)
  607. return HXR_POINTER;
  608.     if (IsEqualIID(IID_IUnknown, riid))
  609.     {
  610. AddRef();
  611. *ppvObj = CUnknownIMP::GetUnknown();
  612. return HXR_OK;
  613.     }
  614. #define INTERFACE_LIST_ENTRY(INTERFACE_IID, INTERFACE_CLASS)
  615.     if (IsEqualIID(INTERFACE_IID, riid))
  616.     {
  617. AddRef();
  618. INTERFACE_CLASS* pThisAsInterfaceClass = this;  
  619. *ppvObj = pThisAsInterfaceClass;
  620. return HXR_OK;
  621.     }
  622. /*!
  623.     @defined INTERFACE_LIST_ENTRY_BASE
  624.     @discussion Specifies a base class whose query interface function should be called.
  625. */
  626. #define INTERFACE_LIST_ENTRY_BASE( BASE_CLASS )
  627. if( SUCCEEDED( BASE_CLASS::_ActualQI( riid, ppvObj ) ) )
  628. {
  629.     return HXR_OK;
  630. }
  631. #define INTERFACE_LIST_ENTRY2(DERIVED_CLASS, BASE_INTERFACE_IID, BASE_CLASS)
  632.     if (IsEqualIID(BASE_INTERFACE_IID, riid))
  633.     {
  634. AddRef();
  635. DERIVED_CLASS* pTemp1 = this;
  636. BASE_CLASS* pTemp2 = pTemp1;
  637. *ppvObj = pTemp2;
  638. return HXR_OK;
  639.     }
  640. #define INTERFACE_LIST_ENTRY_DELEGATE_BLIND(DELEGATE_QI_FUNCTION)
  641.     if( SUCCEEDED( DELEGATE_QI_FUNCTION( riid, ppvObj ) ) )
  642.     {
  643. return HXR_OK;
  644.     }
  645. #define INTERFACE_LIST_ENTRY_DELEGATE(INTERFACE_IID, DELEGATE_QI_FUNCTION)
  646.     if(IsEqualIID(INTERFACE_IID, riid) &&
  647. SUCCEEDED( DELEGATE_QI_FUNCTION( riid, ppvObj ) ) )
  648.     {
  649. return HXR_OK;
  650.     }
  651. #define END_INTERFACE_LIST
  652.     *ppvObj = NULL;
  653.     return HXR_NOINTERFACE;
  654. }
  655. /*!
  656.     @defined END_INTERFACE_LIST_BASE
  657.     @discussion Ends the list of supported interfaces.  Specifies the base class whose
  658.     query interface function should be called.
  659. */
  660. #define END_INTERFACE_LIST_BASE( BASE_CLASS )
  661. return BASE_CLASS::_ActualQI( riid, ppvObj );
  662.     }                                                       
  663. #define DECLARE_COM_CREATE_FUNCS(CLASS)
  664.     public:
  665. static CLASS* CreateObject();
  666. static HX_RESULT CreateObject(CLASS** ppObj);
  667. static HX_RESULT CreateInstance(IUnknown** ppvObj);
  668. static HX_RESULT CreateInstance
  669. (
  670.     IUnknown* pvOuter,
  671.     IUnknown** ppvObj
  672. );
  673. #define IMPLEMENT_COM_CREATE_FUNCS(CLASS)
  674.     HX_RESULT CLASS::CreateObject(CLASS** ppObj)
  675.     {
  676. *ppObj = new CLASS;
  677. if (*ppObj)
  678. {
  679.     InterlockedIncrement(&((*ppObj)->m_lCount));
  680.     HX_RESULT pnrRes = (*ppObj)->FinalConstruct();
  681.     InterlockedDecrement(&((*ppObj)->m_lCount));
  682.     if (FAILED(pnrRes))
  683.     {
  684. delete (*ppObj);
  685. (*ppObj) = NULL;
  686. return pnrRes;
  687.     }
  688.     return HXR_OK;
  689. }
  690. return HXR_OUTOFMEMORY;    
  691.     }
  692.     CLASS* CLASS::CreateObject()
  693.     {
  694. CLASS* pNew = NULL;
  695. if (SUCCEEDED(CreateObject(&pNew)))
  696. {
  697.     return pNew;
  698. }
  699. return NULL;
  700.     }
  701.     HX_RESULT CLASS::CreateInstance
  702.     (
  703. IUnknown* pvOuterObj,
  704. IUnknown** ppvObj
  705.     )
  706.     {
  707. if (!ppvObj)
  708.     return HXR_POINTER;
  709. *ppvObj = NULL;
  710. CLASS* pNew = NULL;
  711. HX_RESULT pnrRes = CreateObject(&pNew);
  712. if (SUCCEEDED(pnrRes) && pNew)
  713. {
  714.     pnrRes = pNew->SetupAggregation( pvOuterObj, ppvObj );
  715. }
  716. return pnrRes;
  717.     }
  718.     HX_RESULT CLASS::CreateInstance(IUnknown** ppvObj)
  719.     {
  720. return CreateInstance(NULL, ppvObj);
  721.     }
  722.     
  723.     
  724. /*!
  725.     @defined IMPLEMENT_UNKNOWN_NOINTERFACE
  726.     @discussion This fills in implementations for AddRef() and Release()--basically forwards
  727.     calls onto CUnknownIMP.
  728. */
  729. #define IMPLEMENT_UNKNOWN_NOINTERFACE( THIS_CLASS )
  730.     STDMETHODIMP THIS_CLASS::QueryInterface( REFIID riid, void** ppvObj)                              
  731.     {                                                                                                           
  732. return CUnknownIMP::QueryInterface( riid, ppvObj );                                                      
  733.     }
  734.     STDMETHODIMP_(ULONG32) THIS_CLASS::AddRef(THIS) { return CUnknownIMP::AddRef(); }
  735.     STDMETHODIMP_(ULONG32) THIS_CLASS::Release(THIS) { return CUnknownIMP::Release(); }               
  736. /*!
  737.     @defined INTERFACE_LIST_ENTRY_SIMPLE
  738.     @discussion Simplified version of INTERFACE_LIST_ENTRY.  Only takes the interface
  739.     name.  The IID is assumed to be the interface name with 'IID_' prepended.
  740. */
  741. #define INTERFACE_LIST_ENTRY_SIMPLE( INTERFACE_CLASS )
  742. INTERFACE_LIST_ENTRY( IID_##INTERFACE_CLASS, INTERFACE_CLASS )                                        
  743. /*!
  744.     @defined INTERFACE_LIST_ENTRY_SIMPLE2
  745.     @discussion This allows an interface to appear in an interface list 
  746.       even when the conversion to it is ambiguous owing to multiple 
  747.       inheritence. By specifying an intermediate interface the conversion 
  748.       is disambiguated.
  749.       This is the simplified version of INTERFACE_LIST_ENTRY2. Only takes 
  750.       the interface names.  The IID are assumed to be the interface names 
  751.       with 'IID_' prepended.
  752. */
  753. #define INTERFACE_LIST_ENTRY_SIMPLE2( DERIVED_CLASS, BASE_CLASS )
  754. INTERFACE_LIST_ENTRY2( DERIVED_CLASS, IID_##BASE_CLASS, BASE_CLASS )                                        
  755. /*!
  756.     @defined INTERFACE_LIST_ENTRY_TESTPOINTER
  757. */
  758. #define INTERFACE_LIST_ENTRY_MEMBER( INTERFACE_IID, MEMBER_VARIABLE )
  759. if( NULL != ( MEMBER_VARIABLE ) )
  760. {                                                                                               
  761.     if( IsEqualIID( INTERFACE_IID, riid ) )                                                     
  762.     {                                                                                           
  763. if( SUCCEEDED( MEMBER_VARIABLE->QueryInterface( riid, ppvObj ) ) )                      
  764.     return HXR_OK;                                                                      
  765.     }                                                                                           
  766. }                                                                                               
  767. /*!
  768.     @defined INTERFACE_LIST_ENTRY_TESTPOINTER
  769. */
  770. #define INTERFACE_LIST_ENTRY_MEMBER_BLIND( MEMBER_VARIABLE )
  771. if( NULL != ( MEMBER_VARIABLE ) )
  772. {                                                                                               
  773.     if( SUCCEEDED( MEMBER_VARIABLE->QueryInterface( riid, ppvObj ) ) )                      
  774. return HXR_OK;                                                                      
  775. }                                                                                               
  776. #endif //!__CUnknownIMP_H__