windows-nt/Source/XPSP1/NT/admin/controls/smonctrl/idataobj.cpp
2020-09-26 16:20:57 +08:00

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;
}