221 lines
5 KiB
C++
221 lines
5 KiB
C++
#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;
|
|
}
|