From c6df9e2fd8f92597a728935e67a6ac6c3bc1223c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 04:22:07 +0200
Subject: shell32: Remove source files when using cut in the context menu.

---
 dlls/shell32/shlview_cmenu.c | 75 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 71 insertions(+), 4 deletions(-)

diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index 494d95b..c32a4e8 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -281,6 +281,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
@@ -293,6 +351,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);
     }
@@ -818,11 +877,19 @@ static BOOL DoPaste(ContextMenu *This)
 	      /* do the copy/move */
 	      if (psfhlpdst && psfhlpsrc)
 	      {
+                DWORD dropEffect;
+                GetDropEffect(pda, &dropEffect);
+
                 if (SUCCEEDED(ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl)))
-                    bSuccess = TRUE;
-		/* FIXME handle move
-		ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, 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);
-- 
2.7.1

