https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6f25b42a3142868c232dc…
commit 6f25b42a3142868c232dcb718b188be9e2a6fc9d
Author: Giannis Adamopoulos <gadamopoulos(a)reactos.org>
AuthorDate: Sat Feb 17 13:59:51 2018 +0200
Commit: Giannis Adamopoulos <gadamopoulos(a)reactos.org>
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: