Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

502 lines
11 KiB

/*++
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;
}