From: Alistair Leslie-Hughes Subject: [PATCH 6/7] shell32: Remove source files when using cut in the context menu. Message-Id: Date: Fri, 25 May 2018 04:49:58 +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/shlview_cmenu.c | 77 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index f84ce31..9fdddee 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -300,6 +300,64 @@ static void DoDelete(ContextMenu *This) } /************************************************************************** + * SetDropEffect + * + * Set the drop effect in a IDataObject object + */ +static void SetDropEffect(IDataObject *dataobject, DWORD value) +{ + FORMATETC formatetc; + STGMEDIUM medium; + DWORD *effect; + + InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW), TYMED_HGLOBAL); + + medium.tymed = TYMED_HGLOBAL; + medium.pUnkForRelease = NULL; + medium.u.hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD)); + if (!medium.u.hGlobal) return; + + effect = GlobalLock(medium.u.hGlobal); + if (!effect) + { + ReleaseStgMedium(&medium); + return; + } + *effect = value; + GlobalUnlock(effect); + + IDataObject_SetData(dataobject, &formatetc, &medium, FALSE); + ReleaseStgMedium(&medium); +} + +/************************************************************************** + * GetDropEffect + * + * Get the drop effect from a IDataObject object + */ +static void GetDropEffect(IDataObject *dataobject, DWORD *value) +{ + FORMATETC formatetc; + STGMEDIUM medium; + DWORD *effect; + + *value = DROPEFFECT_NONE; + + InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW), TYMED_HGLOBAL); + + if (SUCCEEDED(IDataObject_GetData(dataobject, &formatetc, &medium))) + { + effect = GlobalLock(medium.u.hGlobal); + if (effect) + { + *value = *effect; + GlobalUnlock(effect); + } + ReleaseStgMedium(&medium); + } +} + +/************************************************************************** * DoCopyOrCut * * copies the currently selected items into the clipboard @@ -312,6 +370,7 @@ static void DoCopyOrCut(ContextMenu *This, HWND hwnd, BOOL cut) if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->parent, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, 0, (void**)&dataobject))) { + SetDropEffect(dataobject, cut ? DROPEFFECT_MOVE : DROPEFFECT_COPY); OleSetClipboard(dataobject); IDataObject_Release(dataobject); } @@ -1199,11 +1258,19 @@ static BOOL DoPaste(ContextMenu *This) /* do the copy/move */ if (psfhlpdst && psfhlpsrc) { - if (SUCCEEDED(ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl))) - bSuccess = TRUE; - /* FIXME handle move - ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl); - */ + DWORD dropEffect; + GetDropEffect(pda, &dropEffect); + + if (SUCCEEDED(ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl))) + { + if (dropEffect == DROPEFFECT_MOVE) + { + if (SUCCEEDED(ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, (LPCITEMIDLIST*)apidl, FALSE))) + bSuccess = TRUE; + } + else + bSuccess = TRUE; + } } if(psfhlpdst) ISFHelper_Release(psfhlpdst); if(psfhlpsrc) ISFHelper_Release(psfhlpsrc); -- 1.9.1