|
|
/*++
Copyright (C) 1993-1999 Microsoft Corporation
Module Name:
idataobj.cpp
Abstract:
Implementation of the IDataObject interface.
--*/
#include "polyline.h"
#include "unkhlpr.h"
// CImpIDataObject interface implmentation
IMPLEMENT_CONTAINED_INTERFACE(CPolyline, CImpIDataObject)
/*
* CImpIDataObject::GetData * * Purpose: * Retrieves data described by a specific FormatEtc into a StgMedium * allocated by this function. Used like GetClipboardData. * * Parameters: * pFE LPFORMATETC describing the desired data. * pSTM LPSTGMEDIUM in which to return the data. * * Return Value: * HRESULT NOERROR or a general error value. */
STDMETHODIMP CImpIDataObject::GetData( IN LPFORMATETC pFE, OUT LPSTGMEDIUM pSTM ) { CLIPFORMAT cf; IStream *pIStream = NULL; HDC hDevDC = NULL; HRESULT hr = DATA_E_FORMATETC;
if (pFE == NULL || pSTM == NULL) { return E_POINTER; }
try { cf = pFE->cfFormat;
//
// Use do{}while(0) to act like a switch statement
//
do { //
//Check the aspects we support.
//
if (!(DVASPECT_CONTENT & pFE->dwAspect)) { hr = DATA_E_FORMATETC; break; }
pSTM->pUnkForRelease = NULL;
//
//Run creates the window to use as a basis for extents
//
m_pObj->m_pImpIRunnableObject->Run(NULL);
//
// Go render the appropriate data for the format.
//
switch (cf) { case CF_METAFILEPICT: pSTM->tymed=TYMED_MFPICT; hDevDC = CreateTargetDC (NULL, pFE->ptd ); if (hDevDC) { hr = m_pObj->RenderMetafilePict(&pSTM->hGlobal, hDevDC); } else { hr = E_FAIL; } break;
case CF_BITMAP: pSTM->tymed=TYMED_GDI; hDevDC = CreateTargetDC (NULL, pFE->ptd ); if (hDevDC) { hr = m_pObj->RenderBitmap((HBITMAP *)&pSTM->hGlobal, hDevDC); } else { hr = E_FAIL; } break; default: if (cf == m_pObj->m_cf) { hr = CreateStreamOnHGlobal(NULL, TRUE, &pIStream); if (SUCCEEDED(hr)) { hr = m_pObj->m_pCtrl->SaveToStream(pIStream); if (FAILED(hr)) { pIStream->Release(); } } else { hr = E_OUTOFMEMORY; }
if (SUCCEEDED(hr)) { pSTM->tymed = TYMED_ISTREAM; pSTM->pstm = pIStream; } } break; } } while (0);
} catch (...) { hr = E_POINTER; }
if (FAILED(hr)) { if (hDevDC) { ::DeleteDC(hDevDC); } }
return hr; }
/*
* CImpIDataObject::GetDataHere * * Purpose: * Renders the specific FormatEtc into caller-allocated medium * provided in pSTM. * * Parameters: * pFE LPFORMATETC describing the desired data. * pSTM LPSTGMEDIUM providing the medium into which * wer render the data. * * Return Value: * HRESULT NOERROR or a general error value. */
STDMETHODIMP CImpIDataObject::GetDataHere( IN LPFORMATETC pFE, IN OUT LPSTGMEDIUM pSTM ) { CLIPFORMAT cf; HRESULT hr = S_OK;
if (pFE == NULL || pSTM == NULL) { return E_POINTER; }
/*
* The only reasonable time this is called is for * CFSTR_EMBEDSOURCE and TYMED_ISTORAGE (and later for * CFSTR_LINKSOURCE). This means the same as * IPersistStorage::Save. */
cf = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_EMBEDSOURCE);
try { //Aspect is not important to us here, as is lindex and ptd.
if (cf == pFE->cfFormat && (TYMED_ISTORAGE & pFE->tymed)) { //We have an IStorage we can write into.
pSTM->tymed=TYMED_ISTORAGE; pSTM->pUnkForRelease=NULL; hr = m_pObj->m_pImpIPersistStorage->Save(pSTM->pstg, FALSE); m_pObj->m_pImpIPersistStorage->SaveCompleted(NULL); } else { hr = DATA_E_FORMATETC; } } catch (...) { hr = E_POINTER; }
return hr; }
/*
* CImpIDataObject::QueryGetData * * Purpose: * Tests if a call to GetData with this FormatEtc will provide * any rendering; used like IsClipboardFormatAvailable. * * Parameters: * pFE LPFORMATETC describing the desired data. * * Return Value: * HRESULT NOERROR or a general error value. */
STDMETHODIMP CImpIDataObject::QueryGetData( IN LPFORMATETC pFE ) { CLIPFORMAT cf; BOOL fRet = FALSE; HRESULT hr = S_OK;
if (pFE == NULL) { return E_POINTER; }
try { cf = pFE->cfFormat;
//
//Check the aspects we support.
//
if (!(DVASPECT_CONTENT & pFE->dwAspect)) { hr = DATA_E_FORMATETC; } else { switch (cf) {
case CF_METAFILEPICT: fRet = (BOOL)(pFE->tymed & TYMED_MFPICT); break; case CF_BITMAP: fRet = (BOOL)(pFE->tymed & TYMED_GDI); break;
default: //Check our own format.
fRet = ((cf==m_pObj->m_cf) && (BOOL)(pFE->tymed & (TYMED_ISTREAM) )); break; } if (fRet == FALSE) { hr = DATA_E_FORMATETC; } } } catch (...) { hr = E_POINTER; }
return hr; }
/*
* CImpIDataObject::GetCanonicalFormatEtc * * Purpose: * Provides the caller with an equivalent FormatEtc to the one * provided when different FormatEtcs will produce exactly the * same renderings. * * Parameters: * pFEIn LPFORMATETC of the first description. * pFEOut LPFORMATETC of the equal description. * * Return Value: * HRESULT NOERROR or a general error value. */
STDMETHODIMP CImpIDataObject::GetCanonicalFormatEtc( LPFORMATETC /* pFEIn */, LPFORMATETC pFEOut ) { if (NULL == pFEOut) { return E_POINTER; }
try { pFEOut->ptd = NULL; } catch (...) { return E_POINTER; }
return DATA_S_SAMEFORMATETC; }
/*
* CImpIDataObject::SetData * * Purpose: * Places data described by a FormatEtc and living in a StgMedium * into the object. The object may be responsible to clean up the * StgMedium before exiting. * * Parameters: * pFE LPFORMATETC describing the data to set. * pSTM LPSTGMEDIUM containing the data. * fRelease BOOL indicating if this function is responsible * for freeing the data. * * Return Value: * HRESULT NOERROR or a general error value. */
STDMETHODIMP CImpIDataObject::SetData( LPFORMATETC pFE , LPSTGMEDIUM pSTM, BOOL fRelease ) { CLIPFORMAT cf; HRESULT hr = S_OK;
if (pFE == NULL || pSTM == NULL) { return E_POINTER; }
try { cf = pFE->cfFormat;
do { //
//Check for our own clipboard format and DVASPECT_CONTENT
//
if ((cf != m_pObj->m_cf) || !(DVASPECT_CONTENT & pFE->dwAspect)) { hr = DATA_E_FORMATETC; break; }
//
// The medium must be a stream
//
if (TYMED_ISTREAM != pSTM->tymed) { hr = DATA_E_FORMATETC; break; }
hr = m_pObj->m_pCtrl->LoadFromStream(pSTM->pstm); } while (0);
if (fRelease) ReleaseStgMedium(pSTM);
} catch (...) { hr = E_POINTER; }
return hr; }
/*
* CImpIDataObject::EnumFormatEtc * * Purpose: * Returns an IEnumFORMATETC object through which the caller can * iterate to learn about all the data formats this object can * provide through either GetData[Here] or SetData. * * Parameters: * dwDir DWORD describing a data direction, either * DATADIR_SET or DATADIR_GET. * ppEnum LPENUMFORMATETC * in which to return the * pointer to the enumerator. * * Return Value: * HRESULT NOERROR or a general error value. */
STDMETHODIMP CImpIDataObject::EnumFormatEtc( DWORD dwDir, LPENUMFORMATETC *ppEnum ) { HRESULT hr = S_OK;
if (ppEnum == NULL) { return E_POINTER; }
try { hr = m_pObj->m_pDefIDataObject->EnumFormatEtc(dwDir, ppEnum); } catch (...) { hr = E_POINTER; }
return hr; }
/*
* CImpIDataObject::DAdvise * CImpIDataObject::DUnadvise * CImpIDataObject::EnumDAdvise */
STDMETHODIMP CImpIDataObject::DAdvise( LPFORMATETC pFE, DWORD dwFlags, LPADVISESINK pIAdviseSink, LPDWORD pdwConn ) { HRESULT hr = S_OK;
try { do { // Check if requested format is supported
hr = QueryGetData(pFE); if (FAILED(hr)) { break; }
if (NULL == m_pObj->m_pIDataAdviseHolder) { hr = CreateDataAdviseHolder(&m_pObj->m_pIDataAdviseHolder); if (FAILED(hr)) { hr = E_OUTOFMEMORY; break; } }
hr = m_pObj->m_pIDataAdviseHolder->Advise(this, pFE, dwFlags, pIAdviseSink, pdwConn); } while (0);
} catch (...) { hr = E_POINTER; }
return hr; }
STDMETHODIMP CImpIDataObject::DUnadvise( IN DWORD dwConn ) { HRESULT hr;
if (NULL == m_pObj->m_pIDataAdviseHolder) { return E_FAIL; }
hr = m_pObj->m_pIDataAdviseHolder->Unadvise(dwConn);
return hr; }
STDMETHODIMP CImpIDataObject::EnumDAdvise( OUT LPENUMSTATDATA *ppEnum ) { HRESULT hr = S_OK;
if (ppEnum == NULL) { return E_POINTER; }
try { *ppEnum = NULL;
if (m_pObj->m_pIDataAdviseHolder != NULL) { hr = m_pObj->m_pIDataAdviseHolder->EnumAdvise(ppEnum); } else { hr = E_FAIL; } } catch (...) { hr = E_POINTER; }
return hr; }
|