ctldata.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFXCTL_CORE3_SEG
  12. #pragma code_seg(AFXCTL_CORE3_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. /////////////////////////////////////////////////////////////////////////////
  20. // OCX Support
  21. ////////////////////////////////////////////////////////////////////////////
  22. // _AfxRegisterClipFormat - Registers a custom clipboard format, using the
  23. // string form of a class ID.
  24. CLIPFORMAT AFXAPI _AfxRegisterClipFormat(REFCLSID clsid)
  25. {
  26. TCHAR pszClsid[40];
  27. wsprintf(pszClsid,
  28. _T("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  29. clsid.Data1, clsid.Data2, clsid.Data3,
  30. clsid.Data4[0], clsid.Data4[1], clsid.Data4[2], clsid.Data4[3],
  31. clsid.Data4[4], clsid.Data4[5], clsid.Data4[6], clsid.Data4[7]);
  32. return (CLIPFORMAT)RegisterClipboardFormat(pszClsid);
  33. }
  34. CLIPFORMAT AFXAPI _AfxGetClipboardFormatConvertVBX()
  35. {
  36. static CLIPFORMAT _cfConvertVBX;
  37. if (_cfConvertVBX == 0)
  38. _cfConvertVBX = _AfxRegisterClipFormat(CLSID_ConvertVBX);
  39. ASSERT(_cfConvertVBX != NULL);
  40. return _cfConvertVBX;
  41. }
  42. CLIPFORMAT AFXAPI _AfxGetClipboardFormatPersistPropset()
  43. {
  44. static CLIPFORMAT _cfPersistPropset;
  45. if (_cfPersistPropset == 0)
  46. _cfPersistPropset = _AfxRegisterClipFormat(CLSID_PersistPropset);
  47. ASSERT(_cfPersistPropset != NULL);
  48. return _cfPersistPropset;
  49. }
  50. /////////////////////////////////////////////////////////////////////////////
  51. // AfxOleMatchPropsetClipFormat
  52. BOOL AFXAPI _AfxOleMatchPropsetClipFormat(CLIPFORMAT cfFormat, LPCLSID lpFmtID)
  53. {
  54. if (cfFormat == _AfxGetClipboardFormatPersistPropset())
  55. {
  56. *lpFmtID = CLSID_PersistPropset;
  57. return TRUE;
  58. }
  59. if (cfFormat == _AfxGetClipboardFormatConvertVBX())
  60. {
  61. *lpFmtID = CLSID_ConvertVBX;
  62. return TRUE;
  63. }
  64. return FALSE;
  65. }
  66. /////////////////////////////////////////////////////////////////////////////
  67. // COleControl::XDataObject
  68. STDMETHODIMP_(ULONG) COleControl::XDataObject::AddRef()
  69. {
  70. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  71. return (ULONG)pThis->ExternalAddRef();
  72. }
  73. STDMETHODIMP_(ULONG) COleControl::XDataObject::Release()
  74. {
  75. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  76. return (ULONG)pThis->ExternalRelease();
  77. }
  78. STDMETHODIMP COleControl::XDataObject::QueryInterface(
  79. REFIID iid, LPVOID* ppvObj)
  80. {
  81. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  82. return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
  83. }
  84. STDMETHODIMP COleControl::XDataObject::GetData(LPFORMATETC pformatetcIn,
  85. LPSTGMEDIUM pmedium )
  86. {
  87. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  88. CControlDataSource* pDataSource = pThis->GetDataSource();
  89. if (pDataSource == NULL)
  90. return E_OUTOFMEMORY;
  91. return pDataSource->m_xDataObject.GetData(pformatetcIn, pmedium);
  92. }
  93. STDMETHODIMP COleControl::XDataObject::GetDataHere(LPFORMATETC pformatetc,
  94. LPSTGMEDIUM pmedium )
  95. {
  96. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  97. CControlDataSource* pDataSource = pThis->GetDataSource();
  98. if (pDataSource == NULL)
  99. return E_OUTOFMEMORY;
  100. return pDataSource->m_xDataObject.GetDataHere(pformatetc, pmedium);
  101. }
  102. STDMETHODIMP COleControl::XDataObject::QueryGetData(LPFORMATETC pformatetc )
  103. {
  104. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  105. CControlDataSource* pDataSource = pThis->GetDataSource();
  106. if (pDataSource == NULL)
  107. return E_OUTOFMEMORY;
  108. return pDataSource->m_xDataObject.QueryGetData(pformatetc);
  109. }
  110. STDMETHODIMP COleControl::XDataObject::GetCanonicalFormatEtc(
  111. LPFORMATETC pformatetc, LPFORMATETC pformatetcOut)
  112. {
  113. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  114. CControlDataSource* pDataSource = pThis->GetDataSource();
  115. if (pDataSource == NULL)
  116. return E_OUTOFMEMORY;
  117. return pDataSource->m_xDataObject.GetCanonicalFormatEtc(pformatetc,
  118. pformatetcOut);
  119. }
  120. STDMETHODIMP COleControl::XDataObject::SetData(LPFORMATETC pformatetc,
  121. STGMEDIUM * pmedium, BOOL fRelease)
  122. {
  123. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  124. CControlDataSource* pDataSource = pThis->GetDataSource();
  125. if (pDataSource == NULL)
  126. return E_OUTOFMEMORY;
  127. return pDataSource->m_xDataObject.SetData(pformatetc, pmedium, fRelease);
  128. }
  129. STDMETHODIMP COleControl::XDataObject::EnumFormatEtc(DWORD dwDirection,
  130. LPENUMFORMATETC* ppenumFormatEtc)
  131. {
  132. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  133. CControlDataSource* pDataSource = pThis->GetDataSource();
  134. if (pDataSource == NULL)
  135. return E_OUTOFMEMORY;
  136. return pDataSource->m_xDataObject.EnumFormatEtc(dwDirection,
  137. ppenumFormatEtc);
  138. }
  139. STDMETHODIMP COleControl::XDataObject::DAdvise(FORMATETC* pFormatetc,
  140. DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection)
  141. {
  142. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  143. *pdwConnection = 0;
  144. if (pThis->m_pDataAdviseHolder == NULL &&
  145. CreateDataAdviseHolder(&pThis->m_pDataAdviseHolder) != S_OK)
  146. {
  147. return E_OUTOFMEMORY;
  148. }
  149. ASSERT(pThis->m_pDataAdviseHolder != NULL);
  150. return pThis->m_pDataAdviseHolder->Advise(this, pFormatetc, advf, pAdvSink,
  151. pdwConnection);
  152. }
  153. STDMETHODIMP COleControl::XDataObject::DUnadvise(DWORD dwConnection)
  154. {
  155. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  156. if (pThis->m_pDataAdviseHolder == NULL)
  157. return E_FAIL;
  158. ASSERT(pThis->m_pDataAdviseHolder != NULL);
  159. return pThis->m_pDataAdviseHolder->Unadvise(dwConnection);
  160. }
  161. STDMETHODIMP COleControl::XDataObject::EnumDAdvise(
  162. LPENUMSTATDATA* ppenumAdvise)
  163. {
  164. METHOD_PROLOGUE_EX_(COleControl, DataObject)
  165. *ppenumAdvise = NULL;
  166. if (pThis->m_pDataAdviseHolder == NULL)
  167. return E_FAIL;
  168. ASSERT(pThis->m_pDataAdviseHolder != NULL);
  169. return pThis->m_pDataAdviseHolder->EnumAdvise(ppenumAdvise);
  170. }
  171. /////////////////////////////////////////////////////////////////////////////
  172. // COleControl::CControlDataSource
  173. COleControl::CControlDataSource::CControlDataSource(COleControl* pCtrl) :
  174. m_pCtrl(pCtrl)
  175. {
  176. m_nGrowBy = 4; // By default, control puts 4 entries in cache.
  177. }
  178. BOOL COleControl::CControlDataSource::OnRenderGlobalData(
  179. LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal)
  180. {
  181. ASSERT_VALID(this);
  182. return m_pCtrl->OnRenderGlobalData(lpFormatEtc, phGlobal);
  183. // Note: COleDataSource has no implementation
  184. }
  185. BOOL COleControl::CControlDataSource::OnRenderFileData(
  186. LPFORMATETC lpFormatEtc, CFile* pFile)
  187. {
  188. ASSERT_VALID(this);
  189. return m_pCtrl->OnRenderFileData(lpFormatEtc, pFile);
  190. // Note: COleDataSource has no implementation
  191. }
  192. BOOL COleControl::CControlDataSource::OnRenderData(
  193. LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
  194. {
  195. ASSERT_VALID(this);
  196. if (m_pCtrl->OnRenderData(lpFormatEtc, lpStgMedium))
  197. return TRUE;
  198. return COleDataSource::OnRenderData(lpFormatEtc, lpStgMedium);
  199. }
  200. BOOL COleControl::CControlDataSource::OnSetData(LPFORMATETC lpFormatEtc,
  201. LPSTGMEDIUM lpStgMedium, BOOL bRelease)
  202. {
  203. ASSERT_VALID(this);
  204. return m_pCtrl->OnSetData(lpFormatEtc, lpStgMedium, bRelease);
  205. // Note: COleDataSource has no implementation
  206. }
  207. /////////////////////////////////////////////////////////////////////////////
  208. // COleControl overridables for IDataObject implementation
  209. BOOL COleControl::OnRenderGlobalData(LPFORMATETC lpFormatEtc,
  210. HGLOBAL* phGlobal)
  211. {
  212. #ifndef _DEBUG
  213. UNUSED(lpFormatEtc); // unused in release builds
  214. UNUSED(phGlobal); // unused in release builds
  215. #endif
  216. ASSERT_VALID(this);
  217. ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
  218. ASSERT(AfxIsValidAddress(phGlobal, sizeof(HGLOBAL)));
  219. return FALSE; // default does nothing
  220. }
  221. BOOL COleControl::OnRenderFileData(LPFORMATETC lpFormatEtc, CFile* pFile)
  222. {
  223. #ifndef _DEBUG
  224. UNUSED(lpFormatEtc); // unused in release builds
  225. UNUSED(pFile); // unused in release builds
  226. #endif
  227. ASSERT_VALID(this);
  228. ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC)));
  229. ASSERT_VALID(pFile);
  230. return FALSE; // default does nothing
  231. }
  232. BOOL COleControl::OnRenderData(
  233. LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium)
  234. {
  235. ASSERT_VALID(this);
  236. ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
  237. ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
  238. // default implementation does not support extended layout
  239. if (lpFormatEtc->lindex != -1)
  240. return FALSE;
  241. // default implementation supports CF_METAFILEPICT
  242. if (lpFormatEtc->cfFormat == CF_METAFILEPICT)
  243. return GetMetafileData(lpFormatEtc, lpStgMedium);
  244. // default implementation supports propset format
  245. CLSID fmtid;
  246. if (_AfxOleMatchPropsetClipFormat(lpFormatEtc->cfFormat, &fmtid))
  247. {
  248. return GetPropsetData(lpFormatEtc, lpStgMedium, fmtid);
  249. }
  250. return FALSE; // cfFormat not supported
  251. }
  252. BOOL COleControl::OnSetData(LPFORMATETC lpFormatEtc, LPSTGMEDIUM lpStgMedium,
  253. BOOL bRelease)
  254. {
  255. ASSERT_VALID(this);
  256. ASSERT(AfxIsValidAddress(lpFormatEtc, sizeof(FORMATETC), FALSE));
  257. ASSERT(AfxIsValidAddress(lpStgMedium, sizeof(STGMEDIUM)));
  258. // default implementation supports propset format
  259. BOOL bSuccess = FALSE;
  260. CLSID fmtid;
  261. if (_AfxOleMatchPropsetClipFormat(lpFormatEtc->cfFormat, &fmtid))
  262. {
  263. bSuccess = SetPropsetData(lpFormatEtc, lpStgMedium, fmtid);
  264. if (bSuccess && bRelease)
  265. ReleaseStgMedium(lpStgMedium);
  266. }
  267. return bSuccess;
  268. }
  269. /////////////////////////////////////////////////////////////////////////////
  270. // COleControl::GetDataSource
  271. COleControl::CControlDataSource* COleControl::GetDataSource()
  272. {
  273. TRY
  274. {
  275. if (m_pDataSource == NULL)
  276. {
  277. AFX_MANAGE_STATE(m_pModuleState);
  278. m_pDataSource = new CControlDataSource(this);
  279. ASSERT(m_pDataSource != NULL);
  280. SetInitialDataFormats();
  281. }
  282. }
  283. END_TRY
  284. return m_pDataSource;
  285. }
  286. /////////////////////////////////////////////////////////////////////////////
  287. // COleControl::SetInitialDataFormats
  288. void COleControl::SetInitialDataFormats()
  289. {
  290. // by default a COleControl supports CF_METAFILEPICT
  291. FORMATETC formatEtc;
  292. formatEtc.cfFormat = CF_METAFILEPICT;
  293. formatEtc.ptd = NULL;
  294. formatEtc.dwAspect = DVASPECT_CONTENT;
  295. formatEtc.lindex = -1;
  296. formatEtc.tymed = TYMED_MFPICT;
  297. m_pDataSource->DelayRenderData(0, &formatEtc);
  298. // by default a COleControl supports persistent propset format
  299. // (GetData or SetData)
  300. formatEtc.cfFormat = _AfxGetClipboardFormatPersistPropset();
  301. formatEtc.ptd = NULL;
  302. formatEtc.dwAspect = DVASPECT_CONTENT;
  303. formatEtc.lindex = -1;
  304. formatEtc.tymed = TYMED_ISTREAM | TYMED_ISTORAGE;
  305. m_pDataSource->DelayRenderData(0, &formatEtc);
  306. m_pDataSource->DelaySetData(0, &formatEtc);
  307. // by default a COleControl supports VBX conversion propset format
  308. // (SetData only)
  309. formatEtc.cfFormat = _AfxGetClipboardFormatConvertVBX();
  310. m_pDataSource->DelaySetData(0, &formatEtc);
  311. }
  312. /////////////////////////////////////////////////////////////////////////////
  313. // Force any extra compiler-generated code into AFX_INIT_SEG
  314. #ifdef AFX_INIT_SEG
  315. #pragma code_seg(AFX_INIT_SEG)
  316. #endif