Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1139 lines
31 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File:
  4. // enumerators.cpp
  5. //
  6. // Contents:
  7. // Enumerators implementation
  8. //
  9. // Classes:
  10. // CStatData - STATDATA class with methods suitable for
  11. // embedding in the place holder object
  12. // CEnumStatData - STATDATA Enumerator
  13. // CFormatEtc - FORMATETC class with methods suitable for
  14. // embedding in the place holder object
  15. // CEnumFormatEtc - FORMATETC Enumerator
  16. //
  17. // History:
  18. // Gopalk Creation Sep 04, 96
  19. //
  20. //-----------------------------------------------------------------------------
  21. #include <le2int.h>
  22. #include "enumtors.h"
  23. //+----------------------------------------------------------------------------
  24. //
  25. // Member:
  26. // CStatData::CStatData, public
  27. //
  28. // Synopsis:
  29. // Constructor
  30. //
  31. // Arguments:
  32. // [foretc] [in] -- FormatEtc
  33. // [dwAdvf] [in] -- Advise Flags
  34. // [pAdvSink] [in] -- Advise Sink
  35. // [dwConnection] [in] -- Connection ID
  36. //
  37. // History:
  38. // Gopalk Creation Sep 04, 96
  39. //
  40. //-----------------------------------------------------------------------------
  41. CStatData::CStatData(FORMATETC* foretc, DWORD dwAdvf, IAdviseSink* pAdvSink,
  42. DWORD dwConnID)
  43. {
  44. // validation check
  45. // Initialize
  46. m_ulFlags = 0;
  47. m_dwAdvf = dwAdvf;
  48. if(pAdvSink && IsValidInterface(pAdvSink)) {
  49. m_pAdvSink = pAdvSink;
  50. m_pAdvSink->AddRef();
  51. }
  52. else
  53. m_pAdvSink = NULL;
  54. m_dwConnID = dwConnID;
  55. // Copy the FormatEtc
  56. if(!UtCopyFormatEtc(foretc, &m_foretc))
  57. m_ulFlags |= SDFLAG_OUTOFMEMORY;
  58. }
  59. //+----------------------------------------------------------------------------
  60. //
  61. // Member:
  62. // CStatData::~CStatData, public
  63. //
  64. // Synopsis:
  65. // Destructor
  66. //
  67. // Arguments:
  68. //
  69. // History:
  70. // Gopalk Creation Sep 04, 96
  71. //
  72. //-----------------------------------------------------------------------------
  73. CStatData::~CStatData()
  74. {
  75. // Release the advise sink
  76. if(m_pAdvSink)
  77. m_pAdvSink->Release();
  78. // Delete the ptd if it is non-null
  79. if(m_foretc.ptd)
  80. PubMemFree(m_foretc.ptd);
  81. }
  82. //+----------------------------------------------------------------------------
  83. //
  84. // Member:
  85. // CStatData::operator=, public
  86. //
  87. // Synopsis:
  88. // Equality operator
  89. //
  90. // Arguments:
  91. // rStatData [in] - The RHS value
  92. //
  93. // History:
  94. // Gopalk Creation Sep 04, 96
  95. //
  96. //-----------------------------------------------------------------------------
  97. const CStatData& CStatData::operator=(const CStatData& rStatData)
  98. {
  99. // Check to see, if this a=a case
  100. if(this==&rStatData)
  101. return(*this);
  102. // Self destroy
  103. CStatData::~CStatData();
  104. // Initialize
  105. m_ulFlags = 0;
  106. m_dwAdvf = rStatData.m_dwAdvf;
  107. m_pAdvSink = rStatData.m_pAdvSink;
  108. if(m_pAdvSink)
  109. m_pAdvSink->AddRef();
  110. m_dwConnID = rStatData.m_dwConnID;
  111. // Copy the FormatEtc
  112. if(!UtCopyFormatEtc((LPFORMATETC) &rStatData.m_foretc, &m_foretc))
  113. m_ulFlags |= SDFLAG_OUTOFMEMORY;
  114. return(*this);
  115. }
  116. //+----------------------------------------------------------------------------
  117. //
  118. // Member:
  119. // CEnumStatData::CreateEnumStatData, public
  120. //
  121. // Synopsis:
  122. // A static member functions that creates a properly constructed
  123. // StatData Enumerator given the cachenode array of the cache
  124. //
  125. // Arguments:
  126. // [pCacheArray] [in] -- Array of CacheNode maintained by COleCache
  127. //
  128. // Returns:
  129. // Pointer to a properly constructed cache enumerator interface
  130. // NULL otherwise.
  131. //
  132. // History:
  133. // Gopalk Creation Sep 04, 96
  134. //
  135. //-----------------------------------------------------------------------------
  136. LPENUMSTATDATA CEnumStatData::CreateEnumStatData(CArray<CCacheNode>* pCacheArray)
  137. {
  138. CEnumStatData* EnumStatData = new CEnumStatData(pCacheArray);
  139. if(EnumStatData && !(EnumStatData->m_ulFlags & CENUMSDFLAG_OUTOFMEMORY))
  140. return ((IEnumSTATDATA *) EnumStatData);
  141. if(EnumStatData)
  142. EnumStatData->Release();
  143. return(NULL);
  144. }
  145. //+----------------------------------------------------------------------------
  146. //
  147. // Member:
  148. // CEnumStatData::CEnumStatData, private
  149. //
  150. // Synopsis:
  151. // Constructor
  152. //
  153. // Arguments:
  154. // [pCacheArray] [in] -- Array of CacheNode maintained by COleCache
  155. //
  156. // History:
  157. // Gopalk Creation Sep 04, 96
  158. //
  159. //-----------------------------------------------------------------------------
  160. CEnumStatData::CEnumStatData(CArray<CCacheNode>* pCacheArray)
  161. {
  162. // Local variables
  163. ULONG i, CNindex, SDindex;
  164. LPCACHENODE lpCacheNode;
  165. CStatData* pStatData;
  166. // Initilaize
  167. m_ulFlags = 0;
  168. m_refs = 1;
  169. // Create the StatData array
  170. m_pSDArray = CArray<CStatData>::CreateArray(pCacheArray->Length());
  171. if(m_pSDArray) {
  172. // Enumerate the cache nodes
  173. pCacheArray->Reset(CNindex);
  174. for(i=0;i<pCacheArray->Length();i++) {
  175. // Get the next cache node
  176. lpCacheNode = pCacheArray->GetNext(CNindex);
  177. // pCacheNode cannot be null
  178. Win4Assert(lpCacheNode);
  179. // Create a StatData object representing the cachenode
  180. CStatData StatData((FORMATETC *)lpCacheNode->GetFormatEtc(),
  181. lpCacheNode->GetAdvf(), NULL, CNindex);
  182. if(StatData.m_ulFlags & SDFLAG_OUTOFMEMORY) {
  183. m_ulFlags |= CENUMSDFLAG_OUTOFMEMORY;
  184. break;
  185. }
  186. // Add the StatData object to the array
  187. SDindex = m_pSDArray->AddItem(StatData);
  188. if(SDindex) {
  189. // Get the newly added StatData object
  190. pStatData = m_pSDArray->GetItem(SDindex);
  191. Win4Assert(pStatData);
  192. if(pStatData->m_ulFlags & SDFLAG_OUTOFMEMORY) {
  193. m_ulFlags |= CENUMSDFLAG_OUTOFMEMORY;
  194. break;
  195. }
  196. }
  197. else {
  198. m_ulFlags |= CENUMSDFLAG_OUTOFMEMORY;
  199. break;
  200. }
  201. // Check if cachenode format is CF_DIB
  202. if(lpCacheNode->GetFormatEtc()->cfFormat == CF_DIB) {
  203. // We need to add CF_BITMAP format also.
  204. // Add another StatData item
  205. SDindex = m_pSDArray->AddItem(StatData);
  206. if(SDindex) {
  207. // Get the newly added StatData object
  208. pStatData = m_pSDArray->GetItem(SDindex);
  209. Win4Assert(pStatData);
  210. if(pStatData->m_ulFlags & SDFLAG_OUTOFMEMORY) {
  211. m_ulFlags |= CENUMSDFLAG_OUTOFMEMORY;
  212. break;
  213. }
  214. else {
  215. pStatData->m_foretc.cfFormat = CF_BITMAP;
  216. pStatData->m_foretc.tymed = TYMED_GDI;
  217. }
  218. }
  219. else {
  220. m_ulFlags |= CENUMSDFLAG_OUTOFMEMORY;
  221. break;
  222. }
  223. }
  224. }
  225. }
  226. else
  227. m_ulFlags |= CENUMSDFLAG_OUTOFMEMORY;
  228. // Reset the index
  229. if(m_pSDArray)
  230. m_pSDArray->Reset(m_index);
  231. return;
  232. }
  233. //+----------------------------------------------------------------------------
  234. //
  235. // Member:
  236. // CEnumStatData::CEnumStatData, private
  237. //
  238. // Synopsis:
  239. // Copy constructor
  240. //
  241. // Arguments:
  242. // [EnumStatData] [in] -- StatData Enumerator to be copied
  243. //
  244. // History:
  245. // Gopalk Creation Sep 04, 96
  246. //
  247. //-----------------------------------------------------------------------------
  248. CEnumStatData::CEnumStatData(CEnumStatData& EnumStatData)
  249. {
  250. // Initialize
  251. m_ulFlags = EnumStatData.m_ulFlags;
  252. m_refs = 1;
  253. m_index = EnumStatData.m_index;
  254. // Copy the StatData array and add ref it
  255. m_pSDArray = EnumStatData.m_pSDArray;
  256. if(m_pSDArray)
  257. m_pSDArray->AddRef();
  258. }
  259. //+----------------------------------------------------------------------------
  260. //
  261. // Member:
  262. // CEnumStatData::~CEnumStatData, private
  263. //
  264. // Synopsis:
  265. // Desstructor
  266. //
  267. // Arguments:
  268. // NONE
  269. //
  270. // History:
  271. // Gopalk Creation Sep 04, 96
  272. //
  273. //-----------------------------------------------------------------------------
  274. CEnumStatData::~CEnumStatData()
  275. {
  276. if(m_pSDArray) {
  277. m_pSDArray->Release();
  278. m_pSDArray = NULL;
  279. }
  280. return;
  281. }
  282. //+----------------------------------------------------------------------------
  283. //
  284. // Member:
  285. // CEnumStatData::QueryInterface, public
  286. //
  287. // Synopsis:
  288. // Implements IUnknown::QueryInterface
  289. //
  290. // Arguments:
  291. // [iid] [in] -- IID of the desired interface
  292. // [ppv] [out] -- pointer to where the requested interface is returned
  293. //
  294. // Returns:
  295. // NOERROR if the requested interface is available
  296. // E_NOINTERFACE otherwise
  297. //
  298. // History:
  299. // Gopalk Creation Sep 04, 96
  300. //
  301. //-----------------------------------------------------------------------------
  302. STDMETHODIMP CEnumStatData::QueryInterface(REFIID riid, LPVOID* ppv)
  303. {
  304. // Validation checks
  305. VDATEHEAP();
  306. VDATETHREAD(this);
  307. // Get the requested Interface
  308. if(IsEqualIID(riid, IID_IUnknown))
  309. *ppv = (void *)(IUnknown *) this;
  310. else if(IsEqualIID(riid, IID_IEnumSTATDATA))
  311. *ppv = (void *)(IEnumSTATDATA *) this;
  312. else {
  313. *ppv = NULL;
  314. return ResultFromScode(E_NOINTERFACE);
  315. }
  316. // AddRef through the interface being returned
  317. ((IUnknown *) *ppv)->AddRef();
  318. return(NOERROR);
  319. }
  320. //+----------------------------------------------------------------------------
  321. //
  322. // Member:
  323. // CEnumStatData::AddRef, public
  324. //
  325. // Synopsis:
  326. // Implements IUnknown::AddRef
  327. //
  328. // Arguments:
  329. // None
  330. //
  331. // Returns:
  332. // Object's reference count
  333. //
  334. // History:
  335. // Gopalk Creation Sep 04, 96
  336. //
  337. //-----------------------------------------------------------------------------
  338. STDMETHODIMP_(ULONG) CEnumStatData::AddRef()
  339. {
  340. // Validation checks
  341. VDATEHEAP();
  342. if(!VerifyThreadId())
  343. return((ULONG) RPC_E_WRONG_THREAD);
  344. return m_refs++;
  345. }
  346. //+----------------------------------------------------------------------------
  347. //
  348. // Member:
  349. // CEnumStatData::Release, public
  350. //
  351. // Synopsis:
  352. // Implements IUnknown::Release
  353. //
  354. // Arguments:
  355. // None
  356. //
  357. // Returns:
  358. // Object's reference count
  359. //
  360. // History:
  361. // Gopalk Creation Sep 04, 96
  362. //
  363. //-----------------------------------------------------------------------------
  364. STDMETHODIMP_(ULONG) CEnumStatData::Release()
  365. {
  366. // Validation checks
  367. VDATEHEAP();
  368. if(!VerifyThreadId())
  369. return((ULONG) RPC_E_WRONG_THREAD);
  370. if(--m_refs == 0) {
  371. delete this;
  372. return 0;
  373. }
  374. return m_refs;
  375. }
  376. //+----------------------------------------------------------------------------
  377. //
  378. // Member:
  379. // CEnumStatData::Next, public
  380. //
  381. // Synopsis:
  382. // Implements IEnumSTATDATA::Next
  383. //
  384. // Arguments:
  385. // [celt] [in] -- the number of items the caller likes
  386. // to be returned
  387. // [rgelt] [in] -- a pointer to an array where items are
  388. // to be returned
  389. // [pceltFetched] [in/out] -- a pointer where the count of actual
  390. // number of items returned. May be NULL
  391. //
  392. // Returns:
  393. // NOERROR if the number of items returned is same as requested
  394. // S_FALSE if fewer items are returned
  395. // E_OUTOFMEMORY if memory allocation was not successful for
  396. // copying the target device of FORMATETC
  397. //
  398. // History:
  399. // Gopalk Creation Sep 04, 96
  400. //
  401. //-----------------------------------------------------------------------------
  402. STDMETHODIMP CEnumStatData::Next(ULONG celt, STATDATA* rgelt, ULONG* pceltFetched)
  403. {
  404. // Validation checks
  405. VDATEHEAP();
  406. VDATETHREAD(this);
  407. if(celt<1)
  408. return E_INVALIDARG;
  409. if(celt>1 && pceltFetched==NULL && !IsWOWThread())
  410. return E_INVALIDARG;
  411. if(!IsValidPtrOut(rgelt, sizeof(rgelt[0])*celt))
  412. return E_INVALIDARG;
  413. if(pceltFetched)
  414. VDATEPTROUT(pceltFetched, ULONG);
  415. // Local variables
  416. HRESULT error=NOERROR;
  417. ULONG cntFetched;
  418. CStatData* pStatData;
  419. // Enumerate the StatData Array
  420. for(cntFetched=0;cntFetched<celt;cntFetched++) {
  421. // Fetch the next StatData object
  422. pStatData = m_pSDArray->GetNext(m_index);
  423. if(!pStatData) {
  424. error = S_FALSE;
  425. break;
  426. }
  427. // Copy the FormatEtc
  428. if(!UtCopyFormatEtc(&pStatData->m_foretc, &rgelt[cntFetched].formatetc)) {
  429. error = ResultFromScode(E_OUTOFMEMORY);
  430. break;
  431. }
  432. // Copy the rest of StatData fields
  433. rgelt[cntFetched].advf = pStatData->m_dwAdvf;
  434. rgelt[cntFetched].pAdvSink = pStatData->m_pAdvSink;
  435. if(rgelt[cntFetched].pAdvSink)
  436. rgelt[cntFetched].pAdvSink->AddRef();
  437. rgelt[cntFetched].dwConnection = pStatData->m_dwConnID;
  438. }
  439. // Copy the number of items being returned
  440. if(pceltFetched)
  441. *pceltFetched = cntFetched;
  442. return error;
  443. }
  444. //+----------------------------------------------------------------------------
  445. //
  446. // Member:
  447. // CEnumStatData::Skip, public
  448. //
  449. // Synopsis:
  450. // Implements IEnumSTATDATA::Skip
  451. //
  452. // Arguments:
  453. // [celt] [in] -- the number of items the caller likes to be skipped
  454. //
  455. // Returns:
  456. // NOERROR if the number of items skipped is same as requested
  457. // S_FALSE if fewer items are returned
  458. //
  459. // History:
  460. // Gopalk Creation Sep 04, 96
  461. //
  462. //-----------------------------------------------------------------------------
  463. STDMETHODIMP CEnumStatData::Skip(ULONG celt)
  464. {
  465. // Validation checks
  466. VDATEHEAP();
  467. VDATETHREAD(this);
  468. // Local variables
  469. HRESULT error=NOERROR;
  470. ULONG cntSkipped;
  471. CStatData* pStatData;
  472. // Enumerate the StatData Array
  473. for(cntSkipped=0;cntSkipped<celt;cntSkipped++) {
  474. // Fetch the next StatData object
  475. pStatData = m_pSDArray->GetNext(m_index);
  476. if(!pStatData) {
  477. error = S_FALSE;
  478. break;
  479. }
  480. }
  481. return error;
  482. }
  483. //+----------------------------------------------------------------------------
  484. //
  485. // Member:
  486. // CEnumStatData::Reset, public
  487. //
  488. // Synopsis:
  489. // Implements IEnumSTATDATA::Reset
  490. //
  491. // Arguments:
  492. // NONE
  493. //
  494. // Returns:
  495. // NOERROR
  496. //
  497. // History:
  498. // Gopalk Creation Sep 04, 96
  499. //
  500. //-----------------------------------------------------------------------------
  501. STDMETHODIMP CEnumStatData::Reset()
  502. {
  503. // Validation checks
  504. VDATEHEAP();
  505. VDATETHREAD(this);
  506. // Reset the current index
  507. m_pSDArray->Reset(m_index);
  508. return NOERROR;
  509. }
  510. //+----------------------------------------------------------------------------
  511. //
  512. // Member:
  513. // CEnumStatData::Clone, public
  514. //
  515. // Synopsis:
  516. // Implements IEnumSTATDATA::Clone
  517. //
  518. // Arguments:
  519. // [ppenum] [out] -- pointer where the newly created StatData
  520. // enumerator is returned
  521. //
  522. // Returns:
  523. // NOERROR if a new StatData enumerator is returned
  524. // E_OUTOFMEMORY otherwise
  525. //
  526. // History:
  527. // Gopalk Creation Sep 04, 96
  528. //
  529. //-----------------------------------------------------------------------------
  530. STDMETHODIMP CEnumStatData::Clone(LPENUMSTATDATA* ppenum)
  531. {
  532. // Validation checks
  533. VDATEHEAP();
  534. VDATETHREAD(this);
  535. VDATEPTROUT(ppenum, LPENUMSTATDATA);
  536. // Create a new StatData enumerator
  537. CEnumStatData* EnumStatData = new CEnumStatData(*this);
  538. if(EnumStatData)
  539. *ppenum = (IEnumSTATDATA *) EnumStatData;
  540. else
  541. return ResultFromScode(E_OUTOFMEMORY);
  542. return NOERROR;
  543. }
  544. //+----------------------------------------------------------------------------
  545. //
  546. // Member:
  547. // CFormatEtc::CFormatEtc, public
  548. //
  549. // Synopsis:
  550. // Constructor
  551. //
  552. // Arguments:
  553. // [foretc] [in] -- FormatEtc
  554. //
  555. // History:
  556. // Gopalk Creation Sep 04, 96
  557. //
  558. //-----------------------------------------------------------------------------
  559. CFormatEtc::CFormatEtc(FORMATETC* foretc)
  560. {
  561. // Initialize
  562. m_ulFlags = 0;
  563. // Copy the FormatEtc
  564. if(!UtCopyFormatEtc(foretc, &m_foretc))
  565. m_ulFlags |= FEFLAG_OUTOFMEMORY;
  566. }
  567. //+----------------------------------------------------------------------------
  568. //
  569. // Member:
  570. // CFormatEtc::~CFormatEtc, public
  571. //
  572. // Synopsis:
  573. // Destructor
  574. //
  575. // Arguments:
  576. //
  577. // History:
  578. // Gopalk Creation Sep 04, 96
  579. //
  580. //-----------------------------------------------------------------------------
  581. CFormatEtc::~CFormatEtc()
  582. {
  583. // Delete the ptd if it is non-null
  584. if(m_foretc.ptd)
  585. PubMemFree(m_foretc.ptd);
  586. }
  587. //+----------------------------------------------------------------------------
  588. //
  589. // Member:
  590. // CFormatEtc::operator=, public
  591. //
  592. // Synopsis:
  593. // Equality operator
  594. //
  595. // Arguments:
  596. // rFormatEtc [in] - The RHS value
  597. //
  598. // History:
  599. // Gopalk Creation Sep 04, 96
  600. //
  601. //-----------------------------------------------------------------------------
  602. const CFormatEtc& CFormatEtc::operator=(const CFormatEtc& rFormatEtc)
  603. {
  604. // Check to see, if this a=a case
  605. if(this==&rFormatEtc)
  606. return(*this);
  607. // Self destroy
  608. CFormatEtc::~CFormatEtc();
  609. // Copy the FormatEtc
  610. if(!UtCopyFormatEtc((LPFORMATETC) &rFormatEtc.m_foretc, &m_foretc))
  611. m_ulFlags |= FEFLAG_OUTOFMEMORY;
  612. return(*this);
  613. }
  614. //+----------------------------------------------------------------------------
  615. //
  616. // Member:
  617. // CEnumFormatEtc::CreateEnumFormatEtc, public
  618. //
  619. // Synopsis:
  620. // A static member function that creates a properly constructed
  621. // FormatEtc Enumerator given the cachenode array of the cache
  622. //
  623. // Arguments:
  624. // [pCacheArray] [in] -- Array of CacheNode maintained by COleCache
  625. //
  626. // Returns:
  627. // Pointer to a properly constructed FormatEtc enumerator interface
  628. // NULL otherwise.
  629. //
  630. // History:
  631. // Gopalk Creation Sep 04, 96
  632. //
  633. //-----------------------------------------------------------------------------
  634. LPENUMFORMATETC CEnumFormatEtc::CreateEnumFormatEtc(CArray<CCacheNode>* pCacheArray)
  635. {
  636. CEnumFormatEtc* EnumFormatEtc = new CEnumFormatEtc(pCacheArray);
  637. if(EnumFormatEtc && !(EnumFormatEtc->m_ulFlags & CENUMFEFLAG_OUTOFMEMORY))
  638. return ((IEnumFORMATETC *) EnumFormatEtc);
  639. if(EnumFormatEtc)
  640. EnumFormatEtc->Release();
  641. return(NULL);
  642. }
  643. //+----------------------------------------------------------------------------
  644. //
  645. // Member:
  646. // CEnumFormatEtc::CEnumFormatEtc, private
  647. //
  648. // Synopsis:
  649. // Constructor
  650. //
  651. // Arguments:
  652. // [pCacheArray] [in] -- Array of CacheNode maintained by COleCache
  653. //
  654. // History:
  655. // Gopalk Creation Sep 04, 96
  656. //
  657. //-----------------------------------------------------------------------------
  658. CEnumFormatEtc::CEnumFormatEtc(CArray<CCacheNode>* pCacheArray)
  659. {
  660. // Local variables
  661. ULONG i, CNindex, FEindex;
  662. LPCACHENODE lpCacheNode;
  663. CFormatEtc* pFormatEtc;
  664. // Initilaize
  665. m_ulFlags = 0;
  666. m_refs = 1;
  667. // Create the FormatEtc array
  668. m_pFEArray = CArray<CFormatEtc>::CreateArray(pCacheArray->Length());
  669. if(m_pFEArray) {
  670. // Enumerate the cache nodes
  671. pCacheArray->Reset(CNindex);
  672. for(i=0;i<pCacheArray->Length();i++) {
  673. // Get the next cache node
  674. lpCacheNode = pCacheArray->GetNext(CNindex);
  675. // pCacheNode cannot be null
  676. Win4Assert(lpCacheNode);
  677. // Create a FormatEtc object representing the cachenode
  678. CFormatEtc FormatEtc((FORMATETC *)lpCacheNode->GetFormatEtc());
  679. if(FormatEtc.m_ulFlags & FEFLAG_OUTOFMEMORY) {
  680. m_ulFlags |= CENUMFEFLAG_OUTOFMEMORY;
  681. break;
  682. }
  683. // Add the FormatEtc object to the array
  684. FEindex = m_pFEArray->AddItem(FormatEtc);
  685. if(FEindex) {
  686. // Get the newly added FormatEtc object
  687. pFormatEtc = m_pFEArray->GetItem(FEindex);
  688. Win4Assert(pFormatEtc);
  689. if(pFormatEtc->m_ulFlags & FEFLAG_OUTOFMEMORY) {
  690. m_ulFlags |= CENUMFEFLAG_OUTOFMEMORY;
  691. break;
  692. }
  693. }
  694. else {
  695. m_ulFlags |= CENUMFEFLAG_OUTOFMEMORY;
  696. break;
  697. }
  698. // Check if cachenode format is CF_DIB
  699. if(lpCacheNode->GetFormatEtc()->cfFormat == CF_DIB) {
  700. // We need to add CF_BITMAP format also.
  701. // Add another FormatEtc object
  702. FEindex = m_pFEArray->AddItem(FormatEtc);
  703. if(FEindex) {
  704. // Get the newly added FormatEtc object
  705. pFormatEtc = m_pFEArray->GetItem(FEindex);
  706. Win4Assert(pFormatEtc);
  707. if(pFormatEtc->m_ulFlags & FEFLAG_OUTOFMEMORY) {
  708. m_ulFlags |= CENUMFEFLAG_OUTOFMEMORY;
  709. break;
  710. }
  711. else {
  712. pFormatEtc->m_foretc.cfFormat = CF_BITMAP;
  713. pFormatEtc->m_foretc.tymed = TYMED_GDI;
  714. }
  715. }
  716. else {
  717. m_ulFlags |= CENUMFEFLAG_OUTOFMEMORY;
  718. break;
  719. }
  720. }
  721. }
  722. }
  723. else
  724. m_ulFlags |= CENUMFEFLAG_OUTOFMEMORY;
  725. // Reset the index
  726. if(m_pFEArray)
  727. m_pFEArray->Reset(m_index);
  728. return;
  729. }
  730. //+----------------------------------------------------------------------------
  731. //
  732. // Member:
  733. // CEnumFormatEtc::CEnumFormatEtc, private
  734. //
  735. // Synopsis:
  736. // Copy constructor
  737. //
  738. // Arguments:
  739. // [EnumFormatEtc] [in] -- FormatEtc Enumerator to be copied
  740. //
  741. // History:
  742. // Gopalk Creation Sep 04, 96
  743. //
  744. //-----------------------------------------------------------------------------
  745. CEnumFormatEtc::CEnumFormatEtc(CEnumFormatEtc& EnumFormatEtc)
  746. {
  747. // Initialize
  748. m_ulFlags = EnumFormatEtc.m_ulFlags;
  749. m_refs = 1;
  750. m_index = EnumFormatEtc.m_index;
  751. // Copy the FormatEtc array and add ref it
  752. m_pFEArray = EnumFormatEtc.m_pFEArray;
  753. if(m_pFEArray)
  754. m_pFEArray->AddRef();
  755. }
  756. //+----------------------------------------------------------------------------
  757. //
  758. // Member:
  759. // CEnumFormatEtc::~CEnumFormatEtc, private
  760. //
  761. // Synopsis:
  762. // Desstructor
  763. //
  764. // Arguments:
  765. // NONE
  766. //
  767. // History:
  768. // Gopalk Creation Sep 04, 96
  769. //
  770. //-----------------------------------------------------------------------------
  771. CEnumFormatEtc::~CEnumFormatEtc()
  772. {
  773. if(m_pFEArray) {
  774. m_pFEArray->Release();
  775. m_pFEArray = NULL;
  776. }
  777. return;
  778. }
  779. //+----------------------------------------------------------------------------
  780. //
  781. // Member:
  782. // CEnumFormatEtc::QueryInterface, public
  783. //
  784. // Synopsis:
  785. // Implements IUnknown::QueryInterface
  786. //
  787. // Arguments:
  788. // [iid] [in] -- IID of the desired interface
  789. // [ppv] [out] -- pointer to where the requested interface is returned
  790. //
  791. // Returns:
  792. // NOERROR if the requested interface is available
  793. // E_NOINTERFACE otherwise
  794. //
  795. // History:
  796. // Gopalk Creation Sep 04, 96
  797. //
  798. //-----------------------------------------------------------------------------
  799. STDMETHODIMP CEnumFormatEtc::QueryInterface(REFIID riid, LPVOID* ppv)
  800. {
  801. // Validation checks
  802. VDATEHEAP();
  803. VDATETHREAD(this);
  804. // Get the requested Interface
  805. if(IsEqualIID(riid, IID_IUnknown))
  806. *ppv = (void *)(IUnknown *) this;
  807. else if(IsEqualIID(riid, IID_IEnumFORMATETC))
  808. *ppv = (void *)(IEnumFORMATETC *) this;
  809. else {
  810. *ppv = NULL;
  811. return ResultFromScode(E_NOINTERFACE);
  812. }
  813. // AddRef through the interface being returned
  814. ((IUnknown *) *ppv)->AddRef();
  815. return(NOERROR);
  816. }
  817. //+----------------------------------------------------------------------------
  818. //
  819. // Member:
  820. // CEnumFormatEtc::AddRef, public
  821. //
  822. // Synopsis:
  823. // Implements IUnknown::AddRef
  824. //
  825. // Arguments:
  826. // None
  827. //
  828. // Returns:
  829. // Object's reference count
  830. //
  831. // History:
  832. // Gopalk Creation Sep 04, 96
  833. //
  834. //-----------------------------------------------------------------------------
  835. STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef()
  836. {
  837. // Validation checks
  838. VDATEHEAP();
  839. if(!VerifyThreadId())
  840. return((ULONG) RPC_E_WRONG_THREAD);
  841. return m_refs++;
  842. }
  843. //+----------------------------------------------------------------------------
  844. //
  845. // Member:
  846. // CEnumFormatEtc::Release, public
  847. //
  848. // Synopsis:
  849. // Implements IUnknown::Release
  850. //
  851. // Arguments:
  852. // None
  853. //
  854. // Returns:
  855. // Object's reference count
  856. //
  857. // History:
  858. // Gopalk Creation Sep 04, 96
  859. //
  860. //-----------------------------------------------------------------------------
  861. STDMETHODIMP_(ULONG) CEnumFormatEtc::Release()
  862. {
  863. // Validation checks
  864. VDATEHEAP();
  865. if(!VerifyThreadId())
  866. return((ULONG) RPC_E_WRONG_THREAD);
  867. if(--m_refs == 0) {
  868. delete this;
  869. return 0;
  870. }
  871. return m_refs;
  872. }
  873. //+----------------------------------------------------------------------------
  874. //
  875. // Member:
  876. // CEnumFormatEtc::Next, public
  877. //
  878. // Synopsis:
  879. // Implements IEnumFORMATETC::Next
  880. //
  881. // Arguments:
  882. // [celt] [in] -- the number of items the caller likes
  883. // to be returned
  884. // [rgelt] [in] -- a pointer to an array where items are
  885. // to be returned
  886. // [pceltFetched] [in/out] -- a pointer where the count of actual
  887. // number of items returned. May be NULL
  888. //
  889. // Returns:
  890. // NOERROR if the number of items returned is same as requested
  891. // S_FALSE if fewer items are returned
  892. // E_OUTOFMEMORY if memory allocation was not successful for
  893. // copying the target device of FORMATETC
  894. //
  895. // History:
  896. // Gopalk Creation Sep 04, 96
  897. //
  898. //-----------------------------------------------------------------------------
  899. STDMETHODIMP CEnumFormatEtc::Next(ULONG celt, FORMATETC* rgelt, ULONG* pceltFetched)
  900. {
  901. // Validation checks
  902. VDATEHEAP();
  903. VDATETHREAD(this);
  904. if(celt<1)
  905. return E_INVALIDARG;
  906. if(celt>1 && pceltFetched==NULL && !IsWOWThread())
  907. return E_INVALIDARG;
  908. if(!IsValidPtrOut(rgelt, sizeof(rgelt[0])*celt))
  909. return E_INVALIDARG;
  910. if(pceltFetched)
  911. VDATEPTROUT(pceltFetched, ULONG);
  912. // Local variables
  913. HRESULT error=NOERROR;
  914. ULONG cntFetched;
  915. CFormatEtc* pFormatEtc;
  916. // Enumerate the FormatEtc Array
  917. for(cntFetched=0;cntFetched<celt;cntFetched++) {
  918. // Fetch the next FormatEtc object
  919. pFormatEtc = m_pFEArray->GetNext(m_index);
  920. if(!pFormatEtc) {
  921. error = S_FALSE;
  922. break;
  923. }
  924. // Copy the FormatEtc
  925. if(!UtCopyFormatEtc(&pFormatEtc->m_foretc, &rgelt[cntFetched])) {
  926. error = ResultFromScode(E_OUTOFMEMORY);
  927. break;
  928. }
  929. }
  930. // Copy the number of items being returned
  931. if(pceltFetched)
  932. *pceltFetched = cntFetched;
  933. return error;
  934. }
  935. //+----------------------------------------------------------------------------
  936. //
  937. // Member:
  938. // CEnumFormatEtc::Skip, public
  939. //
  940. // Synopsis:
  941. // Implements IEnumFORMATETC::Skip
  942. //
  943. // Arguments:
  944. // [celt] [in] -- the number of items the caller likes to be skipped
  945. //
  946. // Returns:
  947. // NOERROR if the number of items skipped is same as requested
  948. // S_FALSE if fewer items are returned
  949. //
  950. // History:
  951. // Gopalk Creation Sep 04, 96
  952. //
  953. //-----------------------------------------------------------------------------
  954. STDMETHODIMP CEnumFormatEtc::Skip(ULONG celt)
  955. {
  956. // Validation checks
  957. VDATEHEAP();
  958. VDATETHREAD(this);
  959. // Local variables
  960. HRESULT error=NOERROR;
  961. ULONG cntSkipped;
  962. CFormatEtc* pFormatEtc;
  963. // Enumerate the FormatEtc Array
  964. for(cntSkipped=0;cntSkipped<celt;cntSkipped++) {
  965. // Fetch the next FormatEtc object
  966. pFormatEtc = m_pFEArray->GetNext(m_index);
  967. if(!pFormatEtc) {
  968. error = S_FALSE;
  969. break;
  970. }
  971. }
  972. return error;
  973. }
  974. //+----------------------------------------------------------------------------
  975. //
  976. // Member:
  977. // CEnumFormatEtc::Reset, public
  978. //
  979. // Synopsis:
  980. // Implements IEnumFORMATETC::Reset
  981. //
  982. // Arguments:
  983. // NONE
  984. //
  985. // Returns:
  986. // NOERROR
  987. //
  988. // History:
  989. // Gopalk Creation Sep 04, 96
  990. //
  991. //-----------------------------------------------------------------------------
  992. STDMETHODIMP CEnumFormatEtc::Reset()
  993. {
  994. // Validation checks
  995. VDATEHEAP();
  996. VDATETHREAD(this);
  997. // Reset the current index
  998. m_pFEArray->Reset(m_index);
  999. return NOERROR;
  1000. }
  1001. //+----------------------------------------------------------------------------
  1002. //
  1003. // Member:
  1004. // CEnumFormatEtc::Clone, public
  1005. //
  1006. // Synopsis:
  1007. // Implements IEnumFORMATETC::Clone
  1008. //
  1009. // Arguments:
  1010. // [ppenum] [out] -- pointer where the newly created FormatEtc
  1011. // enumerator is returned
  1012. //
  1013. // Returns:
  1014. // NOERROR if a new FormatEtc enumerator is returned
  1015. // E_OUTOFMEMORY otherwise
  1016. //
  1017. // History:
  1018. // Gopalk Creation Sep 04, 96
  1019. //
  1020. //-----------------------------------------------------------------------------
  1021. STDMETHODIMP CEnumFormatEtc::Clone(LPENUMFORMATETC* ppenum)
  1022. {
  1023. // Validation checks
  1024. VDATEHEAP();
  1025. VDATETHREAD(this);
  1026. VDATEPTROUT(ppenum, LPENUMFORMATETC);
  1027. // Create a FormatEtc enumerator
  1028. CEnumFormatEtc* EnumFormatEtc = new CEnumFormatEtc(*this);
  1029. if(EnumFormatEtc)
  1030. *ppenum = (IEnumFORMATETC *) EnumFormatEtc;
  1031. else
  1032. return ResultFromScode(E_OUTOFMEMORY);
  1033. return NOERROR;
  1034. }