366 lines
8.6 KiB
C++
366 lines
8.6 KiB
C++
/*++
|
|
|
|
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(
|
|
LPFORMATETC pFE,
|
|
LPSTGMEDIUM pSTM)
|
|
{
|
|
CLIPFORMAT cf=pFE->cfFormat;
|
|
IStream *pIStream;
|
|
HRESULT hr;
|
|
HDC hDevDC = NULL;
|
|
|
|
//Check the aspects we support.
|
|
if (!(DVASPECT_CONTENT & pFE->dwAspect))
|
|
return ResultFromScode(DATA_E_FORMATETC);
|
|
|
|
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);
|
|
::DeleteDC(hDevDC);
|
|
}
|
|
else {
|
|
hr = ResultFromScode(E_FAIL);
|
|
}
|
|
return hr;
|
|
|
|
case CF_BITMAP:
|
|
pSTM->tymed=TYMED_GDI;
|
|
hDevDC = CreateTargetDC (NULL, pFE->ptd );
|
|
if (hDevDC) {
|
|
hr = m_pObj->RenderBitmap((HBITMAP *)&pSTM->hGlobal, hDevDC);
|
|
::DeleteDC(hDevDC);
|
|
}
|
|
else {
|
|
hr = ResultFromScode(E_FAIL);
|
|
}
|
|
return hr;
|
|
|
|
default:
|
|
if (cf == m_pObj->m_cf)
|
|
{
|
|
hr = CreateStreamOnHGlobal(NULL, TRUE, &pIStream);
|
|
if (FAILED(hr))
|
|
return ResultFromScode(E_OUTOFMEMORY);
|
|
|
|
hr = m_pObj->m_pCtrl->SaveToStream(pIStream);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
pIStream->Release();
|
|
return hr;
|
|
}
|
|
|
|
pSTM->tymed = TYMED_ISTREAM;
|
|
pSTM->pstm = pIStream;
|
|
return NOERROR;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return ResultFromScode(DATA_E_FORMATETC);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
* 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(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
|
|
{
|
|
CLIPFORMAT cf;
|
|
HRESULT hr;
|
|
|
|
/*
|
|
* 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);
|
|
|
|
//Aspect is unimportant 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);
|
|
return hr;
|
|
}
|
|
|
|
return ResultFromScode(DATA_E_FORMATETC);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* 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(LPFORMATETC pFE)
|
|
{
|
|
CLIPFORMAT cf=pFE->cfFormat;
|
|
BOOL fRet=FALSE;
|
|
|
|
//Check the aspects we support.
|
|
if (!(DVASPECT_CONTENT & pFE->dwAspect))
|
|
return ResultFromScode(DATA_E_FORMATETC);
|
|
|
|
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;
|
|
}
|
|
|
|
return fRet ? NOERROR : ResultFromScode(DATA_E_FORMATETC);
|
|
}
|
|
|
|
|
|
/*
|
|
* 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 ResultFromScode(E_INVALIDARG);
|
|
|
|
pFEOut->ptd=NULL;
|
|
return ResultFromScode(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=pFE->cfFormat;
|
|
HRESULT hr;
|
|
|
|
//Check for our own clipboard format and DVASPECT_CONTENT
|
|
if ((cf!=m_pObj->m_cf) || !(DVASPECT_CONTENT & pFE->dwAspect))
|
|
return ResultFromScode(DATA_E_FORMATETC);
|
|
|
|
// The medium must be a stream
|
|
if (TYMED_ISTREAM != pSTM->tymed)
|
|
return ResultFromScode(DATA_E_FORMATETC);
|
|
|
|
hr = m_pObj->m_pCtrl->LoadFromStream(pSTM->pstm);
|
|
|
|
if (fRelease)
|
|
ReleaseStgMedium(pSTM);
|
|
|
|
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
|
|
)
|
|
{
|
|
return m_pObj->m_pDefIDataObject->EnumFormatEtc(dwDir, ppEnum);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
* CImpIDataObject::DAdvise
|
|
* CImpIDataObject::DUnadvise
|
|
* CImpIDataObject::EnumDAdvise
|
|
*/
|
|
|
|
STDMETHODIMP CImpIDataObject::DAdvise(
|
|
LPFORMATETC pFE,
|
|
DWORD dwFlags,
|
|
LPADVISESINK pIAdviseSink,
|
|
LPDWORD pdwConn
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Check if requested format is supported
|
|
hr = QueryGetData(pFE);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
if (NULL == m_pObj->m_pIDataAdviseHolder)
|
|
{
|
|
hr = CreateDataAdviseHolder(&m_pObj->m_pIDataAdviseHolder);
|
|
|
|
if (FAILED(hr))
|
|
return ResultFromScode(E_OUTOFMEMORY);
|
|
}
|
|
|
|
hr = m_pObj->m_pIDataAdviseHolder->Advise(this,
|
|
pFE,
|
|
dwFlags,
|
|
pIAdviseSink,
|
|
pdwConn);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CImpIDataObject::DUnadvise(DWORD dwConn)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (NULL==m_pObj->m_pIDataAdviseHolder)
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
hr=m_pObj->m_pIDataAdviseHolder->Unadvise(dwConn);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CImpIDataObject::EnumDAdvise(LPENUMSTATDATA *ppEnum)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (NULL==m_pObj->m_pIDataAdviseHolder)
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
hr=m_pObj->m_pIDataAdviseHolder->EnumAdvise(ppEnum);
|
|
return hr;
|
|
}
|