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.

365 lines
8.6 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. LPFORMATETC pFE,
  29. LPSTGMEDIUM pSTM)
  30. {
  31. CLIPFORMAT cf=pFE->cfFormat;
  32. IStream *pIStream;
  33. HRESULT hr;
  34. HDC hDevDC = NULL;
  35. //Check the aspects we support.
  36. if (!(DVASPECT_CONTENT & pFE->dwAspect))
  37. return ResultFromScode(DATA_E_FORMATETC);
  38. pSTM->pUnkForRelease=NULL;
  39. //Run creates the window to use as a basis for extents
  40. m_pObj->m_pImpIRunnableObject->Run(NULL);
  41. //Go render the appropriate data for the format.
  42. switch (cf)
  43. {
  44. case CF_METAFILEPICT:
  45. pSTM->tymed=TYMED_MFPICT;
  46. hDevDC = CreateTargetDC (NULL, pFE->ptd );
  47. if (hDevDC) {
  48. hr = m_pObj->RenderMetafilePict(&pSTM->hGlobal, hDevDC);
  49. ::DeleteDC(hDevDC);
  50. }
  51. else {
  52. hr = ResultFromScode(E_FAIL);
  53. }
  54. return hr;
  55. case CF_BITMAP:
  56. pSTM->tymed=TYMED_GDI;
  57. hDevDC = CreateTargetDC (NULL, pFE->ptd );
  58. if (hDevDC) {
  59. hr = m_pObj->RenderBitmap((HBITMAP *)&pSTM->hGlobal, hDevDC);
  60. ::DeleteDC(hDevDC);
  61. }
  62. else {
  63. hr = ResultFromScode(E_FAIL);
  64. }
  65. return hr;
  66. default:
  67. if (cf == m_pObj->m_cf)
  68. {
  69. hr = CreateStreamOnHGlobal(NULL, TRUE, &pIStream);
  70. if (FAILED(hr))
  71. return ResultFromScode(E_OUTOFMEMORY);
  72. hr = m_pObj->m_pCtrl->SaveToStream(pIStream);
  73. if (FAILED(hr))
  74. {
  75. pIStream->Release();
  76. return hr;
  77. }
  78. pSTM->tymed = TYMED_ISTREAM;
  79. pSTM->pstm = pIStream;
  80. return NOERROR;
  81. }
  82. break;
  83. }
  84. return ResultFromScode(DATA_E_FORMATETC);
  85. }
  86. /*
  87. * CImpIDataObject::GetDataHere
  88. *
  89. * Purpose:
  90. * Renders the specific FormatEtc into caller-allocated medium
  91. * provided in pSTM.
  92. *
  93. * Parameters:
  94. * pFE LPFORMATETC describing the desired data.
  95. * pSTM LPSTGMEDIUM providing the medium into which
  96. * wer render the data.
  97. *
  98. * Return Value:
  99. * HRESULT NOERROR or a general error value.
  100. */
  101. STDMETHODIMP CImpIDataObject::GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
  102. {
  103. CLIPFORMAT cf;
  104. HRESULT hr;
  105. /*
  106. * The only reasonable time this is called is for
  107. * CFSTR_EMBEDSOURCE and TYMED_ISTORAGE (and later for
  108. * CFSTR_LINKSOURCE). This means the same as
  109. * IPersistStorage::Save.
  110. */
  111. cf=(CLIPFORMAT)RegisterClipboardFormat(CFSTR_EMBEDSOURCE);
  112. //Aspect is unimportant to us here, as is lindex and ptd.
  113. if (cf == pFE->cfFormat && (TYMED_ISTORAGE & pFE->tymed))
  114. {
  115. //We have an IStorage we can write into.
  116. pSTM->tymed=TYMED_ISTORAGE;
  117. pSTM->pUnkForRelease=NULL;
  118. hr = m_pObj->m_pImpIPersistStorage->Save(pSTM->pstg, FALSE);
  119. m_pObj->m_pImpIPersistStorage->SaveCompleted(NULL);
  120. return hr;
  121. }
  122. return ResultFromScode(DATA_E_FORMATETC);
  123. }
  124. /*
  125. * CImpIDataObject::QueryGetData
  126. *
  127. * Purpose:
  128. * Tests if a call to GetData with this FormatEtc will provide
  129. * any rendering; used like IsClipboardFormatAvailable.
  130. *
  131. * Parameters:
  132. * pFE LPFORMATETC describing the desired data.
  133. *
  134. * Return Value:
  135. * HRESULT NOERROR or a general error value.
  136. */
  137. STDMETHODIMP CImpIDataObject::QueryGetData(LPFORMATETC pFE)
  138. {
  139. CLIPFORMAT cf=pFE->cfFormat;
  140. BOOL fRet=FALSE;
  141. //Check the aspects we support.
  142. if (!(DVASPECT_CONTENT & pFE->dwAspect))
  143. return ResultFromScode(DATA_E_FORMATETC);
  144. switch (cf)
  145. {
  146. case CF_METAFILEPICT:
  147. fRet=(BOOL)(pFE->tymed & TYMED_MFPICT);
  148. break;
  149. case CF_BITMAP:
  150. fRet=(BOOL)(pFE->tymed & TYMED_GDI);
  151. break;
  152. default:
  153. //Check our own format.
  154. fRet=((cf==m_pObj->m_cf)
  155. && (BOOL)(pFE->tymed & (TYMED_ISTREAM) ));
  156. break;
  157. }
  158. return fRet ? NOERROR : ResultFromScode(DATA_E_FORMATETC);
  159. }
  160. /*
  161. * CImpIDataObject::GetCanonicalFormatEtc
  162. *
  163. * Purpose:
  164. * Provides the caller with an equivalent FormatEtc to the one
  165. * provided when different FormatEtcs will produce exactly the
  166. * same renderings.
  167. *
  168. * Parameters:
  169. * pFEIn LPFORMATETC of the first description.
  170. * pFEOut LPFORMATETC of the equal description.
  171. *
  172. * Return Value:
  173. * HRESULT NOERROR or a general error value.
  174. */
  175. STDMETHODIMP CImpIDataObject::GetCanonicalFormatEtc
  176. (LPFORMATETC /* pFEIn */, LPFORMATETC pFEOut)
  177. {
  178. if (NULL==pFEOut)
  179. return ResultFromScode(E_INVALIDARG);
  180. pFEOut->ptd=NULL;
  181. return ResultFromScode(DATA_S_SAMEFORMATETC);
  182. }
  183. /*
  184. * CImpIDataObject::SetData
  185. *
  186. * Purpose:
  187. * Places data described by a FormatEtc and living in a StgMedium
  188. * into the object. The object may be responsible to clean up the
  189. * StgMedium before exiting.
  190. *
  191. * Parameters:
  192. * pFE LPFORMATETC describing the data to set.
  193. * pSTM LPSTGMEDIUM containing the data.
  194. * fRelease BOOL indicating if this function is responsible
  195. * for freeing the data.
  196. *
  197. * Return Value:
  198. * HRESULT NOERROR or a general error value.
  199. */
  200. STDMETHODIMP CImpIDataObject::SetData(
  201. LPFORMATETC pFE ,
  202. LPSTGMEDIUM pSTM,
  203. BOOL fRelease
  204. )
  205. {
  206. CLIPFORMAT cf=pFE->cfFormat;
  207. HRESULT hr;
  208. //Check for our own clipboard format and DVASPECT_CONTENT
  209. if ((cf!=m_pObj->m_cf) || !(DVASPECT_CONTENT & pFE->dwAspect))
  210. return ResultFromScode(DATA_E_FORMATETC);
  211. // The medium must be a stream
  212. if (TYMED_ISTREAM != pSTM->tymed)
  213. return ResultFromScode(DATA_E_FORMATETC);
  214. hr = m_pObj->m_pCtrl->LoadFromStream(pSTM->pstm);
  215. if (fRelease)
  216. ReleaseStgMedium(pSTM);
  217. return hr;
  218. }
  219. /*
  220. * CImpIDataObject::EnumFormatEtc
  221. *
  222. * Purpose:
  223. * Returns an IEnumFORMATETC object through which the caller can
  224. * iterate to learn about all the data formats this object can
  225. * provide through either GetData[Here] or SetData.
  226. *
  227. * Parameters:
  228. * dwDir DWORD describing a data direction, either
  229. * DATADIR_SET or DATADIR_GET.
  230. * ppEnum LPENUMFORMATETC * in which to return the
  231. * pointer to the enumerator.
  232. *
  233. * Return Value:
  234. * HRESULT NOERROR or a general error value.
  235. */
  236. STDMETHODIMP CImpIDataObject::EnumFormatEtc(
  237. DWORD dwDir,
  238. LPENUMFORMATETC *ppEnum
  239. )
  240. {
  241. return m_pObj->m_pDefIDataObject->EnumFormatEtc(dwDir, ppEnum);
  242. }
  243. /*
  244. * CImpIDataObject::DAdvise
  245. * CImpIDataObject::DUnadvise
  246. * CImpIDataObject::EnumDAdvise
  247. */
  248. STDMETHODIMP CImpIDataObject::DAdvise(
  249. LPFORMATETC pFE,
  250. DWORD dwFlags,
  251. LPADVISESINK pIAdviseSink,
  252. LPDWORD pdwConn
  253. )
  254. {
  255. HRESULT hr;
  256. // Check if requested format is supported
  257. hr = QueryGetData(pFE);
  258. if (FAILED(hr))
  259. return hr;
  260. if (NULL == m_pObj->m_pIDataAdviseHolder)
  261. {
  262. hr = CreateDataAdviseHolder(&m_pObj->m_pIDataAdviseHolder);
  263. if (FAILED(hr))
  264. return ResultFromScode(E_OUTOFMEMORY);
  265. }
  266. hr = m_pObj->m_pIDataAdviseHolder->Advise(this,
  267. pFE,
  268. dwFlags,
  269. pIAdviseSink,
  270. pdwConn);
  271. return hr;
  272. }
  273. STDMETHODIMP CImpIDataObject::DUnadvise(DWORD dwConn)
  274. {
  275. HRESULT hr;
  276. if (NULL==m_pObj->m_pIDataAdviseHolder)
  277. return ResultFromScode(E_FAIL);
  278. hr=m_pObj->m_pIDataAdviseHolder->Unadvise(dwConn);
  279. return hr;
  280. }
  281. STDMETHODIMP CImpIDataObject::EnumDAdvise(LPENUMSTATDATA *ppEnum)
  282. {
  283. HRESULT hr;
  284. if (NULL==m_pObj->m_pIDataAdviseHolder)
  285. return ResultFromScode(E_FAIL);
  286. hr=m_pObj->m_pIDataAdviseHolder->EnumAdvise(ppEnum);
  287. return hr;
  288. }