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