|
|
#include "priv.h"
#include "bandobj.h"
UINT g_cfDeskBand = 0; UINT g_cfDeskBandState = 0;
void InitCFDeskBand() { if (!g_cfDeskBand) g_cfDeskBand = RegisterClipboardFormat(TEXT("DeskBand")); if (!g_cfDeskBandState) g_cfDeskBandState = RegisterClipboardFormat(TEXT("DeskBandState")); }
CBandDataObject::CBandDataObject() : _cRef(1) { InitCFDeskBand(); }
HRESULT CBandDataObject::Init(IUnknown* punkBand, IBandSite *pbs, DWORD dwBandID) { HRESULT hres = E_FAIL; _pstm = SHCreateMemStream(NULL, 0);
if (_pstm) {
IPersistStream *ppstm; punkBand->QueryInterface(IID_IPersistStream, (LPVOID*)&ppstm); if (ppstm) { LARGE_INTEGER li = {0}; OleSaveToStream(ppstm, _pstm); _pstm->Seek(li, STREAM_SEEK_SET, NULL); ppstm->Release();
// bandsite state flags
_dwState = 0; // (if we fail just do w/o the state flags)
if (pbs) pbs->QueryBand(dwBandID, NULL, &_dwState, NULL, 0);
hres = S_OK; } }
return hres; }
CBandDataObject::~CBandDataObject() { if (_pstm) _pstm->Release(); }
ULONG CBandDataObject::AddRef() { _cRef++; return _cRef; }
ULONG CBandDataObject::Release() { ASSERT(_cRef > 0); _cRef--;
if (_cRef > 0) return _cRef;
delete this; return 0; }
HRESULT CBandDataObject::QueryInterface(REFIID riid, LPVOID * ppvObj) { if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDataObject)) { *ppvObj = SAFECAST(this, IDataObject*); AddRef(); return S_OK; }
*ppvObj = NULL; return E_NOINTERFACE; }
// *** IDataObject ***
HRESULT CBandDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) { HRESULT hres = E_FAIL; if (pformatetcIn->cfFormat == g_cfDeskBand) { if (pformatetcIn->tymed & TYMED_ISTREAM && EVAL(_pstm)) { ASSERT(_pstm); pmedium->tymed = TYMED_ISTREAM; pmedium->pstm = _pstm; // no AddRef since we xfer ownership
_pstm = NULL; // can only use it 1x (read causes seek)
pmedium->pUnkForRelease = NULL;
hres = S_OK; } } else if (pformatetcIn->cfFormat == g_cfDeskBandState) { if (pformatetcIn->tymed & TYMED_HGLOBAL) { pmedium->tymed = TYMED_HGLOBAL; pmedium->hGlobal = GlobalAlloc(GPTR, sizeof (DWORD)); if (pmedium->hGlobal) { DWORD *pdw = (DWORD*)(pmedium->hGlobal);
*pdw = _dwState;
pmedium->pUnkForRelease = NULL;
hres = S_OK; } else { hres = E_OUTOFMEMORY; } } }
return hres; }
HRESULT CBandDataObject::GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium) { return E_NOTIMPL; }
HRESULT CBandDataObject::QueryGetData(FORMATETC *pformatetc) { HRESULT hres = S_FALSE; // TODO: (reuse, perf) use rgfmtetc table lookup
if ((pformatetc->cfFormat == g_cfDeskBand) && (pformatetc->tymed & TYMED_ISTREAM) || (pformatetc->cfFormat == g_cfDeskBandState) && (pformatetc->tymed & TYMED_HGLOBAL)) { hres = S_OK; } return hres; }
HRESULT CBandDataObject::GetCanonicalFormatEtc(FORMATETC *pformatetcIn, FORMATETC *pformatetcOut) { *pformatetcOut = *pformatetcIn; return DATA_S_SAMEFORMATETC; }
HRESULT CBandDataObject::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease) { return E_NOTIMPL; }
HRESULT CBandDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc) { HRESULT hr = E_FAIL;
if (dwDirection == DATADIR_GET) { FORMATETC rgfmtetc[] = { { g_cfDeskBand, NULL, 0, -1, TYMED_ISTREAM }, { g_cfDeskBandState, NULL, 0, -1, TYMED_HGLOBAL }, };
hr = SHCreateStdEnumFmtEtc(ARRAYSIZE(rgfmtetc), rgfmtetc, ppenumFormatEtc); } return hr; }
HRESULT CBandDataObject::DAdvise(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection) { return E_NOTIMPL; }
HRESULT CBandDataObject::DUnadvise(DWORD dwConnection) { return E_NOTIMPL; }
HRESULT CBandDataObject::EnumDAdvise(IEnumSTATDATA **ppenumAdvise) { return E_NOTIMPL; }
//*** IDataObject_GetDeskBandState -- get band's bandsite state flags from BandDataObject
// NOTES
// 'paired' w/ DragBandState (inline in CBandDataObject::Init)
DWORD IDataObject_GetDeskBandState(IDataObject *pdtobj) { DWORD dwState = 0; // (if we fail just do w/o the state flags)
FORMATETC fmte = {g_cfDeskBandState, NULL, 0, -1, TYMED_HGLOBAL}; STGMEDIUM stg; HRESULT hrTmp;
hrTmp = pdtobj->GetData(&fmte, &stg); if (SUCCEEDED(hrTmp)) { DWORD *p = (DWORD *)(stg.hGlobal);
dwState = *p;
ReleaseStgMedium(&stg); }
return dwState; }
|