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.

781 lines
20 KiB

  1. //+---------------------------------------------------------------------
  2. //
  3. // File: stdenum.cxx
  4. //
  5. // Contents: Standard implementations of common enumerators
  6. //
  7. //----------------------------------------------------------------------
  8. #include "headers.hxx"
  9. #pragma hdrstop
  10. #include <limits.h> // for UINT_MAX below
  11. //
  12. // forward declarations
  13. //
  14. class StdEnumOLEVERB;
  15. typedef StdEnumOLEVERB FAR* LPSTDENUMOLEVERB;
  16. class StdEnumFORMATETC;
  17. typedef StdEnumFORMATETC FAR* LPSTDENUMFORMATETC;
  18. #if 1
  19. class StdStaticEnum;
  20. typedef StdStaticEnum FAR* LPSTDSTATICENUM;
  21. #endif // 0
  22. //+---------------------------------------------------------------
  23. //
  24. // Class: StdEnumOLEVERB
  25. //
  26. // Purpose: Standard enumerator of OLEVERB tables
  27. //
  28. //---------------------------------------------------------------
  29. class StdEnumOLEVERB: public IEnumOLEVERB
  30. {
  31. friend HRESULT CreateOLEVERBEnum(LPOLEVERB, ULONG, LPENUMOLEVERB FAR*);
  32. public:
  33. DECLARE_STANDARD_IUNKNOWN(StdEnumOLEVERB);
  34. // *** IEnumOLEVERB methods ***
  35. STDMETHOD(Next) (ULONG celt, LPOLEVERB rgelt, ULONG FAR* pceltFetched);
  36. STDMETHOD(Skip) (ULONG celt);
  37. STDMETHOD(Reset) (void);
  38. STDMETHOD(Clone) (IEnumOLEVERB FAR* FAR* ppenm);
  39. private:
  40. StdEnumOLEVERB(LPOLEVERB pStart, ULONG cCount);
  41. ~StdEnumOLEVERB(void);
  42. LPOLEVERB _pStart;
  43. ULONG _cCount;
  44. ULONG _cCurrent;
  45. };
  46. //+---------------------------------------------------------------
  47. //
  48. // Member: StdEnumOLEVERB::StdEnumOLEVERB, private
  49. //
  50. // Synopsis: Constructor for StdEnumOLEVERB objects
  51. //
  52. // Arguments: [pStart] -- pointer to the beginning of the OLEVERB array
  53. // [cCount] -- the number of elements in the array
  54. //
  55. // Notes: OLEVERB enumerators should be constructed using the
  56. // CreateOLEVERBEnum function.
  57. //
  58. //----------------------------------------------------------------
  59. StdEnumOLEVERB::StdEnumOLEVERB(LPOLEVERB pStart, ULONG cCount)
  60. {
  61. _ulRefs = 1;
  62. _pStart = pStart;
  63. _cCount = cCount;
  64. _cCurrent = 0;
  65. DOUT(TEXT("StdEnumOLEVERB constructed.\r\n"));
  66. }
  67. //+---------------------------------------------------------------
  68. //
  69. // Member: StdEnumOLEVERB::~StdEnumOLEVERB, private
  70. //
  71. // Synopsis: Destructor for StdEnumOLEVERB objects
  72. //
  73. // Notes: Static enumerators should never be `deleted' but
  74. // instead IUnknown::Release'd.
  75. //
  76. //----------------------------------------------------------------
  77. StdEnumOLEVERB::~StdEnumOLEVERB(void)
  78. {
  79. DOUT(TEXT("StdEnumOLEVERB destructed.\r\n"));
  80. }
  81. IMPLEMENT_STANDARD_IUNKNOWN(StdEnumOLEVERB)
  82. //+---------------------------------------------------------------
  83. //
  84. // Member: StdEnumOLEVERB::QueryInterface, public
  85. //
  86. // Synopsis: Method of IUnknown interface
  87. //
  88. //----------------------------------------------------------------
  89. STDMETHODIMP
  90. StdEnumOLEVERB::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  91. {
  92. if (IsEqualIID(riid,IID_IUnknown) || IsEqualIID(riid,IID_IEnumOLEVERB))
  93. {
  94. *ppvObj = this;
  95. AddRef();
  96. return NOERROR;
  97. }
  98. DOUT(TEXT("StdEnumOLEVERB::QueryInterface E_NOINTERFACE\r\n"));
  99. *ppvObj = NULL;
  100. return E_NOINTERFACE;
  101. }
  102. //+---------------------------------------------------------------
  103. //
  104. // Member: StdEnumOLEVERB::Next
  105. //
  106. // Synopsis: Member of IEnumXXX interface
  107. //
  108. //----------------------------------------------------------------
  109. STDMETHODIMP
  110. StdEnumOLEVERB::Next(ULONG celt,
  111. LPOLEVERB pArrayObjs,
  112. ULONG FAR* pceltFetched)
  113. {
  114. /* skip ahead to primary verb */
  115. for (;_cCurrent <= _cCount; _cCurrent++)
  116. {
  117. LPOLEVERB pVerb = &_pStart[_cCurrent];
  118. if (pVerb->lVerb >= OLEIVERB_PRIMARY)
  119. break;
  120. }
  121. ULONG celtFetched = min(celt, _cCount-_cCurrent);
  122. for (ULONG i = 0; i < celtFetched; i++, _cCurrent++)
  123. {
  124. LPOLEVERB pVerb = &_pStart[_cCurrent];
  125. pArrayObjs[i] = *pVerb;
  126. if (pVerb->lpszVerbName!=NULL)
  127. {
  128. HRESULT r;
  129. r = TaskAllocString(pVerb->lpszVerbName,
  130. &pArrayObjs[i].lpszVerbName);
  131. if (!OK(r))
  132. return r;
  133. }
  134. }
  135. if (pceltFetched != NULL)
  136. {
  137. *pceltFetched = celtFetched;
  138. }
  139. return ((celtFetched == celt) ? NOERROR : S_FALSE);
  140. }
  141. //+---------------------------------------------------------------
  142. //
  143. // Member: StdEnumOLEVERB::Skip
  144. //
  145. // Synopsis: Member of IEnumXXX interface
  146. //
  147. //----------------------------------------------------------------
  148. STDMETHODIMP
  149. StdEnumOLEVERB::Skip(ULONG celt)
  150. {
  151. _cCurrent += celt;
  152. if (_cCurrent >= _cCount)
  153. {
  154. _cCurrent = _cCount;
  155. return S_FALSE;
  156. }
  157. return NOERROR;
  158. }
  159. //+---------------------------------------------------------------
  160. //
  161. // Member: StdEnumOLEVERB::Reset
  162. //
  163. // Synopsis: Member of IEnumXXX interface
  164. //
  165. //----------------------------------------------------------------
  166. STDMETHODIMP
  167. StdEnumOLEVERB::Reset(void)
  168. {
  169. _cCurrent = 0;
  170. return NOERROR;
  171. }
  172. //+---------------------------------------------------------------
  173. //
  174. // Member: StdEnumOLEVERB::Clone
  175. //
  176. // Synopsis: Member of IEnumXXX interface
  177. //
  178. //----------------------------------------------------------------
  179. STDMETHODIMP
  180. StdEnumOLEVERB::Clone(LPENUMOLEVERB FAR* ppenm)
  181. {
  182. HRESULT r = E_OUTOFMEMORY;
  183. //LPSTDENUMOLEVERB penum = new (NullOnFail) StdEnumOLEVERB(_pStart, _cCount);
  184. LPSTDENUMOLEVERB penum = new StdEnumOLEVERB(_pStart, _cCount);
  185. if (penum != NULL)
  186. {
  187. r = NOERROR;
  188. penum->_cCurrent = _cCurrent;
  189. *ppenm = penum;
  190. }
  191. else
  192. {
  193. DOUT(TEXT("o2base/StdEnumOLEVERB::Clone failed\r\n"));
  194. }
  195. return r;
  196. }
  197. //+---------------------------------------------------------------
  198. //
  199. // Function: CreateOLEVERBEnum, public
  200. //
  201. // Synopsis: Creates a standard enumerator over OLEVERB arrays
  202. //
  203. // Arguments: [pVerbs] -- pointer to the beginning of the OLEVERB array
  204. // [cVerbs] -- the number of elements in the array
  205. // [ppenum] -- where the enumerator is returned
  206. //
  207. // Returns: Success if the enumerator could be successfully created
  208. //
  209. // Notes: This function is typically used in the IOleObject::EnumVerbs
  210. // method implementation.
  211. //
  212. //----------------------------------------------------------------
  213. HRESULT
  214. CreateOLEVERBEnum(LPOLEVERB pVerbs, ULONG cVerbs, LPENUMOLEVERB FAR* ppenum)
  215. {
  216. HRESULT r = E_OUTOFMEMORY;
  217. //LPSTDENUMOLEVERB penum = new (NullOnFail) StdEnumOLEVERB(pVerbs, cVerbs);
  218. LPSTDENUMOLEVERB penum = new StdEnumOLEVERB(pVerbs, cVerbs);
  219. if (penum != NULL)
  220. {
  221. r = NOERROR;
  222. *ppenum = penum;
  223. }
  224. else
  225. {
  226. DOUT(TEXT("o2base/stdenum/CreateOLEVERBEnum failed\r\n"));
  227. }
  228. return r;
  229. }
  230. //+---------------------------------------------------------------
  231. //
  232. // Class: StdEnumFORMATETC
  233. //
  234. // Purpose: Standard enumerator of FORMATETC tables
  235. //
  236. //---------------------------------------------------------------
  237. class StdEnumFORMATETC: public IEnumFORMATETC
  238. {
  239. friend HRESULT CreateFORMATETCEnum(LPFORMATETC, ULONG, LPENUMFORMATETC FAR*);
  240. public:
  241. DECLARE_STANDARD_IUNKNOWN(StdEnumFORMATETC);
  242. // *** IEnumFORMATETC methods ***
  243. STDMETHOD(Next) (ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched);
  244. STDMETHOD(Skip) (ULONG celt);
  245. STDMETHOD(Reset) (void);
  246. STDMETHOD(Clone) (IEnumFORMATETC FAR* FAR* ppenm);
  247. private:
  248. StdEnumFORMATETC(LPFORMATETC pStart, ULONG cCount);
  249. ~StdEnumFORMATETC(void);
  250. LPFORMATETC _pStart;
  251. ULONG _cCount;
  252. ULONG _cCurrent;
  253. };
  254. //+---------------------------------------------------------------
  255. //
  256. // Member: StdEnumFORMATETC::StdEnumFORMATETC, private
  257. //
  258. // Synopsis: Constructor for StdEnumFORMATETC objects
  259. //
  260. // Arguments: [pStart] -- pointer to the beginning of the FORMATETC array
  261. // [cCount] -- the number of elements in the array
  262. //
  263. // Notes: Static enumerators should be constructed using the
  264. // CreateFORMATETCEnum function.
  265. //
  266. //----------------------------------------------------------------
  267. StdEnumFORMATETC::StdEnumFORMATETC(LPFORMATETC pStart, ULONG cCount)
  268. {
  269. _ulRefs = 1;
  270. _pStart = pStart;
  271. _cCount = cCount;
  272. _cCurrent = 0;
  273. DOUT(TEXT("StdEnumFORMATETC constructed.\r\n"));
  274. }
  275. //+---------------------------------------------------------------
  276. //
  277. // Member: StdStaticEnum::~StdStaticEnum, private
  278. //
  279. // Synopsis: Destructor for StdStaticEnum objects
  280. //
  281. // Notes: Static enumerators should never be `deleted' but
  282. // instead IUnknown::Release'd.
  283. //
  284. //----------------------------------------------------------------
  285. StdEnumFORMATETC::~StdEnumFORMATETC(void)
  286. {
  287. DOUT(TEXT("StdEnumFORMATETC destructed.\r\n"));
  288. }
  289. IMPLEMENT_STANDARD_IUNKNOWN(StdEnumFORMATETC)
  290. //+---------------------------------------------------------------
  291. //
  292. // Member: StdEnumFORMATETC::QueryInterface, public
  293. //
  294. // Synopsis: Method of IUnknown interface
  295. //
  296. //----------------------------------------------------------------
  297. STDMETHODIMP
  298. StdEnumFORMATETC::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  299. {
  300. #ifdef VERBOSE_DBG
  301. TCHAR achBuffer[256];
  302. wsprintf(achBuffer,
  303. TEXT("StdEnumFORMATETC::QueryInterface (%lx)\r\n"),
  304. riid.Data1);
  305. DOUT(achBuffer);
  306. #endif //VERBOSE_DBG
  307. if (IsEqualIID(riid,IID_IUnknown) || IsEqualIID(riid,IID_IEnumFORMATETC))
  308. {
  309. *ppvObj = this;
  310. AddRef();
  311. return NOERROR;
  312. }
  313. #if VERBOSE_DBG
  314. wsprintf(achBuffer,
  315. TEXT("StdEnumFORMATETC::QueryInterface returning E_NOINTERFACE for %lx\r\n"),
  316. riid.Data1);
  317. DOUT(achBuffer);
  318. #endif //VERBOSE_DBG
  319. *ppvObj = NULL;
  320. return E_NOINTERFACE;
  321. }
  322. //+---------------------------------------------------------------
  323. //
  324. // Member: StdEnumFORMATETC::Next
  325. //
  326. // Synopsis: Member of IEnumXXX interface
  327. //
  328. //----------------------------------------------------------------
  329. STDMETHODIMP
  330. StdEnumFORMATETC::Next(ULONG celt,
  331. LPFORMATETC pArrayObjs,
  332. ULONG FAR* pceltFetched)
  333. {
  334. ULONG celtFetched = 0;
  335. if (_pStart == NULL)
  336. return S_FALSE;
  337. if (pceltFetched != NULL)
  338. *pceltFetched = 0L;
  339. if (pArrayObjs == NULL || _cCurrent >= _cCount)
  340. return S_FALSE;
  341. while ( _cCurrent < _cCount && celt > 0 )
  342. {
  343. LPFORMATETC pFormat = &_pStart[_cCurrent];
  344. // deep copy the FORMATETC structure
  345. *pArrayObjs = *pFormat;
  346. if (pFormat->ptd == DVTARGETIGNORE )
  347. pArrayObjs->ptd = NULL;
  348. if (pArrayObjs->ptd != NULL)
  349. {
  350. HRESULT r = TaskAllocMem(sizeof(DVTARGETDEVICE),
  351. (LPVOID FAR*)&pArrayObjs->ptd);
  352. if (OK(r))
  353. {
  354. *(pArrayObjs->ptd) = *(pFormat->ptd);
  355. }
  356. }
  357. pArrayObjs++;
  358. _cCurrent++;
  359. celtFetched++;
  360. celt--;
  361. }
  362. if (pceltFetched != NULL)
  363. {
  364. *pceltFetched = celtFetched - celt;
  365. }
  366. return NOERROR;
  367. }
  368. //+---------------------------------------------------------------
  369. //
  370. // Member: StdEnumFORMATETC::Skip
  371. //
  372. // Synopsis: Member of IEnumXXX interface
  373. //
  374. //----------------------------------------------------------------
  375. STDMETHODIMP
  376. StdEnumFORMATETC::Skip(ULONG celt)
  377. {
  378. _cCurrent += celt;
  379. if (_cCurrent >= _cCount)
  380. {
  381. _cCurrent = _cCount;
  382. return S_FALSE;
  383. }
  384. return NOERROR;
  385. }
  386. //+---------------------------------------------------------------
  387. //
  388. // Member: StdEnumFORMATETC::Reset
  389. //
  390. // Synopsis: Member of IEnumXXX interface
  391. //
  392. //----------------------------------------------------------------
  393. STDMETHODIMP
  394. StdEnumFORMATETC::Reset(void)
  395. {
  396. _cCurrent = 0;
  397. return NOERROR;
  398. }
  399. //+---------------------------------------------------------------
  400. //
  401. // Member: StdEnumFORMATETC::Clone
  402. //
  403. // Synopsis: Member of IEnumXXX interface
  404. //
  405. //----------------------------------------------------------------
  406. STDMETHODIMP
  407. StdEnumFORMATETC::Clone(LPENUMFORMATETC FAR* ppenm)
  408. {
  409. HRESULT r = E_OUTOFMEMORY;;
  410. LPSTDENUMFORMATETC penum = new StdEnumFORMATETC(_pStart, _cCount);
  411. if (penum != NULL)
  412. {
  413. r = NOERROR;
  414. penum->_cCurrent = _cCurrent;
  415. *ppenm = penum;
  416. }
  417. else
  418. {
  419. DOUT(TEXT("o2base/StdEnumFORMATETC::Clone failed\r\n"));
  420. }
  421. return r;
  422. }
  423. //+---------------------------------------------------------------
  424. //
  425. // Function: CreateFORMATETCEnum, public
  426. //
  427. // Synopsis: Creates a standard enumerator over FORMATETC arrays
  428. //
  429. // Arguments: [pFormats] -- pointer to the beginning of the FORMATETC array
  430. // [cFormats] -- the number of elements in the array
  431. // [ppenum] -- where the enumerator is returned
  432. //
  433. // Returns: Success if the enumerator could be successfully created
  434. //
  435. // Notes: This function is typically used in the IDataObject::EnumFormatetc
  436. // method implementation.
  437. //
  438. //----------------------------------------------------------------
  439. HRESULT
  440. CreateFORMATETCEnum(LPFORMATETC pFormats,
  441. ULONG cFormats,
  442. LPENUMFORMATETC FAR* ppenum)
  443. {
  444. HRESULT r;
  445. LPSTDENUMFORMATETC penum = new StdEnumFORMATETC(pFormats, cFormats);
  446. if (penum == NULL)
  447. {
  448. DOUT(TEXT("o2base/stdenum/CreateFORMATETCEnum E_OUTOFMEMORY\r\n"));
  449. r = E_OUTOFMEMORY;
  450. }
  451. else
  452. {
  453. *ppenum = penum;
  454. r = NOERROR;
  455. }
  456. return r;
  457. }
  458. #if 1 // this maybe useful later but is not currently used.
  459. //+---------------------------------------------------------------
  460. //
  461. // Class: StdStaticEnum
  462. //
  463. // Purpose: Enumerates over a static array
  464. //
  465. // Notes: This may not be used to enumerate over structures
  466. // that are "deep". For instance, it cannot be used
  467. // to enumerate over an array of FORMATETCs because such
  468. // an enumerator needs to deep copy the ptd field
  469. // and the enumerator client frees these allocated ptd.
  470. // Similarly for the OLEVERB structure where the verb
  471. // name string must be deep copied.
  472. //
  473. //---------------------------------------------------------------
  474. class StdStaticEnum: public IUnknown
  475. {
  476. friend HRESULT CreateStaticEnum(REFIID, LPVOID, ULONG, ULONG, LPVOID FAR*);
  477. public:
  478. DECLARE_STANDARD_IUNKNOWN(StdStaticEnum);
  479. //*** IEnumerator methods ***
  480. STDMETHOD(Next) (ULONG celt, LPVOID pArrayObjs, ULONG FAR* pceltFetched);
  481. STDMETHOD(Skip) (ULONG celt);
  482. STDMETHOD(Reset) (void);
  483. STDMETHOD(Clone) (LPSTDSTATICENUM FAR* ppenm);
  484. private:
  485. // constructor/destructor
  486. StdStaticEnum(REFIID riid, LPVOID pStart, ULONG cSize, ULONG cCount);
  487. ~StdStaticEnum(void);
  488. IID _iid;
  489. LPVOID _pStart;
  490. ULONG _cSize;
  491. ULONG _cCount;
  492. ULONG _cCurrent;
  493. };
  494. //+---------------------------------------------------------------
  495. //
  496. // Member: StdStaticEnum::StdStaticEnum, private
  497. //
  498. // Synopsis: Constructor for StdStaticEnum objects
  499. //
  500. // Arguments: [riid] -- the enumerator interface that this class is
  501. // "pretending" to be.
  502. // [pStart] -- pointer to the beginning of the static array
  503. // [cSize] -- the size of the elements of the array
  504. // [cCount] -- the number of elements in the array
  505. //
  506. // Notes: Static enumerators should be constructed using the
  507. // CreateStaticEnum function.
  508. //
  509. //----------------------------------------------------------------
  510. StdStaticEnum::StdStaticEnum(REFIID riid,
  511. LPVOID pStart,
  512. ULONG cSize,
  513. ULONG cCount)
  514. {
  515. _ulRefs = 1;
  516. _iid = riid;
  517. _pStart = pStart;
  518. _cSize = cSize;
  519. _cCount = cCount;
  520. _cCurrent = 0;
  521. DOUT(TEXT("StdStaticEnum constructed.\r\n"));
  522. }
  523. //+---------------------------------------------------------------
  524. //
  525. // Member: StdStaticEnum::~StdStaticEnum, private
  526. //
  527. // Synopsis: Destructor for StdStaticEnum objects
  528. //
  529. // Notes: Static enumerators should never be `deleted' but
  530. // instead IUnknown::Release'd.
  531. //
  532. //----------------------------------------------------------------
  533. StdStaticEnum::~StdStaticEnum(void)
  534. {
  535. DOUT(TEXT("StdStaticEnum destructed.\r\n"));
  536. }
  537. IMPLEMENT_STANDARD_IUNKNOWN(StdStaticEnum);
  538. //+---------------------------------------------------------------
  539. //
  540. // Member: StdStaticEnum::QueryInterface, public
  541. //
  542. // Synopsis: Method of IUnknown interface
  543. //
  544. //----------------------------------------------------------------
  545. STDMETHODIMP
  546. StdStaticEnum::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
  547. {
  548. if (IsEqualIID(riid,IID_IUnknown) || IsEqualIID(riid,_iid))
  549. {
  550. *ppvObj = this;
  551. AddRef();
  552. return NOERROR;
  553. }
  554. DOUT(TEXT("StdStaticEnum::QueryInterface E_NOINTERFACE\r\n"));
  555. *ppvObj = NULL;
  556. return E_NOINTERFACE;
  557. }
  558. //+---------------------------------------------------------------
  559. //
  560. // Member: StdStaticEnum::Next
  561. //
  562. // Synopsis: Member of IEnumXXX interface
  563. //
  564. //----------------------------------------------------------------
  565. STDMETHODIMP
  566. StdStaticEnum::Next(ULONG celt,
  567. LPVOID pArrayObjs,
  568. ULONG FAR* pceltFetched)
  569. {
  570. ULONG celtFetched = min(celt, _cCount-_cCurrent);
  571. // calculate the number of bytes to copy
  572. if (celtFetched != 0 && _cSize > (UINT_MAX/celtFetched))
  573. {
  574. DOUT(TEXT("StdStaticEnum::Next E_FAIL\r\n"));
  575. return E_FAIL; // overflow!
  576. }
  577. UINT count = (UINT) (celtFetched*_cSize);
  578. _fmemcpy(pArrayObjs, (LPBYTE)_pStart+_cCurrent*_cSize, count);
  579. _cCurrent += celtFetched;
  580. if (pceltFetched != NULL)
  581. {
  582. *pceltFetched = celtFetched;
  583. }
  584. return ((celtFetched == celt) ? NOERROR : S_FALSE);
  585. }
  586. //+---------------------------------------------------------------
  587. //
  588. // Member: StdStaticEnum::Skip
  589. //
  590. // Synopsis: Member of IEnumXXX interface
  591. //
  592. //----------------------------------------------------------------
  593. STDMETHODIMP
  594. StdStaticEnum::Skip(ULONG celt)
  595. {
  596. _cCurrent += celt;
  597. if (_cCurrent >= _cCount)
  598. {
  599. _cCurrent = _cCount;
  600. return S_FALSE;
  601. }
  602. return NOERROR;
  603. }
  604. //+---------------------------------------------------------------
  605. //
  606. // Member: StdStaticEnum::Reset
  607. //
  608. // Synopsis: Member of IEnumXXX interface
  609. //
  610. //----------------------------------------------------------------
  611. STDMETHODIMP
  612. StdStaticEnum::Reset(void)
  613. {
  614. _cCurrent = 0;
  615. return NOERROR;
  616. }
  617. //+---------------------------------------------------------------
  618. //
  619. // Member: StdStaticEnum::Clone
  620. //
  621. // Synopsis: Member of IEnumXXX interface
  622. //
  623. //----------------------------------------------------------------
  624. STDMETHODIMP
  625. StdStaticEnum::Clone(LPSTDSTATICENUM FAR* ppenm)
  626. {
  627. HRESULT r;
  628. //LPSTDSTATICENUM penum = new (NullOnFail) StdStaticEnum(
  629. LPSTDSTATICENUM penum = new StdStaticEnum(
  630. _iid,
  631. _pStart,
  632. _cSize,
  633. _cCount);
  634. if (penum == NULL)
  635. {
  636. DOUT(TEXT("o2base/StdStaticEnum::Clone failed\r\n"));
  637. r = E_OUTOFMEMORY;
  638. }
  639. else
  640. {
  641. penum->_cCurrent = _cCurrent;
  642. *ppenm = penum;
  643. r = NOERROR;
  644. }
  645. return r;
  646. }
  647. //+---------------------------------------------------------------
  648. //
  649. // Function: CreateStaticEnum, public
  650. //
  651. // Synopsis: Creates a standard enumerator over static arrays
  652. //
  653. // Arguments: [riid] -- the enumerator interface that this class is
  654. // "pretending" to be.
  655. // [pStart] -- pointer to the beginning of the static array
  656. // [cSize] -- the size of the elements of the array
  657. // [cCount] -- the number of elements in the array
  658. // [ppenum] -- where the enumerator is returned
  659. //
  660. // Returns: Success if the enumerator could be successfully created
  661. //
  662. //----------------------------------------------------------------
  663. HRESULT
  664. CreateStaticEnum(REFIID riid,
  665. LPVOID pStart,
  666. ULONG cSize,
  667. ULONG cCount,
  668. LPVOID FAR* ppenum)
  669. {
  670. HRESULT r;
  671. //LPSTDSTATICENUM penum = new (NullOnFail) StdStaticEnum(
  672. LPSTDSTATICENUM penum = new StdStaticEnum(
  673. riid,
  674. pStart,
  675. cSize,
  676. cCount);
  677. if (penum == NULL)
  678. {
  679. DOUT(TEXT("o2base/stdenum/CreateStaticEnum failed\r\n"));
  680. r = E_OUTOFMEMORY;
  681. }
  682. else
  683. {
  684. *ppenum = penum;
  685. r = NOERROR;
  686. }
  687. return r;
  688. }
  689. #endif // 0
  690.