Leaked source code of windows server 2003
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.

502 lines
11 KiB

  1. /*++
  2. Copyright (C) 1993-1999 Microsoft Corporation
  3. Module Name:
  4. idataobj.cpp
  5. Abstract:
  6. Implementation of the IDataObject interface.
  7. --*/
  8. #include "polyline.h"
  9. #include "unkhlpr.h"
  10. // CImpIDataObject interface implmentation
  11. IMPLEMENT_CONTAINED_INTERFACE(CPolyline, CImpIDataObject)
  12. /*
  13. * CImpIDataObject::GetData
  14. *
  15. * Purpose:
  16. * Retrieves data described by a specific FormatEtc into a StgMedium
  17. * allocated by this function. Used like GetClipboardData.
  18. *
  19. * Parameters:
  20. * pFE LPFORMATETC describing the desired data.
  21. * pSTM LPSTGMEDIUM in which to return the data.
  22. *
  23. * Return Value:
  24. * HRESULT NOERROR or a general error value.
  25. */
  26. STDMETHODIMP
  27. CImpIDataObject::GetData(
  28. IN LPFORMATETC pFE,
  29. OUT LPSTGMEDIUM pSTM
  30. )
  31. {
  32. CLIPFORMAT cf;
  33. IStream *pIStream = NULL;
  34. HDC hDevDC = NULL;
  35. HRESULT hr = DATA_E_FORMATETC;
  36. if (pFE == NULL || pSTM == NULL) {
  37. return E_POINTER;
  38. }
  39. try {
  40. cf = pFE->cfFormat;
  41. //
  42. // Use do{}while(0) to act like a switch statement
  43. //
  44. do {
  45. //
  46. //Check the aspects we support.
  47. //
  48. if (!(DVASPECT_CONTENT & pFE->dwAspect)) {
  49. hr = DATA_E_FORMATETC;
  50. break;
  51. }
  52. pSTM->pUnkForRelease = NULL;
  53. //
  54. //Run creates the window to use as a basis for extents
  55. //
  56. m_pObj->m_pImpIRunnableObject->Run(NULL);
  57. //
  58. // Go render the appropriate data for the format.
  59. //
  60. switch (cf)
  61. {
  62. case CF_METAFILEPICT:
  63. pSTM->tymed=TYMED_MFPICT;
  64. hDevDC = CreateTargetDC (NULL, pFE->ptd );
  65. if (hDevDC) {
  66. hr = m_pObj->RenderMetafilePict(&pSTM->hGlobal, hDevDC);
  67. }
  68. else {
  69. hr = E_FAIL;
  70. }
  71. break;
  72. case CF_BITMAP:
  73. pSTM->tymed=TYMED_GDI;
  74. hDevDC = CreateTargetDC (NULL, pFE->ptd );
  75. if (hDevDC) {
  76. hr = m_pObj->RenderBitmap((HBITMAP *)&pSTM->hGlobal, hDevDC);
  77. }
  78. else {
  79. hr = E_FAIL;
  80. }
  81. break;
  82. default:
  83. if (cf == m_pObj->m_cf)
  84. {
  85. hr = CreateStreamOnHGlobal(NULL, TRUE, &pIStream);
  86. if (SUCCEEDED(hr)) {
  87. hr = m_pObj->m_pCtrl->SaveToStream(pIStream);
  88. if (FAILED(hr)) {
  89. pIStream->Release();
  90. }
  91. }
  92. else {
  93. hr = E_OUTOFMEMORY;
  94. }
  95. if (SUCCEEDED(hr)) {
  96. pSTM->tymed = TYMED_ISTREAM;
  97. pSTM->pstm = pIStream;
  98. }
  99. }
  100. break;
  101. }
  102. } while (0);
  103. } catch (...) {
  104. hr = E_POINTER;
  105. }
  106. if (FAILED(hr)) {
  107. if (hDevDC) {
  108. ::DeleteDC(hDevDC);
  109. }
  110. }
  111. return hr;
  112. }
  113. /*
  114. * CImpIDataObject::GetDataHere
  115. *
  116. * Purpose:
  117. * Renders the specific FormatEtc into caller-allocated medium
  118. * provided in pSTM.
  119. *
  120. * Parameters:
  121. * pFE LPFORMATETC describing the desired data.
  122. * pSTM LPSTGMEDIUM providing the medium into which
  123. * wer render the data.
  124. *
  125. * Return Value:
  126. * HRESULT NOERROR or a general error value.
  127. */
  128. STDMETHODIMP
  129. CImpIDataObject::GetDataHere(
  130. IN LPFORMATETC pFE,
  131. IN OUT LPSTGMEDIUM pSTM
  132. )
  133. {
  134. CLIPFORMAT cf;
  135. HRESULT hr = S_OK;
  136. if (pFE == NULL || pSTM == NULL) {
  137. return E_POINTER;
  138. }
  139. /*
  140. * The only reasonable time this is called is for
  141. * CFSTR_EMBEDSOURCE and TYMED_ISTORAGE (and later for
  142. * CFSTR_LINKSOURCE). This means the same as
  143. * IPersistStorage::Save.
  144. */
  145. cf = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_EMBEDSOURCE);
  146. try {
  147. //Aspect is not important to us here, as is lindex and ptd.
  148. if (cf == pFE->cfFormat && (TYMED_ISTORAGE & pFE->tymed))
  149. {
  150. //We have an IStorage we can write into.
  151. pSTM->tymed=TYMED_ISTORAGE;
  152. pSTM->pUnkForRelease=NULL;
  153. hr = m_pObj->m_pImpIPersistStorage->Save(pSTM->pstg, FALSE);
  154. m_pObj->m_pImpIPersistStorage->SaveCompleted(NULL);
  155. }
  156. else {
  157. hr = DATA_E_FORMATETC;
  158. }
  159. } catch (...) {
  160. hr = E_POINTER;
  161. }
  162. return hr;
  163. }
  164. /*
  165. * CImpIDataObject::QueryGetData
  166. *
  167. * Purpose:
  168. * Tests if a call to GetData with this FormatEtc will provide
  169. * any rendering; used like IsClipboardFormatAvailable.
  170. *
  171. * Parameters:
  172. * pFE LPFORMATETC describing the desired data.
  173. *
  174. * Return Value:
  175. * HRESULT NOERROR or a general error value.
  176. */
  177. STDMETHODIMP
  178. CImpIDataObject::QueryGetData(
  179. IN LPFORMATETC pFE
  180. )
  181. {
  182. CLIPFORMAT cf;
  183. BOOL fRet = FALSE;
  184. HRESULT hr = S_OK;
  185. if (pFE == NULL) {
  186. return E_POINTER;
  187. }
  188. try {
  189. cf = pFE->cfFormat;
  190. //
  191. //Check the aspects we support.
  192. //
  193. if (!(DVASPECT_CONTENT & pFE->dwAspect)) {
  194. hr = DATA_E_FORMATETC;
  195. }
  196. else {
  197. switch (cf) {
  198. case CF_METAFILEPICT:
  199. fRet = (BOOL)(pFE->tymed & TYMED_MFPICT);
  200. break;
  201. case CF_BITMAP:
  202. fRet = (BOOL)(pFE->tymed & TYMED_GDI);
  203. break;
  204. default:
  205. //Check our own format.
  206. fRet = ((cf==m_pObj->m_cf) && (BOOL)(pFE->tymed & (TYMED_ISTREAM) ));
  207. break;
  208. }
  209. if (fRet == FALSE) {
  210. hr = DATA_E_FORMATETC;
  211. }
  212. }
  213. } catch (...) {
  214. hr = E_POINTER;
  215. }
  216. return hr;
  217. }
  218. /*
  219. * CImpIDataObject::GetCanonicalFormatEtc
  220. *
  221. * Purpose:
  222. * Provides the caller with an equivalent FormatEtc to the one
  223. * provided when different FormatEtcs will produce exactly the
  224. * same renderings.
  225. *
  226. * Parameters:
  227. * pFEIn LPFORMATETC of the first description.
  228. * pFEOut LPFORMATETC of the equal description.
  229. *
  230. * Return Value:
  231. * HRESULT NOERROR or a general error value.
  232. */
  233. STDMETHODIMP
  234. CImpIDataObject::GetCanonicalFormatEtc(
  235. LPFORMATETC /* pFEIn */,
  236. LPFORMATETC pFEOut
  237. )
  238. {
  239. if (NULL == pFEOut) {
  240. return E_POINTER;
  241. }
  242. try {
  243. pFEOut->ptd = NULL;
  244. } catch (...) {
  245. return E_POINTER;
  246. }
  247. return DATA_S_SAMEFORMATETC;
  248. }
  249. /*
  250. * CImpIDataObject::SetData
  251. *
  252. * Purpose:
  253. * Places data described by a FormatEtc and living in a StgMedium
  254. * into the object. The object may be responsible to clean up the
  255. * StgMedium before exiting.
  256. *
  257. * Parameters:
  258. * pFE LPFORMATETC describing the data to set.
  259. * pSTM LPSTGMEDIUM containing the data.
  260. * fRelease BOOL indicating if this function is responsible
  261. * for freeing the data.
  262. *
  263. * Return Value:
  264. * HRESULT NOERROR or a general error value.
  265. */
  266. STDMETHODIMP CImpIDataObject::SetData(
  267. LPFORMATETC pFE ,
  268. LPSTGMEDIUM pSTM,
  269. BOOL fRelease
  270. )
  271. {
  272. CLIPFORMAT cf;
  273. HRESULT hr = S_OK;
  274. if (pFE == NULL || pSTM == NULL) {
  275. return E_POINTER;
  276. }
  277. try {
  278. cf = pFE->cfFormat;
  279. do {
  280. //
  281. //Check for our own clipboard format and DVASPECT_CONTENT
  282. //
  283. if ((cf != m_pObj->m_cf) || !(DVASPECT_CONTENT & pFE->dwAspect)) {
  284. hr = DATA_E_FORMATETC;
  285. break;
  286. }
  287. //
  288. // The medium must be a stream
  289. //
  290. if (TYMED_ISTREAM != pSTM->tymed) {
  291. hr = DATA_E_FORMATETC;
  292. break;
  293. }
  294. hr = m_pObj->m_pCtrl->LoadFromStream(pSTM->pstm);
  295. } while (0);
  296. if (fRelease)
  297. ReleaseStgMedium(pSTM);
  298. } catch (...) {
  299. hr = E_POINTER;
  300. }
  301. return hr;
  302. }
  303. /*
  304. * CImpIDataObject::EnumFormatEtc
  305. *
  306. * Purpose:
  307. * Returns an IEnumFORMATETC object through which the caller can
  308. * iterate to learn about all the data formats this object can
  309. * provide through either GetData[Here] or SetData.
  310. *
  311. * Parameters:
  312. * dwDir DWORD describing a data direction, either
  313. * DATADIR_SET or DATADIR_GET.
  314. * ppEnum LPENUMFORMATETC * in which to return the
  315. * pointer to the enumerator.
  316. *
  317. * Return Value:
  318. * HRESULT NOERROR or a general error value.
  319. */
  320. STDMETHODIMP
  321. CImpIDataObject::EnumFormatEtc(
  322. DWORD dwDir,
  323. LPENUMFORMATETC *ppEnum
  324. )
  325. {
  326. HRESULT hr = S_OK;
  327. if (ppEnum == NULL) {
  328. return E_POINTER;
  329. }
  330. try {
  331. hr = m_pObj->m_pDefIDataObject->EnumFormatEtc(dwDir, ppEnum);
  332. } catch (...) {
  333. hr = E_POINTER;
  334. }
  335. return hr;
  336. }
  337. /*
  338. * CImpIDataObject::DAdvise
  339. * CImpIDataObject::DUnadvise
  340. * CImpIDataObject::EnumDAdvise
  341. */
  342. STDMETHODIMP
  343. CImpIDataObject::DAdvise(
  344. LPFORMATETC pFE,
  345. DWORD dwFlags,
  346. LPADVISESINK pIAdviseSink,
  347. LPDWORD pdwConn
  348. )
  349. {
  350. HRESULT hr = S_OK;
  351. try {
  352. do {
  353. // Check if requested format is supported
  354. hr = QueryGetData(pFE);
  355. if (FAILED(hr)) {
  356. break;
  357. }
  358. if (NULL == m_pObj->m_pIDataAdviseHolder) {
  359. hr = CreateDataAdviseHolder(&m_pObj->m_pIDataAdviseHolder);
  360. if (FAILED(hr)) {
  361. hr = E_OUTOFMEMORY;
  362. break;
  363. }
  364. }
  365. hr = m_pObj->m_pIDataAdviseHolder->Advise(this,
  366. pFE,
  367. dwFlags,
  368. pIAdviseSink,
  369. pdwConn);
  370. } while (0);
  371. } catch (...) {
  372. hr = E_POINTER;
  373. }
  374. return hr;
  375. }
  376. STDMETHODIMP
  377. CImpIDataObject::DUnadvise(
  378. IN DWORD dwConn
  379. )
  380. {
  381. HRESULT hr;
  382. if (NULL == m_pObj->m_pIDataAdviseHolder) {
  383. return E_FAIL;
  384. }
  385. hr = m_pObj->m_pIDataAdviseHolder->Unadvise(dwConn);
  386. return hr;
  387. }
  388. STDMETHODIMP
  389. CImpIDataObject::EnumDAdvise(
  390. OUT LPENUMSTATDATA *ppEnum
  391. )
  392. {
  393. HRESULT hr = S_OK;
  394. if (ppEnum == NULL) {
  395. return E_POINTER;
  396. }
  397. try {
  398. *ppEnum = NULL;
  399. if (m_pObj->m_pIDataAdviseHolder != NULL) {
  400. hr = m_pObj->m_pIDataAdviseHolder->EnumAdvise(ppEnum);
  401. }
  402. else {
  403. hr = E_FAIL;
  404. }
  405. } catch (...) {
  406. hr = E_POINTER;
  407. }
  408. return hr;
  409. }