home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / ctldata.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  11KB  |  395 lines

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