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.

733 lines
21 KiB

  1. /************************************************************************
  2. ** _ D B D A O . H *
  3. ** *
  4. *************************************************************************
  5. ** Copyright (C) 1996 by Microsoft Corporation *
  6. ** All Rights Reserved *
  7. ************************************************************************/
  8. /*
  9. _DBDAO.H
  10. Internal definitions and prototypes for dbdao C++ classes
  11. */
  12. #ifndef __DBDAO_H_
  13. #define __DBDAO_H_
  14. /*****************************************************************************
  15. * Forwards
  16. */
  17. class COleVariant;
  18. class CdbBookmark;
  19. class CdbException;
  20. class CdbOleObject;
  21. class CdbObject;
  22. class CdbError;
  23. class CdbProperty;
  24. class CdbDBEngine;
  25. class CdbWorkspace;
  26. class CdbDatabase;
  27. class CdbConnection;
  28. class CdbRecordset;
  29. class CdbGetRowsEx;
  30. class CdbQueryDef;
  31. class CdbTableDef;
  32. class CdbField;
  33. class CdbRelation;
  34. class CdbIndex;
  35. class CdbUser;
  36. class CdbGroup;
  37. class CdbDocument;
  38. class CdbContainer;
  39. class CdbParameter;
  40. class CdbCollection;
  41. class CdbErrors;
  42. class CdbProperties;
  43. class CdbWorkspaces;
  44. class CdbDatabases;
  45. class CdbConnections;
  46. class CdbRecordsets;
  47. class CdbQueryDefs;
  48. class CdbTableDefs;
  49. class CdbFields;
  50. class CdbRelations;
  51. class CdbIndexes;
  52. class CdbUsers;
  53. class CdbGroups;
  54. class CdbDocuments;
  55. class CdbContainers;
  56. class CdbParameters;
  57. class CdbBStr;
  58. /*****************************************************************************
  59. * DAO runtime key
  60. */
  61. const char szKEY[] = "mbmabptebkjcdlgtjmskjwtsdhjbmkmwtrak";
  62. /*****************************************************************************
  63. * Miscellaneous defines
  64. */
  65. #define DAO_MAXSEEKFIELDS 13
  66. /*****************************************************************************
  67. * CdbBSTR (OLE BSTR helper)
  68. */
  69. class DLLEXPORT CdbBSTR
  70. {
  71. public:
  72. CONSTRUCTOR CdbBSTR (BSTR=NULL);
  73. DESTRUCTOR ~CdbBSTR (VOID);
  74. operator BSTR * (VOID);
  75. operator LPCTSTR (VOID);
  76. private:
  77. BSTR m_bstr;
  78. };
  79. /*****************************************************************************
  80. * CdbVariant (OLE Variant helper)
  81. */
  82. class CdbVariant : public COleVariant
  83. {
  84. public:
  85. CONSTRUCTOR CdbVariant (LONG l);
  86. CONSTRUCTOR CdbVariant (VOID);
  87. CONSTRUCTOR CdbVariant (LPCTSTR pstr);
  88. CONSTRUCTOR CdbVariant (SHORT s, BOOL bIsBool = FALSE);
  89. CONSTRUCTOR CdbVariant (LPVARIANT pv);
  90. CONSTRUCTOR CdbVariant (LPSAFEARRAY psa);
  91. VOID operator = (LPVARIANT pv);
  92. VOID operator = (LPCTSTR pstr);
  93. VOID operator = (SHORT s);
  94. VOID operator = (const int i);
  95. VOID operator = (LONG l);
  96. };
  97. inline CONSTRUCTOR CdbVariant::CdbVariant(
  98. VOID) : COleVariant()
  99. {
  100. vt = VT_ERROR;
  101. scode = DISP_E_PARAMNOTFOUND;
  102. }
  103. inline CdbVariant::CdbVariant (LONG l)
  104. {
  105. if (l == -1)
  106. {
  107. vt = VT_ERROR;
  108. scode = DISP_E_PARAMNOTFOUND;
  109. }
  110. else
  111. {
  112. vt = VT_I4;
  113. lVal = l;
  114. }
  115. }
  116. inline CONSTRUCTOR CdbVariant::CdbVariant(
  117. LPCTSTR pstr): COleVariant(pstr,VT_BSTRT)
  118. {
  119. if (!pstr)
  120. {
  121. VariantClear(this);
  122. vt = VT_ERROR;
  123. scode = DISP_E_PARAMNOTFOUND;
  124. }
  125. }
  126. inline CONSTRUCTOR CdbVariant::CdbVariant(
  127. SHORT s, BOOL bIsBool) : COleVariant(s)
  128. {
  129. if (bIsBool)
  130. {
  131. vt = VT_BOOL;
  132. boolVal = s;
  133. }
  134. else if (s==-1)
  135. {
  136. vt = VT_ERROR;
  137. scode = DISP_E_PARAMNOTFOUND;
  138. }
  139. }
  140. inline CONSTRUCTOR CdbVariant::CdbVariant(
  141. LPVARIANT pv)
  142. {
  143. if (!pv)
  144. {
  145. vt = VT_ERROR;
  146. scode = DISP_E_PARAMNOTFOUND;
  147. }
  148. else
  149. VariantCopy(this, pv);
  150. }
  151. inline CONSTRUCTOR CdbVariant::CdbVariant(
  152. LPSAFEARRAY psa)
  153. {
  154. if (!psa)
  155. {
  156. vt = VT_ERROR;
  157. scode = DISP_E_PARAMNOTFOUND;
  158. }
  159. else
  160. {
  161. vt = VT_ARRAY|VT_UI1;
  162. parray = psa;
  163. }
  164. }
  165. inline VOID CdbVariant::operator =(
  166. LPVARIANT pv)
  167. {
  168. if (!pv)
  169. {
  170. vt = VT_ERROR;
  171. scode = DISP_E_PARAMNOTFOUND;
  172. }
  173. else
  174. VariantCopy(this, pv);
  175. }
  176. inline VOID CdbVariant::operator =(
  177. LPCTSTR pstr)
  178. {
  179. if (!pstr)
  180. {
  181. VariantClear(this);
  182. vt = VT_ERROR;
  183. scode = DISP_E_PARAMNOTFOUND;
  184. }
  185. else
  186. {
  187. #ifdef UNICODE
  188. bstrVal = SysAllocString(pstr);
  189. #else
  190. bstrVal = SysAllocStringByteLen(pstr, strlen(pstr));
  191. #endif
  192. vt = VT_BSTR;
  193. }
  194. }
  195. inline VOID CdbVariant::operator =(
  196. SHORT s)
  197. {
  198. if (s==-1)
  199. {
  200. vt = VT_ERROR;
  201. scode = DISP_E_PARAMNOTFOUND;
  202. }
  203. else
  204. {
  205. vt = VT_I2;
  206. iVal = s;
  207. }
  208. }
  209. inline VOID CdbVariant::operator =(
  210. const int i)
  211. {
  212. if (i==-1)
  213. {
  214. vt = VT_ERROR;
  215. scode = DISP_E_PARAMNOTFOUND;
  216. }
  217. else
  218. {
  219. vt = VT_I2;
  220. iVal = (SHORT)i;
  221. }
  222. }
  223. inline VOID CdbVariant::operator =(
  224. LONG l)
  225. {
  226. if (l==-1)
  227. {
  228. vt = VT_ERROR;
  229. scode = DISP_E_PARAMNOTFOUND;
  230. }
  231. else
  232. {
  233. vt = VT_I4;
  234. lVal = l;
  235. }
  236. }
  237. /*****************************************************************************
  238. * CdbWide
  239. */
  240. HRESULT CdbWideFromAnsi(LPSTR, unsigned int, BSTR *);
  241. class CdbWide
  242. {
  243. public:
  244. CONSTRUCTOR CdbWide (LPSTR pstr, unsigned int cb=0)
  245. {
  246. CdbWideFromAnsi(pstr, (pstr ? (cb==0 ? strlen(pstr) : cb) : 0), &m_bstr);
  247. }
  248. DESTRUCTOR ~CdbWide ()
  249. {
  250. SysFreeString(m_bstr);
  251. }
  252. operator LPWSTR ()
  253. {
  254. return (LPWSTR)m_bstr;
  255. }
  256. operator LPSTR ()
  257. {
  258. return (LPSTR)m_bstr;
  259. }
  260. ULONG cBytes ()
  261. {
  262. return SysStringByteLen(m_bstr);
  263. }
  264. private:
  265. BSTR m_bstr;
  266. };
  267. /*****************************************************************************
  268. * CdbOleObject
  269. */
  270. class DLLEXPORT CdbOleObject : public CObject
  271. {
  272. public:
  273. CONSTRUCTOR CdbOleObject (VOID);
  274. virtual DESTRUCTOR ~CdbOleObject (VOID);
  275. BOOL Exists (VOID);
  276. CdbOleObject & operator = (CdbOleObject &o);
  277. operator LPUNKNOWN (){ return GetInterface();}
  278. VOID SetInterface (LPUNKNOWN punk, BOOL bAddRef=FALSE);
  279. VOID SetInterface (REFIID riidClass, REFIID riidInterface);
  280. VOID SetInterfaceLic (REFIID riidClass, REFIID riidInterface);
  281. LPUNKNOWN GetInterface (BOOL bAddRef=FALSE, BOOL bThrowException=TRUE) const;
  282. virtual VOID OnInterfaceChange (VOID);
  283. VOID SetRichErrorInfo (LPOLESTR pstrSource, LPOLESTR pstrDescription, LPOLESTR pstrHelpFile, ULONG ulHelpID) const;
  284. protected:
  285. BOOL StartOLE (VOID);
  286. LPUNKNOWN m_punkInterface;
  287. };
  288. /*****************************************************************************
  289. * CdbCollection
  290. */
  291. class DLLEXPORT CdbCollection : public CdbOleObject
  292. {
  293. public:
  294. // Methods
  295. virtual CdbObject ObItem (LONG i) = 0;
  296. virtual CdbObject ObItem (LPCTSTR pstr) = 0;
  297. virtual LONG GetCount (VOID) = 0;
  298. virtual VOID ObAppend (CdbObject &obj) = 0;
  299. virtual VOID Delete (LPCTSTR pstr) = 0;
  300. virtual VOID Refresh (VOID) = 0;
  301. };
  302. class DLLEXPORT CdbStaticCollection : public CdbCollection
  303. {
  304. public:
  305. CdbObject ObItem (LONG i);
  306. CdbObject ObItem (LPCTSTR pstr);
  307. LONG GetCount (VOID);
  308. VOID ObAppend (CdbObject &obj);
  309. VOID Delete (LPCTSTR pstr);
  310. VOID Refresh (VOID) ;
  311. };
  312. class DLLEXPORT CdbDynamicCollection : public CdbCollection
  313. {
  314. public:
  315. CdbObject ObItem (LONG i);
  316. CdbObject ObItem (LPCTSTR pstr);
  317. LONG GetCount (VOID);
  318. VOID ObAppend (CdbObject &obj);
  319. VOID Delete (LPCTSTR pstr);
  320. VOID Refresh (VOID);
  321. };
  322. #define DAOMFC_STATIC_COLLECTION_DECL(objColl, objSingle, intSingle) \
  323. class DLLEXPORT objColl : public CdbStaticCollection \
  324. { \
  325. public: \
  326. \
  327. objSingle Item (LONG i); \
  328. objSingle Item (LPCTSTR pstr); \
  329. objSingle operator[] (LONG i); \
  330. objSingle operator[] (LPCTSTR pstr); \
  331. }
  332. #define DAOMFC_DYNAMIC_COLLECTION_DECL(objColl, objSingle, intSingle) \
  333. class DLLEXPORT objColl : public CdbDynamicCollection \
  334. { \
  335. public: \
  336. \
  337. objSingle Item (LONG i); \
  338. objSingle Item (LPCTSTR pstr); \
  339. VOID Append (objSingle &o); \
  340. objSingle operator[] (LONG i); \
  341. objSingle operator[] (LPCTSTR pstr); \
  342. }
  343. DAOMFC_STATIC_COLLECTION_DECL(CdbErrors, CdbError, DAOError);
  344. DAOMFC_STATIC_COLLECTION_DECL(CdbDatabases, CdbDatabase, DAODatabase);
  345. //Connections are special cased so we can trap the copy constructor
  346. DAOMFC_STATIC_COLLECTION_DECL(CdbRecordsets, CdbRecordset, DAORecordset);
  347. DAOMFC_STATIC_COLLECTION_DECL(CdbParameters, CdbParameter, DAOParameter);
  348. DAOMFC_STATIC_COLLECTION_DECL(CdbDocuments, CdbDocument, DAODocument);
  349. DAOMFC_STATIC_COLLECTION_DECL(CdbContainers, CdbContainer, DAOContainer);
  350. DAOMFC_DYNAMIC_COLLECTION_DECL(CdbProperties, CdbProperty, DAOProperty);
  351. DAOMFC_DYNAMIC_COLLECTION_DECL(CdbFields, CdbField, DAOField);
  352. DAOMFC_DYNAMIC_COLLECTION_DECL(CdbQueryDefs, CdbQueryDef, DAOQueryDef);
  353. DAOMFC_DYNAMIC_COLLECTION_DECL(CdbTableDefs, CdbTableDef, DAOTableDef);
  354. DAOMFC_DYNAMIC_COLLECTION_DECL(CdbIndexes, CdbIndex, DAOIndex);
  355. DAOMFC_DYNAMIC_COLLECTION_DECL(CdbRelations, CdbRelation, DAORelation);
  356. DAOMFC_DYNAMIC_COLLECTION_DECL(CdbUsers, CdbUser, DAOUser);
  357. DAOMFC_DYNAMIC_COLLECTION_DECL(CdbGroups, CdbGroup, DAOGroup);
  358. //Need some extra functions in CdbWorkspaces to support the delay in creating the
  359. //default workspace needed to support the JET/ODBC option.
  360. class DLLEXPORT CdbWorkspaces : public CdbDynamicCollection
  361. {
  362. friend CdbDBEngine;
  363. private:
  364. DAODBEngine * pDBEng;
  365. BOOL m_bDontStart;
  366. public:
  367. CONSTRUCTOR CdbWorkspaces (VOID){pDBEng = NULL;}
  368. CdbWorkspace Item (LONG i);
  369. CdbWorkspace Item (LPCTSTR pstr);
  370. VOID Append (CdbWorkspace &o);
  371. CdbWorkspace operator[] (LONG i);
  372. CdbWorkspace operator[] (LPCTSTR pstr);
  373. VOID SetDBEngine (DAODBEngine *peng){pDBEng = peng;}
  374. VOID GetDelayedInterface ();
  375. };
  376. //Need to trap Connections in the copy constructor so the user can't
  377. //get a "sorta-kinda" working Connections collection on a Jet workspace
  378. class DLLEXPORT CdbConnections : public CdbStaticCollection
  379. {
  380. public:
  381. CONSTRUCTOR CdbConnections (CdbConnections &Connections);
  382. CONSTRUCTOR CdbConnections (){pwrk = NULL;}
  383. CdbConnection Item (LONG i);
  384. CdbConnection Item (LPCTSTR pstr);
  385. CdbConnection operator[] (LONG i);
  386. CdbConnection operator[] (LPCTSTR pstr);
  387. CdbConnections & operator = (CdbConnections &o);
  388. LONG GetCount (VOID);
  389. VOID Refresh (VOID) ;
  390. VOID SetWorkspace (DAOWorkspace * pParent){pwrk = pParent;}
  391. private:
  392. VOID CheckInterface();
  393. DAOWorkspace * pwrk;
  394. };
  395. /*****************************************************************************
  396. * CdbObject
  397. */
  398. class DLLEXPORT CdbObject : public CdbOleObject
  399. {
  400. public:
  401. CONSTRUCTOR CdbObject (VOID);
  402. CONSTRUCTOR CdbObject (LPUNKNOWN punk, BOOL bAddRef=FALSE);
  403. virtual CString GetName (VOID);
  404. virtual VOID SetName (LPCTSTR pstr);
  405. CdbProperties Properties;
  406. };
  407. /*****************************************************************************
  408. * CdbGetRowsEx (holds GetRowsEx for Recordset)
  409. */
  410. class DLLEXPORT CdbGetRowsEx : public CdbObject
  411. {
  412. public:
  413. // Administration
  414. CONSTRUCTOR CdbGetRowsEx (VOID);
  415. CONSTRUCTOR CdbGetRowsEx (ICDAORecordset *pGetRows, BOOL bAddRef=FALSE);
  416. CONSTRUCTOR CdbGetRowsEx (const CdbGetRowsEx &);
  417. CdbGetRowsEx & operator = (const CdbGetRowsEx &);
  418. VOID OnInterfaceChange (VOID);
  419. };
  420. /*****************************************************************************
  421. * Helper macros
  422. */
  423. //Initialize a variant
  424. #define DAOVINIT(var) \
  425. do \
  426. { \
  427. (var).vt = VT_ERROR; \
  428. (var).scode = DISP_E_PARAMNOTFOUND; \
  429. } \
  430. while (0)
  431. // LPTSTR to VARIANT
  432. #define STV(pstr) CdbVariant(pstr)
  433. // LPTSTR to BSTR
  434. #define STB(pstr) V_BSTR(((LPVARIANT)STV(pstr)))
  435. // LONG to VARIANT
  436. #define LTV(l) CdbVariant(l)
  437. // Optional LONG to VARIANT
  438. #define OLTV(l) CdbVariant((l))
  439. // C/C++ bool to DAO bool
  440. #define BTB(b) ((VARIANT_BOOL)(b?-1:0))
  441. // C/C++ bool to VARIANT
  442. #define BTV(b) CdbVariant(BTB(b), TRUE)
  443. // C/C++ short to VARIANT
  444. #define SHTV(s) CdbVariant((SHORT)s)
  445. // OLE variant to VARIANT
  446. #define VTV(pv) CdbVariant(pv)
  447. // SAFEARRAY to VARIANT
  448. #define ATV(psa, var) \
  449. do \
  450. { \
  451. if (!psa) \
  452. { \
  453. var.vt = VT_ERROR; \
  454. var.scode = DISP_E_PARAMNOTFOUND; \
  455. } \
  456. else \
  457. { \
  458. var.vt = VT_ARRAY|VT_UI1; \
  459. SafeArrayCopy(psa, &var.parray); \
  460. } \
  461. } \
  462. while (0)
  463. #define DAOMFC_CALL(hr) \
  464. do \
  465. { \
  466. HRESULT hresult = (hr); \
  467. if(FAILED(hresult)) \
  468. { \
  469. TRACE0("\nDBDAO Call Failed.\n\t"); \
  470. TRACE2("\nIn file %s on line %d\n", _T("DBDAO.CPP"), __LINE__); \
  471. TRACE1("hResult = %X\n", hresult); \
  472. if (GetScode(hresult) == E_OUTOFMEMORY) \
  473. AfxThrowMemoryException(); \
  474. else \
  475. throw CdbException(hresult); \
  476. } \
  477. } while (0)
  478. /*****************************************************************************
  479. * Property Set/Get helper macros
  480. */
  481. // Get a LONG property
  482. #define LPROPGET(intDAO, meth) \
  483. do \
  484. { \
  485. intDAO * p = (intDAO *)GetInterface(); \
  486. LONG l = 0; \
  487. \
  488. DAOMFC_CALL(p->meth(&l)); \
  489. \
  490. return l; \
  491. } \
  492. while (0)
  493. // Set a LONG property
  494. #define LPROPSET(intDAO, meth, l) \
  495. do \
  496. { \
  497. intDAO * p = (intDAO *)GetInterface(); \
  498. \
  499. DAOMFC_CALL(p->meth(l)); \
  500. } \
  501. while(0)
  502. // Get a SHORT property
  503. #define WPROPGET(intDAO, meth) \
  504. do \
  505. { \
  506. intDAO * p = (intDAO *)GetInterface(); \
  507. SHORT s = 0; \
  508. \
  509. DAOMFC_CALL(p->meth(&s)); \
  510. \
  511. return s; \
  512. } \
  513. while (0)
  514. // Set a SHORT property
  515. #define WPROPSET(intDAO, meth, s) \
  516. do \
  517. { \
  518. intDAO * p = (intDAO *)GetInterface(); \
  519. \
  520. DAOMFC_CALL(p->meth(s)); \
  521. } \
  522. while(0)
  523. // Get a STRING property
  524. #define SPROPGET(intDAO, meth) \
  525. do \
  526. { \
  527. intDAO * p = (intDAO *)GetInterface(); \
  528. CdbBSTR bstr; \
  529. \
  530. DAOMFC_CALL(p->meth(bstr)); \
  531. \
  532. return bstr; \
  533. } \
  534. while (0)
  535. // Set a STRING property
  536. #define SPROPSET(intDAO, meth, s) \
  537. do \
  538. { \
  539. intDAO * p = (intDAO *)GetInterface(); \
  540. \
  541. DAOMFC_CALL(p->meth(STB(s))); \
  542. } \
  543. while(0)
  544. // Get a DATETIME property
  545. #define DPROPGET(intDAO, meth) \
  546. do \
  547. { \
  548. intDAO * p = (intDAO *)GetInterface(); \
  549. VARIANT Var; \
  550. \
  551. VariantInit(&Var); \
  552. DAOMFC_CALL(p->meth(&Var)); \
  553. return Var; \
  554. } \
  555. while (0)
  556. // Set a DATETIME property
  557. #define DPROPSET(intDAO, meth, pv) \
  558. do \
  559. { \
  560. intDAO * p = (intDAO *)GetInterface(); \
  561. \
  562. DAOMFC_CALL(p->meth(*pv)); \
  563. } \
  564. while(0)
  565. // Get a BOOLEAN property
  566. #define BPROPGET(intDAO, meth) \
  567. do \
  568. { \
  569. intDAO * p = (intDAO *)GetInterface(); \
  570. VARIANT_BOOL vb = 0; \
  571. \
  572. DAOMFC_CALL(p->meth(&vb)); \
  573. \
  574. return (BOOL)vb; \
  575. } \
  576. while (0)
  577. // Set a BOOLEAN property
  578. #define BPROPSET(intDAO, meth, b) \
  579. do \
  580. { \
  581. intDAO * p = (intDAO *)GetInterface(); \
  582. \
  583. DAOMFC_CALL(p->meth(BTB(b))); \
  584. } \
  585. while(0)
  586. // Get a VARIANT property
  587. #define VPROPGET(intDAO, meth) \
  588. do \
  589. { \
  590. intDAO * p = (intDAO *)GetInterface(); \
  591. COleVariant v; \
  592. \
  593. VariantInit(&v); \
  594. DAOMFC_CALL(p->meth(&v)); \
  595. \
  596. return &v; \
  597. } \
  598. while (0)
  599. // Set a VARIANT property
  600. #define VPROPSET(intDAO, meth, pv) \
  601. do \
  602. { \
  603. intDAO * p = (intDAO *)GetInterface(); \
  604. \
  605. DAOMFC_CALL(p->meth(*pv)); \
  606. } \
  607. while(0)
  608. // Get a DWORD property
  609. #define DWPROPGET(intDAO, meth) \
  610. do \
  611. { \
  612. intDAO * p = (intDAO *)GetInterface(); \
  613. DWORD dw = 0; \
  614. \
  615. DAOMFC_CALL(p->meth(&dw)); \
  616. \
  617. return dw; \
  618. } \
  619. while (0)
  620. #define DAOMFC_STATIC_COLLECTION_IMPL(objColl, objSingle, intColl, intSingle) \
  621. objSingle objColl::Item (LONG i) { return (intSingle *)(ObItem(i).GetInterface(TRUE)); } \
  622. objSingle objColl::Item (LPCTSTR pstr) { return (intSingle *)(ObItem(pstr).GetInterface(TRUE)); } \
  623. objSingle objColl::operator[] (LONG i) { return (intSingle *)(Item(i).GetInterface(TRUE)); } \
  624. objSingle objColl::operator[] (LPCTSTR pstr) { return (intSingle *)(Item(pstr).GetInterface(TRUE)); }
  625. #define DAOMFC_DYNAMIC_COLLECTION_IMPL(objColl, objSingle, intColl, intSingle) \
  626. objSingle objColl::Item (LONG i) { return (intSingle *)(ObItem(i).GetInterface(TRUE)); } \
  627. objSingle objColl::Item (LPCTSTR pstr) { return (intSingle *)(ObItem(pstr).GetInterface(TRUE)); } \
  628. VOID objColl::Append (objSingle &o) { ObAppend(o); } \
  629. objSingle objColl::operator[] (LONG i) { return (intSingle *)(Item(i).GetInterface(TRUE)); } \
  630. objSingle objColl::operator[] (LPCTSTR pstr) { return (intSingle *)(Item(pstr).GetInterface(TRUE)); }
  631. DECLARE_INTERFACE_(DAOMFCSCollection, _DAOCollection)
  632. {
  633. STDMETHOD(get_Item) (VARIANT index, LPUNKNOWN *ppunk);
  634. };
  635. DECLARE_INTERFACE_(DAOMFCDCollection, _DAODynaCollection)
  636. {
  637. STDMETHOD(get_Item) (VARIANT index, LPUNKNOWN *ppunk);
  638. };
  639. #endif // __DBDAO_H_