home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap21 / cosmo / idataobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  8.7 KB  |  370 lines

  1. /*
  2.  * IDATAOBJ.CPP
  3.  * Cosmo Chapter 21
  4.  *
  5.  * Implementation of the IDataObject interface.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #include "cosmo.h"
  16.  
  17.  
  18. /*
  19.  * CImpIDataObject::CImpIDataObject
  20.  * CImpIDataObject::~CImpIDataObject
  21.  *
  22.  * Parameters (Constructor):
  23.  *  pObj            PCFigure of the object we're in.
  24.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  25.  */
  26.  
  27. CImpIDataObject::CImpIDataObject(PCFigure pObj
  28.     , LPUNKNOWN pUnkOuter)
  29.     {
  30.     m_cRef=0;
  31.     m_pObj=pObj;
  32.     m_pUnkOuter=pUnkOuter;
  33.     return;
  34.     }
  35.  
  36. CImpIDataObject::~CImpIDataObject(void)
  37.     {
  38.     return;
  39.     }
  40.  
  41.  
  42.  
  43.  
  44. /*
  45.  * CImpIDataObject::QueryInterface
  46.  * CImpIDataObject::AddRef
  47.  * CImpIDataObject::Release
  48.  */
  49.  
  50. STDMETHODIMP CImpIDataObject::QueryInterface(REFIID riid, PPVOID ppv)
  51.     {
  52.     return m_pUnkOuter->QueryInterface(riid, ppv);
  53.     }
  54.  
  55. STDMETHODIMP_(ULONG) CImpIDataObject::AddRef(void)
  56.     {
  57.     ++m_cRef;
  58.     return m_pUnkOuter->AddRef();
  59.     }
  60.  
  61. STDMETHODIMP_(ULONG) CImpIDataObject::Release(void)
  62.     {
  63.     --m_cRef;
  64.     return m_pUnkOuter->Release();
  65.     }
  66.  
  67.  
  68.  
  69.  
  70.  
  71. /*
  72.  * CImpIDataObject::GetData
  73.  *
  74.  * Purpose:
  75.  *  Retrieves data described by a specific FormatEtc into a StgMedium
  76.  *  allocated by this function.  Used like GetClipboardData.
  77.  *
  78.  * Parameters:
  79.  *  pFE             LPFORMATETC describing the desired data.
  80.  *  pSTM            LPSTGMEDIUM in which to return the data.
  81.  *
  82.  * Return Value:
  83.  *  HRESULT         NOERROR or a general error value.
  84.  */
  85.  
  86. STDMETHODIMP CImpIDataObject::GetData(LPFORMATETC pFE
  87.     , LPSTGMEDIUM pSTM)
  88.     {
  89.     UINT            cf=pFE->cfFormat;
  90.     BOOL            fRet=FALSE;
  91.  
  92.     //Another part of us already knows if the format is good.
  93.     if (NOERROR!=QueryGetData(pFE))
  94.         return ResultFromScode(DATA_E_FORMATETC);
  95.  
  96.     if (CF_METAFILEPICT==cf || CF_BITMAP==cf || m_pObj->m_cf==cf)
  97.         {
  98.         if (CF_METAFILEPICT==cf)
  99.             {
  100.             pSTM->tymed=TYMED_MFPICT;
  101.             }
  102.         else
  103.             pSTM->tymed=TYMED_HGLOBAL;
  104.  
  105.         pSTM->pUnkForRelease=NULL;
  106.         pSTM->hGlobal=m_pObj->m_pDoc->RenderFormat(cf);
  107.         fRet=(NULL!=pSTM->hGlobal);
  108.         }
  109.     else
  110.         fRet=m_pObj->m_pDoc->RenderMedium(cf, pSTM);
  111.  
  112.     return fRet ? NOERROR : ResultFromScode(DATA_E_FORMATETC);
  113.     }
  114.  
  115.  
  116.  
  117.  
  118. /*
  119.  * CImpIDataObject::GetDataHere
  120.  *
  121.  * Purpose:
  122.  *  Renders the specific FormatEtc into caller-allocated medium
  123.  *  provided in pSTM.
  124.  *
  125.  * Parameters:
  126.  *  pFE             LPFORMATETC describing the desired data.
  127.  *  pSTM            LPSTGMEDIUM providing the medium into which
  128.  *                  wer render the data.
  129.  *
  130.  * Return Value:
  131.  *  HRESULT         NOERROR or a general error value.
  132.  */
  133.  
  134. STDMETHODIMP CImpIDataObject::GetDataHere(LPFORMATETC pFE
  135.     , LPSTGMEDIUM pSTM)
  136.     {
  137.     UINT        cf;
  138.     LONG        lRet;
  139.  
  140.     /*
  141.      * The only reasonable time this is called is for
  142.      * CFSTR_EMBEDSOURCE and TYMED_ISTORAGE (and later for
  143.      * CFSTR_LINKSOURCE).  This means the same as
  144.      * IPersistStorage::Save.
  145.      */
  146.  
  147.     cf=RegisterClipboardFormat(CFSTR_EMBEDSOURCE);
  148.  
  149.     //Aspect is unimportant to us here, as is lindex and ptd.
  150.     if (cf==pFE->cfFormat && (TYMED_ISTORAGE & pFE->tymed))
  151.         {
  152.         //We have an IStorage we can write into.
  153.         pSTM->tymed=TYMED_ISTORAGE;
  154.         pSTM->pUnkForRelease=NULL;
  155.         lRet=m_pObj->m_pPL->WriteToStorage(pSTM->pstg
  156.             , VERSIONCURRENT);
  157.  
  158.         //CHAPTER21MOD
  159.         //These are for creating an embedded object from a file
  160.         WriteClassStg(pSTM->pstg, CLSID_CosmoFigure);
  161.         WriteFmtUserTypeStg(pSTM->pstg, m_pObj->m_cf
  162.             , (*m_pObj->m_pST)[IDS_USERTYPE]);
  163.         //End CHAPTER21MOD
  164.  
  165.         if (lRet >= 0)
  166.             return NOERROR;
  167.  
  168.         return ResultFromScode(STG_E_WRITEFAULT);
  169.         }
  170.  
  171.     return ResultFromScode(DATA_E_FORMATETC);
  172.     }
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179. /*
  180.  * CImpIDataObject::QueryGetData
  181.  *
  182.  * Purpose:
  183.  *  Tests if a call to GetData with this FormatEtc will provide
  184.  *  any rendering; used like IsClipboardFormatAvailable.
  185.  *
  186.  * Parameters:
  187.  *  pFE             LPFORMATETC describing the desired data.
  188.  *
  189.  * Return Value:
  190.  *  HRESULT         NOERROR or a general error value.
  191.  */
  192.  
  193. STDMETHODIMP CImpIDataObject::QueryGetData(LPFORMATETC pFE)
  194.     {
  195.     UINT            cf=pFE->cfFormat;
  196.     UINT            i;
  197.  
  198.     //Check the aspects we support.
  199.     if (!(DVASPECT_CONTENT & pFE->dwAspect))
  200.         return ResultFromScode(S_FALSE);
  201.  
  202.     for (i=0; i < m_pObj->m_cfeGet; i++)
  203.         {
  204.         if (pFE->cfFormat==m_pObj->m_rgfeGet[i].cfFormat
  205.             && pFE->tymed & m_pObj->m_rgfeGet[i].tymed)
  206.             {
  207.             return NOERROR;
  208.             }
  209.         }
  210.  
  211.     return ResultFromScode(S_FALSE);
  212.     }
  213.  
  214.  
  215.  
  216.  
  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.  
  234. STDMETHODIMP CImpIDataObject::GetCanonicalFormatEtc
  235.     (LPFORMATETC pFEIn, LPFORMATETC pFEOut)
  236.     {
  237.     if (NULL==pFEOut)
  238.         return ResultFromScode(E_INVALIDARG);
  239.  
  240.     pFEOut->ptd=NULL;
  241.     return ResultFromScode(DATA_S_SAMEFORMATETC);
  242.     }
  243.  
  244.  
  245.  
  246.  
  247.  
  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.  
  267. STDMETHODIMP CImpIDataObject::SetData(LPFORMATETC pFE
  268.     , LPSTGMEDIUM pSTM, BOOL fRelease)
  269.     {
  270.     LONG            lRet;
  271.  
  272.     /*
  273.      * Data can only come from global memory containing a
  274.      * POLYLINEDATA structure that we send to the Polyline's
  275.      * DataSetMem.
  276.      */
  277.     if ((pFE->cfFormat!=m_pObj->m_cf)
  278.         || !(DVASPECT_CONTENT & pFE->dwAspect)
  279.         || (TYMED_HGLOBAL!=pSTM->tymed))
  280.         return ResultFromScode(DATA_E_FORMATETC);
  281.  
  282.     lRet=m_pObj->m_pPL->DataSetMem(pSTM->hGlobal, FALSE, TRUE
  283.         , TRUE);
  284.  
  285.     if (fRelease)
  286.         ReleaseStgMedium(pSTM);
  287.  
  288.     return (POLYLINE_E_NONE==lRet) ?
  289.         NOERROR : ResultFromScode(DATA_E_FORMATETC);
  290.     }
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297. /*
  298.  * CImpIDataObject::EnumFormatEtc
  299.  *
  300.  * Purpose:
  301.  *  Returns an IEnumFORMATETC object through which the caller can
  302.  *  iterate to learn about all the data formats this object can
  303.  *  provide through either GetData[Here] or SetData.
  304.  *
  305.  * Parameters:
  306.  *  dwDir           DWORD describing a data direction, either
  307.  *                  DATADIR_SET or DATADIR_GET.
  308.  *  ppEnum          LPENUMFORMATETC * in which to return the
  309.  *                  pointer to the enumerator.
  310.  *
  311.  * Return Value:
  312.  *  HRESULT         NOERROR or a general error value.
  313.  */
  314.  
  315. STDMETHODIMP CImpIDataObject::EnumFormatEtc(DWORD dwDir
  316.     , LPENUMFORMATETC *ppEnum)
  317.     {
  318.     return ResultFromScode(OLE_S_USEREG);
  319.     }
  320.  
  321.  
  322.  
  323.  
  324.  
  325. /*
  326.  * CImpIDataObject::DAdvise
  327.  * CImpIDataObject::DUnadvise
  328.  * CImpIDataObject::EnumDAdvise
  329.  *
  330.  * Pass-throughs to IDataAdviseHolder.
  331.  */
  332.  
  333. STDMETHODIMP CImpIDataObject::DAdvise(LPFORMATETC pFE, DWORD dwFlags
  334.     , LPADVISESINK pIAdviseSink, LPDWORD pdwConn)
  335.     {
  336.     HRESULT         hr;
  337.  
  338.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  339.         {
  340.         hr=CreateDataAdviseHolder(&m_pObj->m_pIDataAdviseHolder);
  341.  
  342.         if (FAILED(hr))
  343.             return ResultFromScode(E_OUTOFMEMORY);
  344.         }
  345.  
  346.     hr=m_pObj->m_pIDataAdviseHolder->Advise(this, pFE
  347.         , dwFlags, pIAdviseSink, pdwConn);
  348.  
  349.     return hr;
  350.     }
  351.  
  352.  
  353. STDMETHODIMP CImpIDataObject::DUnadvise(DWORD dwConn)
  354.     {
  355.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  356.         return ResultFromScode(E_FAIL);
  357.  
  358.     return m_pObj->m_pIDataAdviseHolder->Unadvise(dwConn);
  359.     }
  360.  
  361.  
  362.  
  363. STDMETHODIMP CImpIDataObject::EnumDAdvise(LPENUMSTATDATA *ppEnum)
  364.     {
  365.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  366.         return ResultFromScode(E_FAIL);
  367.  
  368.     return m_pObj->m_pIDataAdviseHolder->EnumAdvise(ppEnum);
  369.     }
  370.