From: Alistair Leslie-Hughes Subject: [PATCH 4/7] shell32: Add support for setting/getting PREFERREDDROPEFFECT in IDataObject. Message-Id: Date: Fri, 25 May 2018 04:49:55 +0000 In-Reply-To: <1527223779-15319-1-git-send-email-leslie_alistair@hotmail.com> References: <1527223779-15319-1-git-send-email-leslie_alistair@hotmail.com> From: Michael Müller Signed-off-by: Alistair Leslie-Hughes --- dlls/shell32/clipboard.c | 40 ++++++++++++++++++++++++++++++++++++++++ dlls/shell32/dataobject.c | 24 +++++++++++++++++++++--- dlls/shell32/shell32_main.h | 2 ++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/dlls/shell32/clipboard.c b/dlls/shell32/clipboard.c index 82df534..9c6f284 100644 --- a/dlls/shell32/clipboard.c +++ b/dlls/shell32/clipboard.c @@ -38,6 +38,8 @@ #include #include +#define NONAMELESSUNION + #include "windef.h" #include "winbase.h" #include "winreg.h" @@ -214,3 +216,41 @@ HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) return hGlobal; } + +HGLOBAL RenderPREFERREDDROPEFFECT (DWORD value) +{ + DWORD *pEffect; + HGLOBAL hGlobal; + + TRACE("(%d)\n", value); + + hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD)); + if(!hGlobal) return hGlobal; + + pEffect = GlobalLock(hGlobal); + if (pEffect) + { + *pEffect = value; + GlobalUnlock(hGlobal); + } + + return hGlobal; +} + +HRESULT GetPREFERREDDROPEFFECT (STGMEDIUM *pmedium, DWORD *value) +{ + DWORD *pEffect; + BOOL result = E_OUTOFMEMORY; + + TRACE("(%p, %p)\n", pmedium, value); + + pEffect = GlobalLock(pmedium->u.hGlobal); + if (pEffect) + { + *value = *pEffect; + result = S_OK; + GlobalUnlock(pmedium->u.hGlobal); + } + + return result; +} diff --git a/dlls/shell32/dataobject.c b/dlls/shell32/dataobject.c index ab72055..85278be 100644 --- a/dlls/shell32/dataobject.c +++ b/dlls/shell32/dataobject.c @@ -196,7 +196,7 @@ LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[]) */ /* number of supported formats */ -#define MAX_FORMATS 4 +#define MAX_FORMATS 5 typedef struct { @@ -208,12 +208,13 @@ typedef struct LPITEMIDLIST pidl; LPITEMIDLIST * apidl; UINT cidl; + DWORD dropEffect; FORMATETC pFormatEtc[MAX_FORMATS]; UINT cfShellIDList; UINT cfFileNameA; UINT cfFileNameW; - + UINT cfDropEffect; } IDataObjectImpl; static inline IDataObjectImpl *impl_from_IDataObject(IDataObject *iface) @@ -313,6 +314,10 @@ static HRESULT WINAPI IDataObject_fnGetData(IDataObject *iface, LPFORMATETC pfor if (This->cidl < 1) return(E_UNEXPECTED); pmedium->u.hGlobal = RenderFILENAMEW(This->pidl, This->apidl, This->cidl); } + else if (pformatetcIn->cfFormat == This->cfDropEffect) + { + pmedium->u.hGlobal = RenderPREFERREDDROPEFFECT(This->dropEffect); + } else { FIXME("-- expected clipformat not implemented\n"); @@ -367,7 +372,17 @@ static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(IDataObject *iface, LP static HRESULT WINAPI IDataObject_fnSetData(IDataObject *iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease) { IDataObjectImpl *This = impl_from_IDataObject(iface); - FIXME("(%p)->()\n", This); + + FIXME("(%p)->(%p, %p, %u): semi-stub\n", This, pformatetc, pmedium, fRelease); + + if (pformatetc->cfFormat == This->cfDropEffect) + { + if (pmedium->tymed == TYMED_HGLOBAL) + return GetPREFERREDDROPEFFECT(pmedium, &This->dropEffect); + else + return DV_E_TYMED; + } + return E_NOTIMPL; } @@ -440,14 +455,17 @@ IDataObject* IDataObject_Constructor(HWND hwndOwner, dto->pidl = ILClone(pMyPidl); dto->apidl = _ILCopyaPidl(apidl, cidl); dto->cidl = cidl; + dto->dropEffect = 0; dto->cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW); dto->cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA); dto->cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW); + dto->cfDropEffect = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW); InitFormatEtc(dto->pFormatEtc[0], dto->cfShellIDList, TYMED_HGLOBAL); InitFormatEtc(dto->pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL); InitFormatEtc(dto->pFormatEtc[2], dto->cfFileNameA, TYMED_HGLOBAL); InitFormatEtc(dto->pFormatEtc[3], dto->cfFileNameW, TYMED_HGLOBAL); + InitFormatEtc(dto->pFormatEtc[4], dto->cfDropEffect, TYMED_HGLOBAL); } TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl); diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h index d1b0e01..fa2a549 100644 --- a/dlls/shell32/shell32_main.h +++ b/dlls/shell32/shell32_main.h @@ -141,6 +141,8 @@ HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECL HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN; HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN; HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN; +HGLOBAL RenderPREFERREDDROPEFFECT (DWORD value) DECLSPEC_HIDDEN; +HRESULT GetPREFERREDDROPEFFECT (STGMEDIUM *pmedium, DWORD *value) DECLSPEC_HIDDEN; /* Change Notification */ void InitChangeNotifications(void) DECLSPEC_HIDDEN; -- 1.9.1