/**************************************************************************
File: DataObj.cpp
Description:
**************************************************************************/
/**************************************************************************
#include statements
**************************************************************************/
#include "stdafx.h"
#include <shlobj.h>
#include "DataObj.h"
using namespace System::Runtime::InteropServices;
namespace ShellUtils
{
/**************************************************************************
CDataObject::CDataObject()
**************************************************************************/
CDataObject::CDataObject()
{
}
/**************************************************************************
CDataObject::~CDataObject()
**************************************************************************/
CDataObject::~CDataObject()
{
Clear();
}
void CDataObject::Clear()
{
for(Storage::iterator it = m_storage.begin(); it != m_storage.end(); ++it)
ReleaseStgMedium(it->lpMed);
}
///////////////////////////////////////////////////////////////////////////
//
// IUnknown Implementation
//
/**************************************************************************
CDataObject::QueryInterface()
**************************************************************************/
STDMETHODIMP CDataObject::QueryInterface(REFIID riid, LPVOID *ppvOut)
{
*ppvOut = NULL;
//IUnknown
if(IsEqualIID(riid, IID_IUnknown))
{
*ppvOut = this;
return S_OK;
}
//IDataObject
if(IsEqualIID(riid, IID_IDataObject))
{
*ppvOut = (IDataObject*)this;
return S_OK;
}
return E_NOINTERFACE;
}
/**************************************************************************
CDataObject::AddRef()
**************************************************************************/
STDMETHODIMP_(ULONG) CDataObject::AddRef(void)
{
return 2;
}
/**************************************************************************
CDataObject::Release()
**************************************************************************/
STDMETHODIMP_(ULONG) CDataObject::Release(void)
{
return 1;
}
///////////////////////////////////////////////////////////////////////////
//
// IDataObject Implementation
//
/**************************************************************************
CDataObject::GetData()
**************************************************************************/
STDMETHODIMP CDataObject::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSM)
{
if (pFE == NULL || pSM == NULL)
return E_INVALIDARG;
pSM->hGlobal = NULL;
for(Storage::iterator it = m_storage.begin(); it != m_storage.end(); ++it)
{
if (pFE->tymed & it->lpFmt->tymed &&
pFE->dwAspect == it->lpFmt->dwAspect &&
pFE->cfFormat == it->lpFmt->cfFormat)
{
CopyStgMedium(it->lpMed, pSM);
return S_OK;
}
}
return DV_E_FORMATETC;
}
/**************************************************************************
CDataObject::GetDataHere()
**************************************************************************/
STDMETHODIMP CDataObject::GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSM)
{
return E_NOTIMPL;
}
/**************************************************************************
CDataObject::QueryGetData()
**************************************************************************/
STDMETHODIMP CDataObject::QueryGetData(LPFORMATETC pFE)
{
if (pFE == NULL)
return E_INVALIDARG;
//support others if needed DVASPECT_THUMBNAIL //DVASPECT_ICON //DVASPECT_DOCPRINT
if (!(DVASPECT_CONTENT & pFE->dwAspect))
return (DV_E_DVASPECT);
HRESULT hr = DV_E_TYMED;
for(Storage::iterator it = m_storage.begin(); it != m_storage.end(); ++it)
{
if (pFE->tymed & it->lpFmt->tymed)
{
if (pFE->cfFormat == it->lpFmt->cfFormat)
return S_OK;
else
hr = DV_E_CLIPFORMAT;
}
else
hr = DV_E_TYMED;
}
return hr;
}
/**************************************************************************
CDataObject::GetCanonicalFormatEtc()
**************************************************************************/
STDMETHODIMP CDataObject::GetCanonicalFormatEtc(LPFORMATETC pFE1, LPFORMATETC pFE2)
{
return DATA_S_SAMEFORMATETC;
}
/**************************************************************************
CDataObject::SetData()
**************************************************************************/
STDMETHODIMP CDataObject::SetData(LPFORMATETC pFE , LPSTGMEDIUM pSM, BOOL fRelease)
{
if (pFE == NULL || pSM == NULL)
return E_INVALIDARG;
for(Storage::iterator it = m_storage.begin(); it != m_storage.end(); ++it)
{
if (pFE->tymed & it->lpFmt->tymed &&
pFE->dwAspect == it->lpFmt->dwAspect &&
pFE->cfFormat == it->lpFmt->cfFormat)
{
m_storage.erase(it);
break;
}
}
FORMATETC* fetc=new FORMATETC;
STGMEDIUM* pStgMed = new STGMEDIUM;
if (fetc == NULL || pStgMed == NULL)
return E_OUTOFMEMORY;
ZeroMemory(fetc, sizeof(FORMATETC));
ZeroMemory(pStgMed, sizeof(STGMEDIUM));
*fetc = *pFE;
if (fRelease)
*pStgMed = *pSM;
else
CopyStgMedium(pSM, pStgMed);
DataStorage storage;
storage.lpFmt = fetc;
storage.lpMed = pStgMed;
m_storage.push_back(storage);
return S_OK;
}
/**************************************************************************
CDataObject::EnumFormatEtc()
**************************************************************************/
STDMETHODIMP CDataObject::EnumFormatEtc(DWORD dwDir, LPENUMFORMATETC *ppEnum)
{
*ppEnum = NULL;
switch(dwDir)
{
case DATADIR_GET:
{
*ppEnum = new CEnumFormatEtc(m_storage);
if(*ppEnum)
return S_OK;
break;
}
default:
return OLE_S_USEREG;
}
return E_OUTOFMEMORY;
}
/**************************************************************************
CDataObject::DAdvise()
**************************************************************************/
STDMETHODIMP CDataObject::DAdvise( LPFORMATETC pFE,
DWORD advf,
LPADVISESINK pAdvSink,
LPDWORD pdwConnection)
{
return E_NOTIMPL;
}
/**************************************************************************
CDataObject::DUnadvise()
**************************************************************************/
STDMETHODIMP CDataObject::DUnadvise(DWORD dwConnection)
{
return E_NOTIMPL;
}
/**************************************************************************
CDataObject::EnumDAdvise()
**************************************************************************/
STDMETHODIMP CDataObject::EnumDAdvise(LPENUMSTATDATA *ppenumAdvise)
{
return OLE_E_ADVISENOTSUPPORTED;
}
DataObjectEx::DataObjectEx()
{
_pDataObject = new CDataObject();
}
DataObjectEx::~DataObjectEx()
{
if(_pDataObject)
{
_pDataObject->Release();
_pDataObject = NULL;
}
}
void DataObjectEx::SetData(Object* o)
{
DataObject::SetData(o);
CacheData(o->GetType()->ToString());
}
void DataObjectEx::SetData(String* s, Object* o)
{
DataObject::SetData(s, o);
CacheData(s);
}
void DataObjectEx::SetData(Type* t, Object* o)
{
DataObject::SetData(t, o);
CacheData(t->ToString());
}
void DataObjectEx::SetData(String* s, bool b, Object* o)
{
DataObject::SetData(s, b, o);
CacheData(s);
}
void _CacheData(LPFORMATETC lpFetc, LPDATAOBJECT pSrc, LPDATAOBJECT pDest)
{
STGMEDIUM stgMed;
if(SUCCEEDED(pSrc->QueryGetData(lpFetc)))
{
pSrc->GetData(lpFetc, &stgMed);
- 1
- 2
- 3
- 4
- 5
- 6
前往页