home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / mac / SiteBldr / AMOVIE / SDK / _SETUP / COMMON.Z / ext_enum.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-02  |  7.7 KB  |  244 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11. //
  12. // Ext_Enum.h
  13. //
  14. //
  15. // Contents:
  16. //
  17.  
  18. #ifndef _Ext_Enum_h
  19. #define _Ext_Enum_h
  20.  
  21. #pragma warning( disable : 4514 )
  22.  
  23. // A helper template & macro so that we only release non-null interface
  24. // pointers and we set the pointer to null afterwards so that we don't 
  25. // release it again.
  26. template<class Interface> void SafeRelPtrIPtr( Interface * * ppIUnk )
  27. {
  28.     if ( *ppIUnk )
  29.     {
  30.         (*ppIUnk)->Release();
  31.         (*ppIUnk) = 0;
  32.     }
  33. }
  34.  
  35. #define SafeRelIPtr( pI ) SafeRelPtrIPtr( &(pI) )
  36.  
  37. // A template function for cloning.  We always clone an Implementation, but
  38. // supply a pointer to an Interface.  We need both to parameterize this function.
  39. template<class Implementation, class Interface> 
  40. static inline HRESULT CloneAny( const Implementation & _this, Interface ** ppI)
  41.     HRESULT hr;
  42.  
  43.     if (ppI)
  44.     {
  45.         *ppI = 0;
  46.         // Relies on Implementation having defined this kind of "copy" constructor.
  47.         Implementation *const p = new Implementation( _this, &hr );
  48.         if (p)
  49.         {
  50.             if SUCCEEDED(hr)    *ppI = p;
  51.             else                delete p;
  52.         }
  53.         else hr = E_OUTOFMEMORY;
  54.     }
  55.     else hr = E_POINTER;
  56.     return hr;
  57. }
  58.  
  59. // AnyEnum presents a simple concrete class that can cover any enumerator that conforms to
  60. // the standard COM enumerator interface.  You'll probably never instantiate one of these,
  61. // but it gives us a good foundation from which to build derived enumerators with special
  62. // behaviour.
  63.  
  64. template<class IEnum, class BaseType> class AnyEnum : public IEnum
  65. {
  66. protected:
  67.     long    m_cRef;                             // Local ref count
  68.     IEnum * m_pIEnum;                           // Pointer to a "real" enumarator that will do most of the work
  69.  
  70.     // Protected default constructor, derived classes relying on this must set m_pIEnum themselves.
  71.     AnyEnum()                                   : m_cRef(1), m_pIEnum(0)  {}
  72.  
  73. public:
  74.     virtual ~AnyEnum()                          { SafeRelIPtr( m_pIEnum ); } 
  75.     AnyEnum( const AnyEnum & copy, HRESULT * phr );
  76.  
  77.     // IUnknown interface
  78.     STDMETHODIMP            QueryInterface( REFIID iid, void ** ppv );
  79.     STDMETHODIMP_(ULONG)    AddRef();
  80.     STDMETHODIMP_(ULONG)    Release();
  81.  
  82.     // IEnum interface 
  83.     STDMETHODIMP            Next( ULONG cBase, BaseType ** ppBase, ULONG * pcFetched );
  84.     STDMETHODIMP            Skip( ULONG cBase );
  85.     STDMETHODIMP            Reset( void );
  86.     STDMETHODIMP            Clone( IEnum ** ppEnum );
  87. };
  88.  
  89.  
  90. // ConstrictedEnum
  91. //
  92. // An abstract template class extending AnyEnum by adding a Select() method.
  93. // Derived classes must implement this method.  For each object that our inner
  94. // enumerator passes back to us, we ask Select() if it meets its selection 
  95. // criteria, if it does, we pass the object back to our caller, otherwise we
  96. // ask our inner enumerator for another candidate.
  97. //
  98. // Next() is enhanced to call Select() for each candidate.  Skip() is re-implemented
  99. // since its skip count must now be in terms of objects that meet Select()'s criteria.
  100. // A new Skip() is implemented where we can explicity get a count of the number of
  101. // candidates skipped.
  102.  
  103. template<class IEnum, class BaseType> class ConstrictedEnum : public AnyEnum<IEnum,BaseType>
  104. {
  105. protected:
  106.     ConstrictedEnum()                       {}
  107.  
  108.     // Pure virtual Selector method.
  109.     virtual BOOL Select( BaseType ** ppBase ) =0;
  110.  
  111. public:
  112.     ConstrictedEnum( const ConstrictedEnum & copy, HRESULT * phr )
  113.     : AnyEnum<IEnum,BaseType>( copy, phr )  {}
  114.  
  115.     STDMETHODIMP            Next( ULONG cBase, BaseType ** ppBase, ULONG * pcFetched );
  116.     STDMETHODIMP            Skip( ULONG cBase );
  117.     STDMETHODIMP            Skip( ULONG cBase, ULONG * pcCount );
  118. };
  119.  
  120.  
  121. // CImpIEnumFilters
  122. //
  123. // This class not only restricts ennumeration to IFilters that support a specific interface,
  124. // it also returns pointers to THAT interface, rather than just IFilter pointers.
  125.  
  126. class CImpIEnumFilters : public ConstrictedEnum<IEnumFilters, IFilter> 
  127. {
  128. private:
  129.     REFIID    m_iid;
  130.  
  131. protected:
  132.     CImpIEnumFilters( REFIID iid )                  : m_iid(iid)                {}
  133.     BOOL    Select( IFilter ** ppIFilter );
  134.  
  135. public:
  136.     CImpIEnumFilters( const CImpIEnumFilters & copy, HRESULT * phr )
  137.     : ConstrictedEnum<IEnumFilters,IFilter>( copy, phr ), m_iid( copy.m_iid )   {}
  138.  
  139.     CImpIEnumFilters( IFilterGraph * pIFilterGraph, REFIID iid )
  140.     : m_iid(iid)
  141.     {
  142.         HRESULT hr = pIFilterGraph->EnumFilters( &m_pIEnum );
  143.         ASSERT( SUCCEEDED(hr) );
  144.     }
  145.  
  146.     STDMETHODIMP Clone( IEnumFilters  ** ppEnum );
  147. };
  148.  
  149.  
  150. // CImpIEnumUnconnectedFilters
  151. //
  152. // Enumerates filters over a filter graph, but only returns those who have none of their pins connected
  153.  
  154. class CImpIEnumUnconnectedFilters : public ConstrictedEnum<IEnumFilters, IFilter> 
  155. {
  156. protected:
  157.     BOOL    Select( IFilter ** ppIFilter );
  158.  
  159. public:
  160.     CImpIEnumUnconnectedFilters( const CImpIEnumUnconnectedFilters & copy, HRESULT * phr )
  161.     : ConstrictedEnum<IEnumFilters,IFilter>( copy, phr ) {}
  162.  
  163.     CImpIEnumUnconnectedFilters( IFilterGraph * pIFilterGraph )
  164.     {
  165.         HRESULT hr = pIFilterGraph->EnumFilters( &m_pIEnum );
  166.         ASSERT( SUCCEEDED(hr) );
  167.     }
  168.  
  169.     STDMETHODIMP Clone( IEnumFilters  ** ppEnum );
  170. };
  171.  
  172.  
  173. template<PIN_DIRECTION DIR> class CImpIEnumPins : public ConstrictedEnum<IEnumPins, IPin> 
  174. {
  175. protected:
  176.     CImpIEnumPins()                                                 {}
  177.     BOOL    Select( IPin ** ppIPin );
  178.  
  179. public:
  180.     CImpIEnumPins( const CImpIEnumPins & copy, HRESULT * phr )
  181.     : ConstrictedEnum<IEnumPins, IPin>( copy, phr )                 {}
  182.  
  183.     CImpIEnumPins( IFilter * pIFilter )
  184.     {
  185.         HRESULT hr = pIFilter->EnumPins( &m_pIEnum );
  186.         ASSERT ( SUCCEEDED(hr) );
  187.     }
  188.  
  189.     STDMETHODIMP Clone( IEnumPins  ** ppEnum );
  190. };
  191.  
  192. typedef CImpIEnumPins<PINDIR_INPUT>     CImpIEnumPinsIn;
  193. typedef CImpIEnumPins<PINDIR_OUTPUT>    CImpIEnumPinsOut;
  194. typedef AnyEnum<IEnumPins, IPin>        CImpIEnumPinsBoth;
  195.  
  196. template<class EnumPinClass> class CImpIEnumOverGraph : public EnumPinClass
  197. {
  198. private:
  199.     CImpIEnumOverGraph()            {}
  200. protected:
  201.     HRESULT         m_hr;
  202.     IEnumFilters    * m_pIEnumFilters;
  203.     CCritSec        m_crit_sec;
  204.  
  205.  
  206.     HRESULT NextFilter();           // Iterates us through the filters
  207.  
  208. public:
  209.     ~CImpIEnumOverGraph()           { SafeRelIPtr(m_pIEnumFilters); }
  210.  
  211.     CImpIEnumOverGraph( const CImpIEnumOverGraph & copy, HRESULT * phr )
  212.     : EnumPinClass( copy, phr )
  213.     {
  214.         if SUCCEEDED(*phr)
  215.         {
  216.             *phr = copy.m_pIEnumFilters->Clone( &m_pIEnumFilters );
  217.             m_hr = SUCCEEDED(*phr) ? copy.m_hr : *phr;
  218.         }
  219.         else m_pIEnumFilters = 0;
  220.     }
  221.  
  222.     CImpIEnumOverGraph( IFilterGraph * pIFilterGraph )
  223.     {
  224.         HRESULT hr;
  225.         hr = pIFilterGraph->EnumFilters( &m_pIEnumFilters );
  226.         ASSERT( SUCCEEDED(hr) );
  227.         hr = NextFilter();
  228.         ASSERT( SUCCEEDED(hr) );
  229.     }
  230.  
  231.     STDMETHODIMP Next( ULONG cBase, IPin ** ppBase, ULONG * pcFetched );
  232.     STDMETHODIMP Reset( void );
  233.     STDMETHODIMP Clone( IEnumPins ** ppEnum );
  234. };
  235.  
  236.  
  237. typedef CImpIEnumOverGraph<CImpIEnumPinsIn>     CImpIEnumPinsInOverGraph;
  238. typedef CImpIEnumOverGraph<CImpIEnumPinsOut>    CImpIEnumPinsOutOverGraph;
  239. typedef CImpIEnumOverGraph<CImpIEnumPinsBoth>   CImpIEnumPinsOverGraph;
  240.  
  241. #include "Ext_Enum.inl"
  242.  
  243. #endif