https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6f25b42a3142868c232dcb718b188be9e2a6fc9d

commit 6f25b42a3142868c232dcb718b188be9e2a6fc9d
Author:     Giannis Adamopoulos <[email protected]>
AuthorDate: Sat Feb 17 13:59:51 2018 +0200
Commit:     Giannis Adamopoulos <[email protected]>
CommitDate: Sat Feb 17 20:30:37 2018 +0200

    [SHELL32] CFSDropTarget: Use copy depending on the source drive
    Show the default action as the default menu item in the right click menu.
---
 dll/win32/shell32/droptargets/CFSDropTarget.cpp | 46 ++++++++++++++++++++++---
 dll/win32/shell32/droptargets/CFSDropTarget.h   |  3 +-
 2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/dll/win32/shell32/droptargets/CFSDropTarget.cpp 
b/dll/win32/shell32/droptargets/CFSDropTarget.cpp
index 3337b455a0..deca859934 100644
--- a/dll/win32/shell32/droptargets/CFSDropTarget.cpp
+++ b/dll/win32/shell32/droptargets/CFSDropTarget.cpp
@@ -164,7 +164,7 @@ BOOL CFSDropTarget::QueryDrop(DWORD dwKeyState, LPDWORD 
pdwEffect)
     /* TODO Windows does different drop effects if dragging across drives. 
     i.e., it will copy instead of move if the directories are on different 
disks. */
 
-    DWORD dwEffect = DROPEFFECT_MOVE;
+    DWORD dwEffect = m_dwDefaultEffect;
 
     *pdwEffect = DROPEFFECT_NONE;
 
@@ -182,16 +182,32 @@ BOOL CFSDropTarget::QueryDrop(DWORD dwKeyState, LPDWORD 
pdwEffect)
     return FALSE;
 }
 
-HRESULT CFSDropTarget::_GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, 
DWORD *pdwEffect)
+HRESULT CFSDropTarget::_GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, 
DWORD *pdwEffect, DWORD dwAvailableEffects)
 {
     HMENU hmenu = LoadMenuW(shell32_hInstance, MAKEINTRESOURCEW(IDM_DRAGFILE));
     if (!hmenu)
         return E_OUTOFMEMORY;
 
+    HMENU hpopupmenu = GetSubMenu(hmenu, 0);
+
+    if ((dwAvailableEffects & DROPEFFECT_COPY) == 0)
+        DeleteMenu(hpopupmenu, IDM_COPYHERE, MF_BYCOMMAND);
+    else if ((dwAvailableEffects & DROPEFFECT_MOVE) == 0)
+        DeleteMenu(hpopupmenu, IDM_MOVEHERE, MF_BYCOMMAND);
+    else if ((dwAvailableEffects & DROPEFFECT_LINK) == 0)
+        DeleteMenu(hpopupmenu, IDM_LINKHERE, MF_BYCOMMAND);
+
+    if ((*pdwEffect & DROPEFFECT_COPY))
+        SetMenuDefaultItem(hpopupmenu, IDM_COPYHERE, FALSE);
+    else if ((*pdwEffect & DROPEFFECT_MOVE))
+        SetMenuDefaultItem(hpopupmenu, IDM_MOVEHERE, FALSE);
+    else if ((*pdwEffect & DROPEFFECT_LINK))
+        SetMenuDefaultItem(hpopupmenu, IDM_LINKHERE, FALSE);
+
     /* FIXME: We need to support shell extensions here */
 
-    UINT uCommand = TrackPopupMenu(GetSubMenu(hmenu, 0),
-                                   TPM_LEFTALIGN | TPM_RETURNCMD | 
TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
+    UINT uCommand = TrackPopupMenu(hpopupmenu,
+                                   TPM_LEFTALIGN | TPM_RETURNCMD | 
TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_NONOTIFY,
                                    pt.x, pt.y, 0, m_hwndSite, NULL);
     if (uCommand == 0)
         return S_FALSE;
@@ -263,6 +279,22 @@ HRESULT WINAPI CFSDropTarget::DragEnter(IDataObject 
*pDataObject,
         fAcceptFmt = TRUE;
 
     m_grfKeyState = dwKeyState;
+    m_dwDefaultEffect = DROPEFFECT_MOVE;
+
+    STGMEDIUM medium;
+    if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)))
+    {
+        WCHAR wstrFirstFile[MAX_PATH];
+        if (DragQueryFileW((HDROP)medium.hGlobal, 0, wstrFirstFile, 
_countof(wstrFirstFile)))
+        {
+            /* Check if the drive letter is different */
+            if (wstrFirstFile[0] != sPathTarget[0])
+            {
+                m_dwDefaultEffect = DROPEFFECT_COPY;
+            }
+        }
+        ReleaseStgMedium(&medium);
+    }
 
     QueryDrop(dwKeyState, pdwEffect);
     return S_OK;
@@ -302,11 +334,15 @@ HRESULT WINAPI CFSDropTarget::Drop(IDataObject 
*pDataObject,
 
     IUnknown_GetWindow(m_site, &m_hwndSite);
 
+    DWORD dwAvailableEffects = *pdwEffect;
+
     QueryDrop(dwKeyState, pdwEffect);
 
+    TRACE("pdwEffect: 0x%x, m_dwDefaultEffect: 0x%x, dwAvailableEffects: 
0x%x\n", *pdwEffect, m_dwDefaultEffect, dwAvailableEffects);
+
     if (m_grfKeyState & MK_RBUTTON)
     {
-        HRESULT hr = _GetEffectFromMenu(pDataObject, pt, pdwEffect);
+        HRESULT hr = _GetEffectFromMenu(pDataObject, pt, pdwEffect, 
dwAvailableEffects);
         if (FAILED_UNEXPECTEDLY(hr) || hr == S_FALSE)
             return hr;
     }
diff --git a/dll/win32/shell32/droptargets/CFSDropTarget.h 
b/dll/win32/shell32/droptargets/CFSDropTarget.h
index 091e60ee33..e0740d2ee7 100644
--- a/dll/win32/shell32/droptargets/CFSDropTarget.h
+++ b/dll/win32/shell32/droptargets/CFSDropTarget.h
@@ -34,6 +34,7 @@ class CFSDropTarget :
         LPWSTR sPathTarget;
         HWND m_hwndSite;
         DWORD m_grfKeyState;
+        DWORD m_dwDefaultEffect;
         CComPtr<IUnknown> m_site;
 
         BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
@@ -41,7 +42,7 @@ class CFSDropTarget :
         virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, 
LPCITEMIDLIST *apidl, BOOL bCopy);
         BOOL GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR 
pwszTarget, BOOL bShortcut);
         static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter);
-        HRESULT _GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, DWORD 
*pdwEffect);
+        HRESULT _GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, DWORD 
*pdwEffect, DWORD dwAvailableEffects);
         HRESULT _RepositionItems(IShellFolderView *psfv, IDataObject 
*pDataObject, POINTL pt);
 
     public:

Reply via email to