|
|
//
// sdo.cpp
//
#include "private.h"
#include "sdo.h"
#include "helpers.h"
//////////////////////////////////////////////////////////////////////////////
//
// CDataObject
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// IUnknown
//
//----------------------------------------------------------------------------
STDAPI CDataObject::QueryInterface(REFIID riid, void **ppvObj) { *ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDataObject)) { *ppvObj = SAFECAST(this, IDataObject *); }
if (*ppvObj) { AddRef(); return S_OK; }
return E_NOINTERFACE; }
STDAPI_(ULONG) CDataObject::AddRef() { return ++_cRef; }
STDAPI_(ULONG) CDataObject::Release() { long cr;
cr = --_cRef; Assert(cr >= 0);
if (cr == 0) { delete this; }
return cr; }
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CDataObject::CDataObject() { Dbg_MemSetThisName(TEXT("CDataObject"));
memset(&_fe, 0, sizeof(_fe)); memset(&_sm, 0, sizeof(_sm)); _cRef = 1; }
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CDataObject::~CDataObject() { ReleaseStgMedium(&_sm); }
//+---------------------------------------------------------------------------
//
// GetData
//
//----------------------------------------------------------------------------
STDAPI CDataObject::GetData(FORMATETC *pfe, STGMEDIUM *psm) { WCHAR *pch; ULONG cch;
if (pfe == NULL || psm == NULL) return E_INVALIDARG;
// verify the formatetc -- Issue: use QueryGetData
if (pfe->cfFormat != _fe.cfFormat) return DV_E_FORMATETC; // Issue: ignoring ptd
if (pfe->dwAspect != _fe.dwAspect) return DV_E_DVASPECT; if (pfe->lindex != _fe.lindex) return DV_E_LINDEX; if (!(pfe->tymed & _fe.lindex)) return DV_E_TYMED;
Assert(_fe.tymed == _sm.tymed);
// allocate the medium
if ((pfe->tymed & _fe.lindex) == TYMED_HGLOBAL) { switch (pfe->cfFormat) { case CF_UNICODETEXT: pch = (WCHAR *)GlobalLock(_sm.hGlobal); cch = wcslen(pch) + 1; // include the '\0'
if ((psm->hGlobal = GlobalAlloc(GMEM_FIXED, cch*sizeof(WCHAR))) == NULL) { GlobalUnlock(_sm.hGlobal); return STG_E_MEDIUMFULL; }
memcpy(psm->hGlobal, pch, cch*sizeof(WCHAR)); GlobalUnlock(_sm.hGlobal);
psm->tymed = TYMED_HGLOBAL;
psm->pUnkForRelease = NULL; // caller must GlobalFree
break;
default: Assert(0); // shouldn't have let anyone SetData with something we can't handle
break; } } else { Assert(0); // shouldn't have let anyone SetData with something we can't handle
}
return S_OK; }
//+---------------------------------------------------------------------------
//
// GetDataHere
//
//----------------------------------------------------------------------------
STDAPI CDataObject::GetDataHere(FORMATETC *pfe, STGMEDIUM *psm) { return E_NOTIMPL; }
//+---------------------------------------------------------------------------
//
// QueryGetData
//
//----------------------------------------------------------------------------
STDAPI CDataObject::QueryGetData(FORMATETC *pfe) { if (pfe == NULL) return E_INVALIDARG;
// verify the formatetc
if (pfe->cfFormat != _fe.cfFormat) return DV_E_FORMATETC; // Issue: ignoring ptd
if (pfe->dwAspect != _fe.dwAspect) return DV_E_DVASPECT; if (pfe->lindex != _fe.lindex) return DV_E_LINDEX; if (!(pfe->tymed & _fe.lindex)) return DV_E_TYMED;
return S_OK; }
//+---------------------------------------------------------------------------
//
// GetCanonicalFormatEtc
//
//----------------------------------------------------------------------------
STDAPI CDataObject::GetCanonicalFormatEtc(FORMATETC *pfeIn, FORMATETC *pfeOut) { return E_NOTIMPL; // Issue: may not be legal to leave this unimpl
}
//+---------------------------------------------------------------------------
//
// SetData
//
//----------------------------------------------------------------------------
STDAPI CDataObject::SetData(FORMATETC *pfe, STGMEDIUM *psm, BOOL fRelease) { Assert(fRelease == TRUE); // bogus, but for now we don't support copying
if (pfe == NULL || psm == NULL) return E_INVALIDARG;
if (pfe->tymed != psm->tymed) return E_INVALIDARG;
// free up any storage
ReleaseStgMedium(&_sm);
// copy the new stuff
_fe = *pfe; _sm = *psm;
return S_OK; }
//+---------------------------------------------------------------------------
//
// EnumFormatEtc
//
//----------------------------------------------------------------------------
STDAPI CDataObject::EnumFormatEtc(DWORD dwDir, IEnumFORMATETC **ppefe) { return E_NOTIMPL; }
//+---------------------------------------------------------------------------
//
// DAdvise
//
//----------------------------------------------------------------------------
STDAPI CDataObject::DAdvise(FORMATETC *pfe, DWORD advf, IAdviseSink *pas, DWORD *pdwCookie) { return E_NOTIMPL; }
//+---------------------------------------------------------------------------
//
// DUnadvise
//
//----------------------------------------------------------------------------
STDAPI CDataObject::DUnadvise(DWORD dwCookie) { return E_NOTIMPL; }
//+---------------------------------------------------------------------------
//
// EnumDAdvise
//
//----------------------------------------------------------------------------
STDAPI CDataObject::EnumDAdvise(IEnumSTATDATA **ppesd) { return E_NOTIMPL; }
//+---------------------------------------------------------------------------
//
// _SetData
//
//----------------------------------------------------------------------------
HRESULT CDataObject::_SetData(const WCHAR *pch, ULONG cch) { FORMATETC fe; STGMEDIUM sm;
fe.cfFormat = CF_UNICODETEXT; fe.ptd = NULL; fe.dwAspect = DVASPECT_CONTENT; fe.lindex = -1; fe.tymed = TYMED_HGLOBAL;
sm.tymed = TYMED_HGLOBAL; sm.hGlobal = NULL; sm.pUnkForRelease = NULL; sm.hGlobal = GlobalAlloc(GMEM_FIXED, (cch+1)*sizeof(WCHAR));
if (sm.hGlobal == NULL) return E_OUTOFMEMORY;
memcpy(sm.hGlobal, pch, cch*sizeof(WCHAR)); ((WCHAR *)sm.hGlobal)[cch] = '\0';
return SetData(&fe, &sm, TRUE); }
|