16BEGIN_IGRAPHICS_NAMESPACE
18namespace DragAndDropHelpers
26 assert(mRefCount == 0);
29 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID refiid,
void** resultHandle)
override
31 if (refiid == IID_IDropSource)
37 *resultHandle =
nullptr;
41 ULONG STDMETHODCALLTYPE AddRef ()
override {
return ++mRefCount; }
42 ULONG STDMETHODCALLTYPE Release()
override
44 int refCount = --mRefCount;
45 assert(refCount >= 0);
54 HRESULT STDMETHODCALLTYPE QueryContinueDrag(BOOL escapeKeyPressed, DWORD grfKeyState)
override
56 if (escapeKeyPressed == TRUE)
58 DBGMSG(
"DropSource: escapeKeyPressed, abort dnd\n");
59 return DRAGDROP_S_CANCEL;
62 if ((grfKeyState & MK_LBUTTON) == 0)
64 return DRAGDROP_S_DROP;
69 HRESULT STDMETHODCALLTYPE GiveFeedback(DWORD )
override
71 return DRAGDROP_S_USEDEFAULTCURSORS;
77static void deepFormatCopy(FORMATETC& dest,
const FORMATETC& source)
80 if (source.ptd !=
nullptr)
82 dest.ptd = (DVTARGETDEVICE*) CoTaskMemAlloc (
sizeof (DVTARGETDEVICE));
83 if (dest.ptd !=
nullptr)
85 *(dest.ptd) = *(source.ptd);
96 ULONG STDMETHODCALLTYPE AddRef(
void) {
return ++mRefCount; }
97 ULONG STDMETHODCALLTYPE Release(
void)
99 int refCount = --mRefCount;
100 assert(refCount >= 0);
107 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID refiid,
void **resultHandle)
109 if (refiid == IID_IEnumFORMATETC)
112 *resultHandle =
this;
115 *resultHandle =
nullptr;
116 return E_NOINTERFACE;
119 HRESULT Clone (IEnumFORMATETC** resultHandle)
override
121 if (resultHandle ==
nullptr)
126 copyObj->mCounter = mCounter;
127 *resultHandle = copyObj;
131 HRESULT Next (ULONG celt, FORMATETC *pFormat, ULONG* pceltFetched)
override
133 if (pceltFetched !=
nullptr)
142 if (mCounter == 0 && celt > 0 && pFormat !=
nullptr)
144 deepFormatCopy(pFormat[0], *mFormatPtr);
146 if (pceltFetched !=
nullptr)
155 HRESULT Skip (ULONG celt)
override
157 if (mCounter + (
int) celt >= 1)
161 mCounter += (int) celt;
165 HRESULT Reset()
override
173 const FORMATETC*
const mFormatPtr;
181 DataObject(
const FORMATETC* f,
const char *filePath) : mFormatPtr (f)
183 mFilePath = filePath;
188 assert(mRefCount == 0);
191 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID refiid,
void **resultHandle)
193 if (refiid == IID_IDataObject || refiid == IID_IUnknown)
199 *resultHandle = NULL;
200 return E_NOINTERFACE;
203 ULONG STDMETHODCALLTYPE AddRef() {
return ++mRefCount; }
204 ULONG STDMETHODCALLTYPE Release()
206 int refCount = --mRefCount;
207 assert(mRefCount>=0);
215 bool acceptFormat(FORMATETC *f)
217 return (f->dwAspect & DVASPECT_CONTENT) && (f->tymed & TYMED_HGLOBAL) && (f->cfFormat == CF_HDROP);
220 HRESULT STDMETHODCALLTYPE GetData(FORMATETC *pFormat, STGMEDIUM *pMedium)
222 if (pFormat ==
nullptr)
227 if (acceptFormat(pFormat) ==
false)
229 return DV_E_FORMATETC;
232 UTF8AsUTF16 pathWide(mFilePath.c_str());
234 HDROP hGlobal = (HDROP)GlobalAlloc(GHND,
sizeof(DROPFILES) + (
sizeof(wchar_t) * (pathWide.GetLength() + 2)));
238 DBGMSG(
"DataObject::GetData ERROR: GlobalAlloc returned null, aborting.\n");
242 DROPFILES* pDropFiles = (DROPFILES*) GlobalLock(hGlobal);
245 DBGMSG(
"DataObject::GetData ERROR: GlobalLock returned null, aborting.\n");
249 pDropFiles->pFiles =
sizeof(DROPFILES);
250 pDropFiles->fWide =
true;
251 std::copy_n(pathWide.Get(), pathWide.GetLength(),
reinterpret_cast<wchar_t*
>(&pDropFiles[1]));
254 pMedium->tymed = TYMED_HGLOBAL;
255 pMedium->hGlobal = hGlobal;
256 pMedium->pUnkForRelease =
nullptr;
258 GlobalUnlock(hGlobal);
263 HRESULT STDMETHODCALLTYPE QueryGetData( FORMATETC *pFormat )
265 if (pFormat ==
nullptr)
270 if (acceptFormat(pFormat) ==
false)
272 return DV_E_FORMATETC;
278 HRESULT GetCanonicalFormatEtc(FORMATETC*, FORMATETC* pFormatOut)
override
280 pFormatOut->ptd =
nullptr;
284 HRESULT EnumFormatEtc(DWORD direction, IEnumFORMATETC** resultHandle)
override
290 if (direction == DATADIR_GET)
295 *resultHandle =
nullptr;
300 HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC*, STGMEDIUM*) {
return E_NOTIMPL; }
301 HRESULT STDMETHODCALLTYPE SetData(FORMATETC*, STGMEDIUM*, BOOL) {
return E_NOTIMPL; }
302 HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC*, DWORD, IAdviseSink*, DWORD*) {
return E_NOTIMPL; }
303 HRESULT STDMETHODCALLTYPE DUnadvise(DWORD) {
return E_NOTIMPL; }
304 HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA**) {
return E_NOTIMPL; }
307 std::string mFilePath;
308 const FORMATETC*
const mFormatPtr;
312END_IGRAPHICS_NAMESPACE
IPlug logging a.k.a tracing functionality.