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 / chap10 / polyline / idataobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  9.5 KB  |  414 lines

  1. /*
  2.  * IDATAOBJ.CPP
  3.  * Polyline Component Chapter 10
  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 "polyline.h"
  16.  
  17.  
  18. /*
  19.  * CImpIDataObject::CImpIDataObject
  20.  * CImpIDataObject::~CImpIDataObject
  21.  *
  22.  * Parameters (Constructor):
  23.  *  pObj            PCPolyline of the object we're in.
  24.  *  pUnkOuter       LPUNKNOWN to which we delegate.
  25.  */
  26.  
  27. CImpIDataObject::CImpIDataObject(PCPolyline 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.  
  91.     //Check the aspects we support.
  92.     if (!(DVASPECT_CONTENT & pFE->dwAspect))
  93.         return ResultFromScode(DATA_E_FORMATETC);
  94.  
  95.     pSTM->pUnkForRelease=NULL;
  96.  
  97.     //Go render the appropriate data for the format.
  98.     switch (cf)
  99.         {
  100.         case CF_METAFILEPICT:
  101.             pSTM->tymed=TYMED_MFPICT;
  102.             return m_pObj->RenderMetafilePict(&pSTM->hGlobal);
  103.  
  104.         case CF_BITMAP:
  105.             pSTM->tymed=TYMED_GDI;
  106.             return m_pObj->RenderBitmap((HBITMAP *)&pSTM->hGlobal);
  107.  
  108.         default:
  109.             if (cf==m_pObj->m_cf)
  110.                 {
  111.                 pSTM->tymed=TYMED_HGLOBAL;
  112.                 return m_pObj->RenderNative(&pSTM->hGlobal);
  113.                 }
  114.  
  115.             break;
  116.         }
  117.  
  118.     return ResultFromScode(DATA_E_FORMATETC);
  119.     }
  120.  
  121.  
  122.  
  123.  
  124. /*
  125.  * CImpIDataObject::GetDataHere
  126.  *
  127.  * Purpose:
  128.  *  Renders the specific FormatEtc into caller-allocated medium
  129.  *  provided in pSTM.
  130.  *
  131.  * Parameters:
  132.  *  pFE             LPFORMATETC describing the desired data.
  133.  *  pSTM            LPSTGMEDIUM providing the medium into which
  134.  *                  wer render the data.
  135.  *
  136.  * Return Value:
  137.  *  HRESULT         NOERROR or a general error value.
  138.  */
  139.  
  140. STDMETHODIMP CImpIDataObject::GetDataHere(LPFORMATETC pFE
  141.     , LPSTGMEDIUM pSTM)
  142.     {
  143.     //No support for this function.
  144.     return ResultFromScode(DATA_E_FORMATETC);
  145.     }
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152. /*
  153.  * CImpIDataObject::QueryGetData
  154.  *
  155.  * Purpose:
  156.  *  Tests if a call to GetData with this FormatEtc will provide
  157.  *  any rendering; used like IsClipboardFormatAvailable.
  158.  *
  159.  * Parameters:
  160.  *  pFE             LPFORMATETC describing the desired data.
  161.  *
  162.  * Return Value:
  163.  *  HRESULT         NOERROR or a general error value.
  164.  */
  165.  
  166. STDMETHODIMP CImpIDataObject::QueryGetData(LPFORMATETC pFE)
  167.     {
  168.     UINT            cf=pFE->cfFormat;
  169.     BOOL            fRet=FALSE;
  170.  
  171.     //Check the aspects we support.
  172.     if (!(DVASPECT_CONTENT & pFE->dwAspect))
  173.         return ResultFromScode(DATA_E_FORMATETC);
  174.  
  175.     switch (cf)
  176.         {
  177.         case CF_METAFILEPICT:
  178.             fRet=(BOOL)(pFE->tymed & TYMED_MFPICT);
  179.             break;
  180.  
  181.         case CF_BITMAP:
  182.             fRet=(BOOL)(pFE->tymed & TYMED_GDI);
  183.             break;
  184.  
  185.         default:
  186.             //Check our own format.
  187.             fRet=((cf==m_pObj->m_cf)
  188.                 && (BOOL)(pFE->tymed & TYMED_HGLOBAL));
  189.             break;
  190.         }
  191.  
  192.     return fRet ? NOERROR : ResultFromScode(S_FALSE);
  193.     }
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. /*
  201.  * CImpIDataObject::GetCanonicalFormatEtc
  202.  *
  203.  * Purpose:
  204.  *  Provides the caller with an equivalent FormatEtc to the one
  205.  *  provided when different FormatEtcs will produce exactly the
  206.  *  same renderings.
  207.  *
  208.  * Parameters:
  209.  *  pFEIn            LPFORMATETC of the first description.
  210.  *  pFEOut           LPFORMATETC of the equal description.
  211.  *
  212.  * Return Value:
  213.  *  HRESULT         NOERROR or a general error value.
  214.  */
  215.  
  216. STDMETHODIMP CImpIDataObject::GetCanonicalFormatEtc
  217.     (LPFORMATETC pFEIn, LPFORMATETC pFEOut)
  218.     {
  219.     if (NULL==pFEOut)
  220.         return ResultFromScode(E_INVALIDARG);
  221.  
  222.     pFEOut->ptd=NULL;
  223.     return ResultFromScode(DATA_S_SAMEFORMATETC);
  224.     }
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231. /*
  232.  * CImpIDataObject::SetData
  233.  *
  234.  * Purpose:
  235.  *  Places data described by a FormatEtc and living in a StgMedium
  236.  *  into the object.  The object may be responsible to clean up the
  237.  *  StgMedium before exiting.
  238.  *
  239.  * Parameters:
  240.  *  pFE             LPFORMATETC describing the data to set.
  241.  *  pSTM            LPSTGMEDIUM containing the data.
  242.  *  fRelease        BOOL indicating if this function is responsible
  243.  *                  for freeing the data.
  244.  *
  245.  * Return Value:
  246.  *  HRESULT         NOERROR or a general error value.
  247.  */
  248.  
  249. STDMETHODIMP CImpIDataObject::SetData(LPFORMATETC pFE
  250.     , LPSTGMEDIUM pSTM, BOOL fRelease)
  251.     {
  252.     UINT            cf=pFE->cfFormat;
  253.     BOOL            fRet=FALSE;
  254.     PPOLYLINEDATA   ppl;
  255.  
  256.     //Check for our own clipboard format and DVASPECT_CONTENT
  257.     if ((cf!=m_pObj->m_cf) || !(DVASPECT_CONTENT & pFE->dwAspect))
  258.         return ResultFromScode(DATA_E_FORMATETC);
  259.  
  260.     /*
  261.      * Data can only come from global memory containing a
  262.      * POLYLINEDATA structure that we send to the Polyline's
  263.      * DataSet, a now internal function used from here and
  264.      * from IPersistStorage::Load.
  265.      */
  266.  
  267.     if (TYMED_HGLOBAL!=pSTM->tymed)
  268.         return ResultFromScode(DATA_E_FORMATETC);
  269.  
  270.     ppl=(PPOLYLINEDATA)GlobalLock(pSTM->hGlobal);
  271.  
  272.     if (NULL!=ppl)
  273.         {
  274.         m_pObj->DataSet(ppl, TRUE, TRUE);
  275.         GlobalUnlock(pSTM->hGlobal);
  276.         fRet=TRUE;
  277.         }
  278.  
  279.     if (fRelease)
  280.         ReleaseStgMedium(pSTM);
  281.  
  282.     return fRet ? NOERROR : ResultFromScode(DATA_E_FORMATETC);
  283.     }
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290. /*
  291.  * CImpIDataObject::EnumFormatEtc
  292.  *
  293.  * Purpose:
  294.  *  Returns an IEnumFORMATETC object through which the caller can
  295.  *  iterate to learn about all the data formats this object can
  296.  *  provide through either GetData[Here] or SetData.
  297.  *
  298.  * Parameters:
  299.  *  dwDir           DWORD describing a data direction, either
  300.  *                  DATADIR_SET or DATADIR_GET.
  301.  *  ppEnum          LPENUMFORMATETC * in which to return the
  302.  *                  pointer to the enumerator.
  303.  *
  304.  * Return Value:
  305.  *  HRESULT         NOERROR or a general error value.
  306.  */
  307.  
  308. STDMETHODIMP CImpIDataObject::EnumFormatEtc(DWORD dwDir
  309.     , LPENUMFORMATETC *ppEnum)
  310.     {
  311.     return OleRegEnumFormatEtc(m_pObj->m_clsID, dwDir, ppEnum);
  312.     }
  313.  
  314.  
  315.  
  316.  
  317.  
  318. /*
  319.  * CImpIDataObject::DAdvise
  320.  *
  321.  * Purpose:
  322.  *  Provides the data object with an IAdviseSink object that we are
  323.  *  responsible to notify when the data changes.
  324.  *
  325.  * Parameters:
  326.  *  ppFE            LPFORMATETC
  327.  *  dwFlags         DWORD carrying flags indicating how the advise
  328.  *                  sink wants to be treated.
  329.  *  pIAdviseSink    LPADVISESINK to the object to notify.
  330.  *  pdwConn         LPDWORD into which we store a DWORD key
  331.  *                  identifying the advise connection.
  332.  *
  333.  * Return Value:
  334.  *  HRESULT         NOERROR or a general error value.
  335.  */
  336.  
  337. STDMETHODIMP CImpIDataObject::DAdvise(LPFORMATETC pFE, DWORD dwFlags
  338.     , LPADVISESINK pIAdviseSink, LPDWORD pdwConn)
  339.     {
  340.     HRESULT         hr;
  341.  
  342.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  343.         {
  344.         hr=CreateDataAdviseHolder(&m_pObj->m_pIDataAdviseHolder);
  345.  
  346.         if (FAILED(hr))
  347.             return ResultFromScode(E_OUTOFMEMORY);
  348.         }
  349.  
  350.     hr=m_pObj->m_pIDataAdviseHolder->Advise(this, pFE
  351.         , dwFlags, pIAdviseSink, pdwConn);
  352.     return hr;
  353.     }
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360. /*
  361.  * CImpIDataObject::DUnadvise
  362.  *
  363.  * Purpose:
  364.  *  Turns off advising previously set up with Advise.
  365.  *
  366.  * Parameters:
  367.  *  dwConn          DWORD connection key returned from Advise.
  368.  *
  369.  * Return Value:
  370.  *  HRESULT         NOERROR or a general error value.
  371.  */
  372.  
  373. STDMETHODIMP CImpIDataObject::DUnadvise(DWORD dwConn)
  374.     {
  375.     HRESULT         hr;
  376.  
  377.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  378.         return ResultFromScode(E_FAIL);
  379.  
  380.     hr=m_pObj->m_pIDataAdviseHolder->Unadvise(dwConn);
  381.     return hr;
  382.     }
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389. /*
  390.  * CImpIDataObject::EnumDAdvise
  391.  *
  392.  * Purpose:
  393.  *  Returns an enumerator object through which the caller can find
  394.  *  all the agents currently receiving advises on this data object.
  395.  *
  396.  * Parameters:
  397.  *  ppEnum          LPENUMSTATDATA * in which to return the
  398.  *                  enumerator.
  399.  *
  400.  * Return Value:
  401.  *  HRESULT         NOERROR or a general error value.
  402.  */
  403.  
  404. STDMETHODIMP CImpIDataObject::EnumDAdvise(LPENUMSTATDATA *ppEnum)
  405.     {
  406.     HRESULT         hr;
  407.  
  408.     if (NULL==m_pObj->m_pIDataAdviseHolder)
  409.         return ResultFromScode(E_FAIL);
  410.  
  411.     hr=m_pObj->m_pIDataAdviseHolder->EnumAdvise(ppEnum);
  412.     return hr;
  413.     }
  414.