enum.cpp
上传用户:xhy777
上传日期:2007-02-14
资源大小:24088k
文件大小:13k
源码类别:

系统编程

开发平台:

Visual C++

  1. //-------------------------------------------------------------------------//
  2. //  Enum.cpp
  3. //-------------------------------------------------------------------------//
  4. #include "pch.h"
  5. #include "PTsrv32.h"
  6. #include "Enum.h"
  7. #include "DefProp.h"
  8. #include "MruProp.h"
  9. #include "DefSrv32.h"
  10. //-------------------------------------------------------------------------//
  11. //  Standard IUnknown implementation:
  12. #define IMPLEMENT_ENUM_UNKNOWN( classname, iid ) 
  13.     ULONG classname::m_cObj = 0 ; 
  14.     STDMETHODIMP classname::QueryInterface( REFIID _iid, void** ppvObj ) { 
  15.         if( ppvObj == NULL ) return E_POINTER ; *ppvObj = NULL ; 
  16.         if( IsEqualGUID( _iid, IID_IUnknown ) )   *ppvObj = this ; 
  17.         else if( IsEqualGUID( _iid, iid ) ) *ppvObj = this ; 
  18.         if( *ppvObj )    { AddRef() ; return S_OK ;  } 
  19.         return E_NOINTERFACE ; } 
  20.     STDMETHODIMP_( ULONG ) classname::AddRef() { 
  21.         if( InterlockedIncrement( (LONG*)&m_cRef )==1 )  
  22.             _Module.Lock() ; 
  23.         return m_cRef ; } 
  24.     STDMETHODIMP_( ULONG ) classname::Release() { 
  25.         if( InterlockedDecrement( (LONG*)&m_cRef )==0 ) 
  26.             { _Module.Unlock() ; delete this ; return 0 ; } 
  27.         return m_cRef ;  } 
  28. //-------------------------------------------------------------------------//
  29. // CEnumFolderItem
  30. //-------------------------------------------------------------------------//
  31. //-------------------------------------------------------------------------//
  32. CEnumFolderItem::CEnumFolderItem( CPropertySource* pSrc )
  33.     :   m_iPos(0),
  34.         m_pEnumSpecialized(NULL),
  35.         m_cMax(DefFolderCount()),
  36.         m_cRef(0),
  37.         m_pSrc( pSrc )
  38. {
  39.     ASSERT( m_pSrc ) ;
  40.     //  Contain specialized enumerator, if any.
  41.     IAdvancedPropertyServer* pSpecialized ;
  42.     LPARAM lParamSpecialized ;
  43.     if( (pSpecialized = m_pSrc->GetSpecializedServer( &lParamSpecialized )) )
  44.         pSpecialized->EnumFolderItems( lParamSpecialized, &m_pEnumSpecialized ) ;
  45. }
  46. IMPLEMENT_ENUM_UNKNOWN( CEnumFolderItem, IID_IEnumPROPFOLDERITEM ) ;
  47. //-------------------------------------------------------------------------//
  48. STDMETHODIMP CEnumFolderItem::Next( ULONG cItems, PROPFOLDERITEM * rgFolderItem, ULONG * pcItemsFetched )
  49. {
  50.     if( !( pcItemsFetched && rgFolderItem ) ) 
  51.         return E_POINTER ;
  52.     *pcItemsFetched = 0 ;
  53.     //  If we have a specialized server, give him a crack
  54.     if( m_pEnumSpecialized )
  55.     {
  56.         if( SUCCEEDED( m_pEnumSpecialized->Next( cItems, rgFolderItem, pcItemsFetched ) ) )
  57.         {
  58.             //  we need to hijack his data cookie...
  59.             for( ULONG i = 0; i< *pcItemsFetched; i++ )
  60.                 rgFolderItem[i].lParam = (LPARAM)m_pSrc ;
  61.         }
  62.     }
  63.     //  Do our own thing
  64.     while( *pcItemsFetched < cItems && m_iPos < m_cMax )
  65.     {
  66.         HRESULT hr ;
  67.         if( m_pSrc->UsesFolder( m_iPos ) )
  68.         {
  69.             if( SUCCEEDED( (hr = MakeDefFolderItem( m_iPos, &rgFolderItem[*pcItemsFetched], (LPARAM)m_pSrc )) ) )
  70.                 (*pcItemsFetched)++ ;
  71.         }
  72.         InterlockedIncrement( &m_iPos ) ;
  73.     }
  74.     return cItems == *pcItemsFetched ? S_OK : S_FALSE ;
  75. }
  76. //-------------------------------------------------------------------------//
  77. STDMETHODIMP CEnumFolderItem::Reset()
  78. {
  79.     if( m_pEnumSpecialized )
  80.         m_pEnumSpecialized->Reset() ;
  81. InterlockedExchange( &m_iPos, 0 ) ;
  82.     return S_OK;
  83. }
  84. //-------------------------------------------------------------------------//
  85. const CEnumFolderItem& CEnumFolderItem::operator=( const CEnumFolderItem& src )
  86. {
  87.     if( &src==this ) 
  88.         return *this ;
  89.     InterlockedExchange( &m_iPos, src.m_iPos ) ;
  90.     InterlockedExchange( &m_cMax, src.m_cMax ) ;
  91.     return *this ;
  92. }
  93. //-------------------------------------------------------------------------//
  94. // CEnumPropertyItem
  95. //-------------------------------------------------------------------------//
  96. IMPLEMENT_ENUM_UNKNOWN( CEnumPropertyItem, IID_IEnumPROPERTYITEM ) ;
  97. //-------------------------------------------------------------------------//
  98. CEnumPropertyItem::CEnumPropertyItem( CPropertySource* pSrc, const PROPFOLDERITEM* pFolder )
  99.     :   m_cRef(0),
  100.         m_hIterator(NULL),
  101.         m_pEnumSpecialized(NULL),
  102.         m_pfid(pFolder->pfid),
  103.         m_pSrc( pSrc ),
  104.         m_bEnumSpecialized(FALSE)
  105. {
  106.     ASSERT( pSrc ) ;
  107.     //  Contain specialized enumerator, if any.
  108.     IAdvancedPropertyServer* pSpecialized ;
  109.     LPARAM lParamSpecialized ;
  110.     if( (pSpecialized = m_pSrc->GetSpecializedServer( &lParamSpecialized )) )
  111.     {
  112.         ((PROPFOLDERITEM*)pFolder)->lParam = lParamSpecialized ;
  113.         m_bEnumSpecialized = S_OK == pSpecialized->EnumPropertyItems( pFolder, &m_pEnumSpecialized ) ;
  114.         ((PROPFOLDERITEM*)pFolder)->lParam = (LPARAM)pSrc ;
  115.     }
  116. }
  117. //-------------------------------------------------------------------------//
  118. CEnumPropertyItem::~CEnumPropertyItem()
  119. {
  120.     Reset() ;
  121. }
  122. //-------------------------------------------------------------------------//
  123. BOOL CEnumPropertyItem::Iterate( OUT PROPERTYITEM& propitem )
  124. {
  125.     CPropertyMap& map = m_pSrc->PropertyMap() ;
  126.     if( m_hIterator )
  127.         return map.LookupNext( m_hIterator, propitem ) ;
  128.     if( (m_hIterator = map.LookupFirst( CPropertyMap::iFolderID, &m_pfid, propitem ))==NULL )
  129.         return FALSE ;
  130.     
  131.     return TRUE ;
  132. }
  133. //-------------------------------------------------------------------------//
  134. STDMETHODIMP CEnumPropertyItem::Next( 
  135.     ULONG cItems, 
  136.     PROPERTYITEM * rgPropertyItem, 
  137.     ULONG * pcItemsFetched )
  138. {
  139.     if( !( pcItemsFetched && rgPropertyItem ) ) 
  140.         return E_POINTER ;
  141.     *pcItemsFetched = 0 ;
  142.     //  If we have a specialized server, give him a crack
  143.     if( m_pEnumSpecialized && m_bEnumSpecialized )
  144.     {
  145.         HRESULT hr = m_pEnumSpecialized->Next( cItems, rgPropertyItem, pcItemsFetched ) ;
  146.         if( SUCCEEDED( hr ) )
  147.         {
  148.             for( ULONG i = 0; i< *pcItemsFetched; i++ )
  149.             {
  150.                 //  If the specialized server is serving up a property that
  151.                 //  we were ready to supply, remove our own version.
  152.                 CPropertyMap& map = m_pSrc->PropertyMap() ;
  153.                 if( map.Exists( CPropertyMap.iShColID, (SHCOLUMNID*)&rgPropertyItem[i].puid ) )
  154.                 {
  155.                     ASSERT( NULL == m_hIterator ) ; // don't delete unless we know we're reset.
  156.                     map.Delete( CPropertyMap.iShColID, (SHCOLUMNID*)&rgPropertyItem[i].puid ) ;
  157.                 }
  158.                 
  159.                 //  hijack his data cookie...
  160.                 rgPropertyItem[i].lParam = (LPARAM)m_pSrc ;
  161.             }
  162.         }
  163.         else
  164.             m_bEnumSpecialized = FALSE ;    // no need to ask again.
  165.     }
  166.     while( *pcItemsFetched < cItems )
  167.     {
  168.         if( Iterate( rgPropertyItem[*pcItemsFetched] ) )
  169.             (*pcItemsFetched)++ ;
  170.         else
  171.             break ;
  172.     }
  173.     return cItems == *pcItemsFetched ? S_OK : S_FALSE ;
  174. }
  175. //-------------------------------------------------------------------------//
  176. STDMETHODIMP CEnumPropertyItem::Reset()
  177. {
  178.     if( m_pEnumSpecialized )
  179.     {
  180.         m_pEnumSpecialized->Reset() ;
  181.         m_bEnumSpecialized = TRUE ;
  182.     }
  183.     
  184.     if( m_hIterator )
  185.     {
  186.         CPropertyMap& map = m_pSrc->PropertyMap() ;
  187.         map.EndLookup( m_hIterator ) ;
  188.         m_hIterator = NULL ;
  189.     }
  190.     return S_OK;
  191. }
  192. //-------------------------------------------------------------------------//
  193. const CEnumPropertyItem& CEnumPropertyItem::operator= ( const CEnumPropertyItem& src )
  194. {
  195.     if( &src == this )
  196.         return src ;
  197.     m_pfid = src.m_pfid ;
  198.     m_pSrc = src.m_pSrc ;
  199.     return *this ;
  200. }
  201. //-------------------------------------------------------------------------//
  202. // CEnumMruValues
  203. //-------------------------------------------------------------------------//
  204. IMPLEMENT_ENUM_UNKNOWN( CEnumMruValues, IID_IEnumPROPVARIANT_DISPLAY ) ;
  205. //-------------------------------------------------------------------------//
  206. CEnumMruValues::CEnumMruValues( const tagPUID& puid )
  207.     :   m_puid(puid),
  208.         m_iPos(0), 
  209.         m_cMax(0),
  210.         m_cRef(0)
  211. {
  212.     for( int i=0; i<5; i++ )
  213.     {
  214.         PROPVARIANT v ;
  215.         ULONG       dwHash = 0 ;
  216.         v.vt = VT_LPSTR ;
  217.         v.pszVal = "Scott Hanggie" ;
  218.         PropVariantHash( v, dwHash ) ;
  219.     }
  220. }
  221. //-------------------------------------------------------------------------//
  222. const CEnumMruValues& CEnumMruValues::operator= ( const CEnumMruValues& src )
  223. {
  224.     if( this != &src )
  225.     {
  226.         m_puid      = src.m_puid ;
  227.         m_iPos      = src.m_iPos ;
  228.         m_cMax      = src.m_cMax ;
  229.     }
  230.     return *this ;
  231. }
  232. //-------------------------------------------------------------------------//
  233. STDMETHODIMP CEnumMruValues::Next( ULONG cItems, PROPVARIANT_DISPLAY * rgVar, ULONG * pcItemsFetched )
  234. {
  235.     CPropMruStor stor( PTREGROOTKEY, PTREGSUBKEY ) ;
  236.     HRESULT      hr ;
  237.     long         iStart = m_iPos ;
  238.     
  239.     if( !( pcItemsFetched && rgVar ) ) 
  240.         return E_POINTER ;
  241.     *pcItemsFetched = 0 ;
  242.     if( !SUCCEEDED( (hr = stor.BeginFetch( m_puid.fmtid, m_puid.propid, m_puid.vt )) ) )
  243.         return S_FALSE ;
  244.     m_cMax = stor.IndexCount() ;
  245.     if( m_iPos >= m_cMax )
  246.         return S_FALSE ;
  247.     for( hr = stor.FetchNext( m_iPos, rgVar[m_iPos - iStart] ) ;
  248.          SUCCEEDED( hr ) ; )
  249.     {
  250.         if( ++(*pcItemsFetched) >= cItems ) 
  251.             break ;
  252.         hr = stor.FetchNext( m_iPos, rgVar[m_iPos - iStart] ) ;
  253.     }
  254.     return cItems == *pcItemsFetched ? S_OK : S_FALSE ;
  255. }
  256. //-------------------------------------------------------------------------//
  257. STDMETHODIMP CEnumMruValues::Reset()
  258. {
  259.     InterlockedExchange( &m_iPos, 0 ) ;
  260.     return S_OK;
  261. }
  262. //-------------------------------------------------------------------------//
  263. // CEnumHardValues
  264. //-------------------------------------------------------------------------//
  265. IMPLEMENT_ENUM_UNKNOWN( CEnumHardValues, IID_IEnumPROPVARIANT_DISPLAY ) ;
  266. //-------------------------------------------------------------------------//
  267. CEnumHardValues::CEnumHardValues( const DEFVAL* pVals, int cVals )
  268.     : m_cMax( cVals ),
  269.       m_iPos(0),
  270.       m_pVals( pVals )
  271. {
  272. }
  273. //-------------------------------------------------------------------------//
  274. CEnumHardValues::~CEnumHardValues()
  275. {
  276. }
  277. //-------------------------------------------------------------------------//
  278. STDMETHODIMP CEnumHardValues::Next( 
  279.     ULONG cItems,
  280.     PROPVARIANT_DISPLAY * rgVar, 
  281.     ULONG * pcItemsFetched )
  282. {
  283.     if( !( pcItemsFetched && rgVar ) ) 
  284.         return E_POINTER ;
  285.     *pcItemsFetched = 0 ;
  286.     if( m_iPos >= m_cMax )
  287.         return S_FALSE ;
  288.     for( long iStart = m_iPos ;
  289.          m_iPos < min( m_cMax, iStart + (long)cItems ); )
  290.     {
  291.         InitPropVariantDisplay( &rgVar[m_iPos-iStart] ) ;
  292.         //  BUGBUG: the following line is type-unsafe, and works only for simple VARTYPES.
  293.         //  Guaranteed to fail for pointer, string and array types.
  294.         //  Need to shore up at least the string types, and implement string resource loading.
  295.         PropVariantCopy( &rgVar[m_iPos-iStart].val, (PROPVARIANT*)&m_pVals[m_iPos] ) ;
  296.         //  Allocate display string, if any.
  297.         if( 0L != m_pVals[m_iPos].lpDisplay )
  298.         {
  299.             if( m_pVals[m_iPos].fDisplayStrRes )
  300.             {
  301.                 WCHAR wszDisplay[MAX_PATH+1] ;
  302.                 if( LoadStringW( _Module.GetModuleInstance(), (UINT)m_pVals[m_iPos].lpDisplay,
  303.                                  wszDisplay, sizeof(wszDisplay)/sizeof(WCHAR) ) )
  304.                 {
  305.                     rgVar[m_iPos - iStart].bstrDisplay = SysAllocString( wszDisplay ) ;
  306.                 }
  307.             }
  308.             else
  309.             {
  310.                 USES_CONVERSION ;
  311.                 rgVar[m_iPos - iStart].bstrDisplay = 
  312.                     SysAllocString( T2W( (LPTSTR)m_pVals[m_iPos].lpDisplay ) ) ;
  313.             }
  314.         }
  315.         (*pcItemsFetched)++ ;
  316.         InterlockedIncrement( &m_iPos ) ;
  317.     }
  318.     return cItems == *pcItemsFetched ? S_OK : S_FALSE ;
  319. }
  320. //-------------------------------------------------------------------------//
  321. STDMETHODIMP CEnumHardValues::Reset()
  322. {
  323.     InterlockedExchange( &m_iPos, 0 ) ;
  324.     return S_OK;
  325. }
  326. //-------------------------------------------------------------------------//
  327. const CEnumHardValues& CEnumHardValues::operator=( const CEnumHardValues& src )
  328. {
  329.     if( &src==this ) 
  330.         return *this ;
  331.     InterlockedExchange( &m_iPos, src.m_iPos ) ;
  332.     InterlockedExchange( &m_cMax, src.m_cMax ) ;
  333.     m_pVals = src.m_pVals ;
  334.     return *this ;
  335. }