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.

655 lines
20 KiB

  1. /*
  2. * dataobject.cxx
  3. *
  4. *
  5. * Copyright (c) 1998-1999 Microsoft Corporation
  6. *
  7. * PURPOSE: Implements the CDataObject class
  8. *
  9. *
  10. * OWNER: ptousig
  11. */
  12. #include <headers.hxx>
  13. // -----------------------------------------------------------------------------
  14. // static variables
  15. UINT CBaseDataObject::s_cfAdminHscopeitem = RegisterClipboardFormat(CF_EXCHANGE_ADMIN_HSCOPEITEM); // The HSCOPEITEM of this node
  16. UINT CBaseDataObject::s_cfMMCSnapinMachineName = RegisterClipboardFormat(CF_MMC_SNAPIN_MACHINE_NAME); // Format supplied by the Computer manager snapin. Passes in the name of the server.
  17. UINT CBaseDataObject::s_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  18. UINT CBaseDataObject::s_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  19. UINT CBaseDataObject::s_cfSzNodeType = RegisterClipboardFormat(CCF_SZNODETYPE);
  20. UINT CBaseDataObject::s_cfSnapinClsid = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  21. UINT CBaseDataObject::s_cfNodeID = RegisterClipboardFormat(CCF_NODEID);
  22. UINT CBaseDataObject::s_cfColumnSetId = RegisterClipboardFormat(CCF_COLUMN_SET_ID);
  23. UINT CBaseDataObject::s_cfMultiSelectionItemTypes = RegisterClipboardFormat(CCF_OBJECT_TYPES_IN_MULTI_SELECT); // Multiselect - list of types for the selected nodes
  24. // -----------------------------------------------------------------------------
  25. HRESULT CBaseDataObject::GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium)
  26. {
  27. DECLARE_SC(sc,_T(""));
  28. Trace(tagBaseSnapinIDataObject, _T("--> %S::IDataObject::GetDataHere(pformatetc->cfFormat=%s)"), SzGetSnapinItemClassName(), SzDebugNameFromFormatEtc(pformatetc->cfFormat));
  29. ADMIN_TRY;
  30. sc=ScGetDataHere(pformatetc, pmedium);
  31. ADMIN_CATCH_HR
  32. Trace(tagBaseSnapinIDataObject, _T("<-- %S::IDataObject::GetDataHere is returning hr=%s"), SzGetSnapinItemClassName(), SzGetDebugNameOfHr(sc.ToHr()));
  33. if (sc == SC(DV_E_FORMATETC) )
  34. {
  35. sc.Clear();
  36. return DV_E_FORMATETC;
  37. }
  38. return(sc.ToHr());
  39. }
  40. // -----------------------------------------------------------------------------
  41. HRESULT CBaseDataObject::GetData(FORMATETC *pformatetc, STGMEDIUM *pmedium)
  42. {
  43. DECLARE_SC(sc,_T(""));
  44. Trace(tagBaseSnapinIDataObject, _T("--> %S::IDataObject::GetData(pformatetc->cfFormat=%s)"), SzGetSnapinItemClassName(), SzDebugNameFromFormatEtc(pformatetc->cfFormat));
  45. ADMIN_TRY;
  46. sc=ScGetData(pformatetc, pmedium);
  47. ADMIN_CATCH_HR
  48. Trace(tagBaseSnapinIDataObject, _T("<-- %S::IDataObject::GetData is returning hr=%s"), SzGetSnapinItemClassName(), SzGetDebugNameOfHr(sc.ToHr()));
  49. if (sc == SC(DV_E_FORMATETC) )
  50. {
  51. sc.Clear();
  52. return DV_E_FORMATETC;
  53. }
  54. return(sc.ToHr());
  55. }
  56. // -----------------------------------------------------------------------------
  57. HRESULT CBaseDataObject::QueryGetData(FORMATETC *pformatetc)
  58. {
  59. DECLARE_SC(sc,_T(""));
  60. Trace(tagBaseSnapinIDataObject, _T("--> %S::IDataObject::QueryGetData(pformatetc->cfFormat=%s)"), SzGetSnapinItemClassName(), SzDebugNameFromFormatEtc(pformatetc->cfFormat));
  61. ADMIN_TRY;
  62. sc=ScQueryGetData(pformatetc);
  63. ADMIN_CATCH_HR
  64. Trace(tagBaseSnapinIDataObject, _T("<-- %S::IDataObject::QueryGetData is returning hr=%s"), SzGetSnapinItemClassName(), SzGetDebugNameOfHr(sc.ToHr()));
  65. return(sc.ToHr());
  66. }
  67. // -----------------------------------------------------------------------------
  68. HRESULT CBaseDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC* ppEnumFormatEtc)
  69. {
  70. DECLARE_SC(sc,_T(""));
  71. Trace(tagBaseSnapinIDataObject, _T("--> %S::IDataObject::EnumFormatEtc(dwDirection=%d)"), SzGetSnapinItemClassName(), dwDirection);
  72. ADMIN_TRY;
  73. sc=ScEnumFormatEtc(dwDirection, ppEnumFormatEtc);
  74. ADMIN_CATCH_HR
  75. Trace(tagBaseSnapinIDataObject, _T("<-- %S::IDataObject::EnumFormatEtc is returning hr=%s"), SzGetSnapinItemClassName(), SzGetDebugNameOfHr(sc.ToHr()));
  76. return(sc.ToHr());
  77. }
  78. // -----------------------------------------------------------------------------
  79. // Renders the data in a preallocated medium.
  80. //
  81. SC CBaseDataObject::ScGetDataHere(FORMATETC *pFormatEtc, STGMEDIUM *pMedium)
  82. {
  83. SC sc = S_OK;
  84. // check parameters
  85. if (pFormatEtc == NULL || pMedium == NULL)
  86. return sc = E_INVALIDARG;
  87. const CLIPFORMAT cf = pFormatEtc->cfFormat;
  88. CComPtr<IStream> spStream;
  89. HGLOBAL hGlobal = NULL;
  90. // see what kind of medium we have
  91. if (pFormatEtc->tymed == TYMED_ISTREAM)
  92. {
  93. // it's a stream
  94. spStream = pMedium->pstm;
  95. if (spStream == NULL)
  96. {
  97. sc = E_UNEXPECTED;
  98. goto Error;
  99. }
  100. }
  101. else if (pFormatEtc->tymed == TYMED_HGLOBAL)
  102. {
  103. // it's hGlobal
  104. hGlobal = pMedium->hGlobal;
  105. sc = CreateStreamOnHGlobal( hGlobal, FALSE, &spStream );
  106. if ( sc )
  107. goto Error; // Minimal error checking
  108. }
  109. else // got the media we do not support
  110. {
  111. sc = DV_E_TYMED;
  112. goto Error;
  113. }
  114. pMedium->tymed = pFormatEtc->tymed;
  115. pMedium->pUnkForRelease = NULL; // by OLE spec
  116. if (cf == s_cfDisplayName )
  117. sc = ScWriteDisplayName( spStream );
  118. else if ( cf == s_cfAdminHscopeitem )
  119. sc = ScWriteAdminHscopeitem( spStream );
  120. else if ( cf == s_cfNodeType )
  121. sc = ScWriteNodeType( spStream );
  122. else if ( cf == s_cfSzNodeType )
  123. sc = ScWriteSzNodeType( spStream );
  124. else if ( cf == s_cfSnapinClsid )
  125. sc = ScWriteClsid( spStream );
  126. else if ( cf == s_cfNodeID )
  127. sc = ScWriteNodeID( spStream );
  128. else if (cf == s_cfColumnSetId )
  129. sc = ScWriteColumnSetId( spStream );
  130. else if ( (cf == s_cfMultiSelectionItemTypes) && FIsMultiSelectDataObject()) // the clipboard format is enabled only for multiselect data objects
  131. sc = ScWriteMultiSelectionItemTypes( spStream );
  132. else if ( cf == CF_TEXT)
  133. sc = ScWriteAnsiName( spStream );
  134. else // Unknown format
  135. {
  136. // we will pretend to suport it for IStream based media (it probably comes from object model)
  137. if (pFormatEtc->tymed == TYMED_ISTREAM)
  138. {
  139. WCHAR szDescription[] = L"Sample Value For Requested Format Of: ";
  140. spStream->Write(szDescription, wcslen(szDescription) * sizeof(WCHAR), NULL);
  141. TCHAR szFormatName[512];
  142. int nChars = GetClipboardFormatName(cf, szFormatName, sizeof(szFormatName) / sizeof(szFormatName[0]));
  143. USES_CONVERSION;
  144. spStream->Write(T2W(szFormatName), nChars * sizeof(WCHAR), NULL);
  145. }
  146. else
  147. {
  148. sc = DV_E_FORMATETC;
  149. goto Cleanup;
  150. }
  151. }
  152. if (sc)
  153. goto Error;
  154. if (pFormatEtc->tymed == TYMED_HGLOBAL)
  155. {
  156. sc = GetHGlobalFromStream(spStream, &hGlobal);
  157. if (sc)
  158. goto Error;
  159. ASSERT(pMedium->hGlobal == NULL || pMedium->hGlobal == hGlobal);
  160. pMedium->hGlobal = hGlobal;
  161. }
  162. Cleanup:
  163. return sc;
  164. Error:
  165. if (sc == E_NOTIMPL)
  166. {
  167. sc = DV_E_FORMATETC; // Format not supported by this node
  168. goto Cleanup;
  169. }
  170. TraceError(_T("CBaseDataObject::GetDataHere"), sc);
  171. goto Cleanup;
  172. }
  173. // -----------------------------------------------------------------------------
  174. // Renders the data in a newly allocated medium.
  175. //
  176. SC CBaseDataObject::ScGetData(FORMATETC *pFormatEtc, STGMEDIUM *pmedium)
  177. {
  178. SC sc = S_OK;
  179. pmedium->tymed = TYMED_HGLOBAL;
  180. pmedium->pUnkForRelease = NULL;
  181. pmedium->hGlobal = NULL;
  182. sc = ScGetDataHere(pFormatEtc, pmedium);
  183. if (sc == SC(DV_E_FORMATETC) )
  184. {
  185. sc.Clear();
  186. return DV_E_FORMATETC;
  187. }
  188. if (sc)
  189. goto Error;
  190. Cleanup:
  191. return sc;
  192. Error:
  193. TraceError(_T("CBaseDataObject::ScGetData"), sc);
  194. if (pmedium->hGlobal)
  195. GlobalFree(pmedium->hGlobal);
  196. pmedium->hGlobal = NULL;
  197. goto Cleanup;
  198. }
  199. // -----------------------------------------------------------------------------
  200. // Asks whether a given format is supported by this data object.
  201. //
  202. SC CBaseDataObject::ScQueryGetData(FORMATETC *pFormatEtc)
  203. {
  204. SC sc = S_OK;
  205. const CLIPFORMAT cf = pFormatEtc->cfFormat;
  206. if ( ( cf == s_cfDisplayName ) ||
  207. ( cf == s_cfNodeType ) ||
  208. ( cf == s_cfSzNodeType ) ||
  209. ( cf == s_cfSnapinClsid ) ||
  210. ( cf == s_cfNodeID ) ||
  211. ( cf == CF_TEXT) ||
  212. ( (cf == s_cfMultiSelectionItemTypes) && FIsMultiSelectDataObject() ) // the clipboard format is enabled only for multiselect data objects
  213. )
  214. {
  215. sc = S_OK; // known and acceptable format
  216. }
  217. else
  218. {
  219. sc = S_FALSE; // unknown or unacceptable format
  220. }
  221. return sc;
  222. }
  223. // -----------------------------------------------------------------------------
  224. // Enumerates available clipboard format supported by this data object.
  225. // Only implemented in DEBUG.
  226. //
  227. SC CBaseDataObject::ScEnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC* ppEnumFormatEtc)
  228. #ifdef DBG
  229. {
  230. SC sc = S_OK;
  231. CComObject<CEnumFormatEtc> *pEnum = NULL;
  232. ASSERT(ppEnumFormatEtc);
  233. sc = CComObject<CEnumFormatEtc>::CreateInstance(&pEnum);
  234. if (!pEnum)
  235. goto MemoryError;
  236. sc = pEnum->QueryInterface(__uuidof(IEnumFORMATETC),(void **) ppEnumFormatEtc );
  237. pEnum = NULL;
  238. if (sc)
  239. goto Error;
  240. Cleanup:
  241. return sc;
  242. MemoryError:
  243. if (pEnum)
  244. delete pEnum;
  245. pEnum = NULL;
  246. Error:
  247. TraceError(_T("CBaseDataObject::ScEnumFormatEtc"), sc);
  248. goto Cleanup;
  249. }
  250. #else
  251. {
  252. return E_NOTIMPL;
  253. }
  254. #endif
  255. // -----------------------------------------------------------------------------
  256. // A convenience function to extract a GUID of the specified clipboard format
  257. // from a dataobject.
  258. //
  259. SC CBaseDataObject::ScGetGUID(UINT cf, LPDATAOBJECT lpDataObject, GUID *pguid)
  260. {
  261. SC sc = S_OK;
  262. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
  263. FORMATETC formatetc = {(CLIPFORMAT)cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  264. BYTE* pb = NULL;
  265. // validate parameters
  266. ASSERT(lpDataObject);
  267. ASSERT(pguid);
  268. // Allocate memory for the stream
  269. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, sizeof(GUID));
  270. if (!stgmedium.hGlobal)
  271. goto MemoryError;
  272. // Attempt to get data from the object
  273. sc = lpDataObject->GetDataHere(&formatetc, &stgmedium);
  274. if (sc == SC(DV_E_FORMATETC) )
  275. {
  276. SC scNoTrace = sc;
  277. sc.Clear();
  278. return scNoTrace;
  279. }
  280. if (sc)
  281. goto Error;
  282. // Copy the GUID into the return buffer
  283. pb = (BYTE*) GlobalLock(stgmedium.hGlobal);
  284. CopyMemory(pguid, pb, sizeof(GUID));
  285. Cleanup:
  286. if (pb)
  287. GlobalUnlock(stgmedium.hGlobal);
  288. if (stgmedium.hGlobal)
  289. {
  290. ASSERT(GlobalFree(stgmedium.hGlobal) == NULL);
  291. }
  292. stgmedium.hGlobal = NULL;
  293. return sc;
  294. MemoryError:
  295. sc = E_OUTOFMEMORY;
  296. Error:
  297. TraceError(_T("CBaseDataObject::ScGetGUID"), sc);
  298. goto Cleanup;
  299. }
  300. // -----------------------------------------------------------------------------
  301. // A convenience function to extract a string of the specified clipboard format
  302. // from a dataobject.
  303. //
  304. SC CBaseDataObject::ScGetString(UINT cf, LPDATAOBJECT lpDataObject, tstring& str)
  305. {
  306. SC sc = S_OK;
  307. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
  308. FORMATETC formatetc = {(CLIPFORMAT)cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  309. BYTE* pb = NULL;
  310. // validate parameters
  311. ASSERT(lpDataObject);
  312. // Allocate memory for the stream
  313. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, str.length());
  314. if (!stgmedium.hGlobal)
  315. goto MemoryError;
  316. // Attempt to get data from the object
  317. sc = lpDataObject->GetData(&formatetc, &stgmedium);
  318. if (sc)
  319. goto Error;
  320. // copy the string into the return buffer
  321. pb = (BYTE*) GlobalLock(stgmedium.hGlobal);
  322. str = (LPTSTR)pb;
  323. Cleanup:
  324. if (pb)
  325. GlobalUnlock(stgmedium.hGlobal);
  326. if (stgmedium.hGlobal)
  327. {
  328. ASSERT(GlobalFree(stgmedium.hGlobal) == NULL);
  329. }
  330. stgmedium.hGlobal = NULL;
  331. return sc;
  332. MemoryError:
  333. sc = E_OUTOFMEMORY;
  334. Error:
  335. TraceError(_T("CBaseDataObject::ScGetString"), sc);
  336. goto Cleanup;
  337. }
  338. // -----------------------------------------------------------------------------
  339. // A convenience function to extract a bool of the specified clipboard format
  340. // from a dataobject.
  341. //
  342. SC CBaseDataObject::ScGetBool(UINT cf, LPDATAOBJECT lpDataObject, BOOL *pf)
  343. {
  344. SC sc = S_OK;
  345. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
  346. FORMATETC formatetc = {(CLIPFORMAT)cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  347. BYTE* pb = NULL;
  348. // validate parameters
  349. ASSERT(lpDataObject);
  350. ASSERT(pf);
  351. // Allocate memory for the stream
  352. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, sizeof(BOOL));
  353. if (!stgmedium.hGlobal)
  354. goto MemoryError;
  355. // Attempt to get data from the object
  356. sc = lpDataObject->GetDataHere(&formatetc, &stgmedium);
  357. if (sc)
  358. goto Error;
  359. // copy the BOOL into the return buffer
  360. pb = (BYTE*) GlobalLock(stgmedium.hGlobal);
  361. CopyMemory(pf, pb, sizeof(BOOL));
  362. Cleanup:
  363. if (pb)
  364. GlobalUnlock(stgmedium.hGlobal);
  365. if (stgmedium.hGlobal)
  366. {
  367. ASSERT(GlobalFree(stgmedium.hGlobal) == NULL);
  368. }
  369. stgmedium.hGlobal = NULL;
  370. return sc;
  371. MemoryError:
  372. sc = E_OUTOFMEMORY;
  373. Error:
  374. TraceError(_T("CBaseDataObject::ScGetBool"), sc);
  375. goto Cleanup;
  376. }
  377. // -----------------------------------------------------------------------------
  378. // A convenience function to extract a dword of the specified clipboard format
  379. // from a dataobject.
  380. //
  381. SC CBaseDataObject::ScGetDword(UINT cf, LPDATAOBJECT lpDataObject, DWORD *pdw)
  382. {
  383. SC sc = S_OK;
  384. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
  385. FORMATETC formatetc = {(CLIPFORMAT)cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  386. BYTE* pb = NULL;
  387. // validate parameters
  388. ASSERT(lpDataObject);
  389. ASSERT(pdw);
  390. // Allocate memory for the stream
  391. stgmedium.hGlobal = GlobalAlloc(GMEM_SHARE, sizeof(DWORD));
  392. if (!stgmedium.hGlobal)
  393. goto MemoryError;
  394. // Attempt to get data from the object
  395. sc = lpDataObject->GetDataHere(&formatetc, &stgmedium);
  396. if (sc)
  397. goto Error;
  398. // copy the DWORD into the return buffer
  399. pb = (BYTE*) GlobalLock(stgmedium.hGlobal);
  400. CopyMemory(pdw, pb, sizeof(DWORD));
  401. Cleanup:
  402. if (pb)
  403. GlobalUnlock(stgmedium.hGlobal);
  404. if (stgmedium.hGlobal)
  405. {
  406. ASSERT(GlobalFree(stgmedium.hGlobal) == NULL);
  407. }
  408. stgmedium.hGlobal = NULL;
  409. return sc;
  410. MemoryError:
  411. sc = E_OUTOFMEMORY;
  412. Error:
  413. TraceError(_T("CBaseDataObject::ScGetDword"), sc);
  414. goto Cleanup;
  415. }
  416. // -----------------------------------------------------------------------------
  417. // A convenience function to extract the SNodeID from a dataobject.
  418. // The SNodeID will be allocated with PvAlloc() and needs to be freed by
  419. // the caller.
  420. //
  421. SC CBaseDataObject::ScGetNodeID(LPDATAOBJECT lpDataObject, SNodeID **ppsnodeid)
  422. {
  423. SC sc = S_OK;
  424. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL, NULL};
  425. FORMATETC formatetc = {(CLIPFORMAT)s_cfNodeID, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  426. BYTE* pb = NULL;
  427. int cb = 0;
  428. SNodeID * psnodeid = NULL;
  429. // validate parameters
  430. ASSERT(lpDataObject);
  431. ASSERT(ppsnodeid);
  432. ASSERT(*ppsnodeid == NULL);
  433. // Attempt to get data from the object
  434. sc = lpDataObject->GetData(&formatetc, &stgmedium);
  435. if (sc)
  436. goto Error;
  437. // Get a pointer to the blob
  438. pb = (BYTE*) GlobalLock(stgmedium.hGlobal);
  439. psnodeid = (SNodeID *) pb;
  440. cb = sizeof(DWORD) + psnodeid->cBytes;
  441. // Allocate a new buffer with PvAlloc
  442. psnodeid = (SNodeID *) GlobalAlloc(GMEM_FIXED, cb);
  443. if (psnodeid == NULL)
  444. goto MemoryError;
  445. CopyMemory(psnodeid, pb, cb);
  446. // Transfer ownership to our caller
  447. *ppsnodeid = psnodeid;
  448. psnodeid = NULL;
  449. Cleanup:
  450. if (pb)
  451. GlobalUnlock(stgmedium.hGlobal);
  452. if (stgmedium.hGlobal)
  453. GlobalFree(stgmedium.hGlobal);
  454. if (psnodeid)
  455. GlobalFree(psnodeid);
  456. return sc;
  457. MemoryError:
  458. sc = E_OUTOFMEMORY;
  459. Error:
  460. TraceError(_T("CBaseDataObject::ScGetNodeID"), sc);
  461. goto Cleanup;
  462. }
  463. // -----------------------------------------------------------------------------
  464. // A convenience function to extract an MMC Column Set ID from a dataobject.
  465. //
  466. SC CBaseDataObject::ScGetColumnSetID(LPDATAOBJECT lpDataObject, SColumnSetID ** ppColumnSetID)
  467. {
  468. SC sc = S_OK;
  469. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
  470. FORMATETC formatetc = {(CLIPFORMAT)s_cfColumnSetId, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  471. BYTE* pb = NULL;
  472. SColumnSetID * pColumnSetID = NULL;
  473. int cb = 0;
  474. // validate parameters
  475. ASSERT(lpDataObject);
  476. ASSERT(ppColumnSetID);
  477. ASSERT(!*ppColumnSetID);
  478. // Attempt to get data from the object
  479. sc = lpDataObject->GetData(&formatetc, &stgmedium);
  480. if (sc)
  481. goto Error;
  482. pb = (BYTE*)GlobalLock(stgmedium.hGlobal);
  483. pColumnSetID = (SColumnSetID *) pb;
  484. cb = sizeof(SColumnSetID) + pColumnSetID->cBytes;
  485. // Allocate a new buffer with PvAlloc
  486. *ppColumnSetID = (SColumnSetID *)GlobalAlloc(GMEM_FIXED, cb);
  487. if (*ppColumnSetID == NULL)
  488. goto MemoryError;
  489. CopyMemory(*ppColumnSetID, pColumnSetID, cb);
  490. Cleanup:
  491. if (pColumnSetID)
  492. GlobalUnlock(stgmedium.hGlobal);
  493. if (stgmedium.hGlobal)
  494. {
  495. ASSERT(GlobalFree(stgmedium.hGlobal) == NULL);
  496. }
  497. stgmedium.hGlobal = NULL;
  498. return sc;
  499. MemoryError:
  500. sc = E_OUTOFMEMORY;
  501. Error:
  502. if(*ppColumnSetID)
  503. delete (*ppColumnSetID);
  504. (*ppColumnSetID) = NULL;
  505. TraceError(_T("CBaseDataObject::ScGetColumnSetID"), sc);
  506. goto Cleanup;
  507. }
  508. // -----------------------------------------------------------------------------
  509. // Returns the name of the clipboard format (debug only)
  510. //
  511. #ifdef DBG
  512. LPTSTR CBaseDataObject::SzDebugNameFromFormatEtc(UINT format)
  513. {
  514. const int cchMaxLine = 256;
  515. static TCHAR s_szName[cchMaxLine];
  516. int ret = 0;
  517. ret = GetClipboardFormatName(format, s_szName, cchMaxLine);
  518. if (ret == 0)
  519. _tcscpy(s_szName, _T("Unknown Clipboard Format"));
  520. return s_szName;
  521. }
  522. #endif
  523. // -----------------------------------------------------------------------------
  524. // Moves to the next available clipboard format (debug only)
  525. //
  526. #ifdef DBG
  527. STDMETHODIMP CEnumFormatEtc::Next(
  528. /* [in] */ ULONG celt,
  529. /* [length_is][size_is][out] */ FORMATETC *rgelt,
  530. /* [out] */ ULONG *pceltFetched)
  531. {
  532. ASSERT(rgelt);
  533. if (celt != 1)
  534. return E_FAIL;
  535. if (m_dwIndex > 0)
  536. return S_FALSE;
  537. if (pceltFetched)
  538. *pceltFetched = 1;
  539. if (rgelt)
  540. {
  541. rgelt->cfFormat = CF_UNICODETEXT;
  542. rgelt->dwAspect = DVASPECT_CONTENT;
  543. rgelt->tymed = TYMED_HGLOBAL;
  544. }
  545. else
  546. return E_INVALIDARG;
  547. m_dwIndex++;
  548. return S_OK;
  549. }
  550. #endif