unkimp.h
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:24k
源码类别:

Symbian

开发平台:

Visual C++

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