mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patches to fix multiple issues in shell32 context menu handling.
This commit is contained in:
parent
bd61bfe45f
commit
1f27eee3ed
@ -294,6 +294,7 @@ patch_enable_all ()
|
||||
enable_setupapi_SetupPromptForDisk="$1"
|
||||
enable_sfc_SfcGetNextProtectedFile="$1"
|
||||
enable_shdocvw_ParseURLFromOutsideSource_Tests="$1"
|
||||
enable_shell32_Context_Menu="$1"
|
||||
enable_shell32_Default_Path="$1"
|
||||
enable_shell32_File_Property_Dialog="$1"
|
||||
enable_shell32_FolderItems_Stub_Iface="$1"
|
||||
@ -1059,6 +1060,9 @@ patch_enable ()
|
||||
shdocvw-ParseURLFromOutsideSource_Tests)
|
||||
enable_shdocvw_ParseURLFromOutsideSource_Tests="$2"
|
||||
;;
|
||||
shell32-Context_Menu)
|
||||
enable_shell32_Context_Menu="$2"
|
||||
;;
|
||||
shell32-Default_Path)
|
||||
enable_shell32_Default_Path="$2"
|
||||
;;
|
||||
@ -6181,6 +6185,39 @@ if test "$enable_shdocvw_ParseURLFromOutsideSource_Tests" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset shell32-Context_Menu
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#34319] Add support for Paste in context menu
|
||||
# | * [#34322] Fix implementation of Cut file operation
|
||||
# | * [#34321] Fix Cut/Copy/Paste keyboard shortcuts in Total Commander
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/shell32/clipboard.c, dlls/shell32/dataobject.c, dlls/shell32/recyclebin.c, dlls/shell32/shell32.rc,
|
||||
# | dlls/shell32/shell32_main.h, dlls/shell32/shellfolder.h, dlls/shell32/shfldr_fs.c, dlls/shell32/shfldr_unixfs.c,
|
||||
# | dlls/shell32/shlview.c, dlls/shell32/shlview_cmenu.c
|
||||
# |
|
||||
if test "$enable_shell32_Context_Menu" -eq 1; then
|
||||
patch_apply shell32-Context_Menu/0001-shell32-Fix-copying-of-files-when-using-a-context-me.patch
|
||||
patch_apply shell32-Context_Menu/0002-shell32-Set-return-value-correctly-in-DoPaste.patch
|
||||
patch_apply shell32-Context_Menu/0003-shell32-Implement-insert-paste-for-item-context-menu.patch
|
||||
patch_apply shell32-Context_Menu/0004-shell32-Correctly-interpret-result-of-SHFileOperatio.patch
|
||||
patch_apply shell32-Context_Menu/0005-shell32-Add-support-for-setting-getting-PREFERREDDRO.patch
|
||||
patch_apply shell32-Context_Menu/0006-shell32-Add-parameter-to-ISFHelper-DeleteItems-to-al.patch
|
||||
patch_apply shell32-Context_Menu/0007-shell32-Remove-source-files-when-using-cut-in-the-co.patch
|
||||
patch_apply shell32-Context_Menu/0008-shell32-Recognize-cut-copy-paste-string-verbs-in-ite.patch
|
||||
(
|
||||
echo '+ { "Michael Müller", "shell32: Fix copying of files when using a context menu.", 1 },';
|
||||
echo '+ { "Michael Müller", "shell32: Set return value correctly in DoPaste.", 1 },';
|
||||
echo '+ { "Michael Müller", "shell32: Implement insert/paste for item context menus.", 1 },';
|
||||
echo '+ { "Michael Müller", "shell32: Correctly interpret result of SHFileOperation in UNIXFS copy and delete.", 1 },';
|
||||
echo '+ { "Michael Müller", "shell32: Add support for setting/getting PREFERREDDROPEFFECT in IDataObject.", 1 },';
|
||||
echo '+ { "Michael Müller", "shell32: Add parameter to ISFHelper::DeleteItems to allow deleting files without confirmation.", 1 },';
|
||||
echo '+ { "Michael Müller", "shell32: Remove source files when using cut in the context menu.", 1 },';
|
||||
echo '+ { "Michael Müller", "shell32: Recognize cut/copy/paste string verbs in item menu context menu.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset shell32-Default_Path
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 9175a389d86cc231e7e8158360402feb7c5b269e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 2 Apr 2016 00:22:30 +0200
|
||||
Subject: shell32: Fix copying of files when using a context menu.
|
||||
|
||||
---
|
||||
dlls/shell32/shlview_cmenu.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
|
||||
index 099f5bc..552b809 100644
|
||||
--- a/dlls/shell32/shlview_cmenu.c
|
||||
+++ b/dlls/shell32/shlview_cmenu.c
|
||||
@@ -739,6 +739,13 @@ static BOOL DoPaste(ContextMenu *This)
|
||||
|
||||
apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
|
||||
|
||||
+ /*
|
||||
+ * In case source is a file we need to remove the last component
|
||||
+ * to obtain a IShellFolder of the parent.
|
||||
+ */
|
||||
+ if (_ILIsValue(pidl))
|
||||
+ ILRemoveLastID(pidl);
|
||||
+
|
||||
/* bind to the source shellfolder */
|
||||
SHGetDesktopFolder(&psfDesktop);
|
||||
if(psfDesktop)
|
||||
--
|
||||
2.7.1
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 7f13fd37d55efe4cc20c4c3eb1c79d3c8ef0040d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 2 Apr 2016 01:21:34 +0200
|
||||
Subject: shell32: Set return value correctly in DoPaste.
|
||||
|
||||
---
|
||||
dlls/shell32/shlview_cmenu.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
|
||||
index 552b809..7ce6cd9 100644
|
||||
--- a/dlls/shell32/shlview_cmenu.c
|
||||
+++ b/dlls/shell32/shlview_cmenu.c
|
||||
@@ -764,7 +764,8 @@ static BOOL DoPaste(ContextMenu *This)
|
||||
/* do the copy/move */
|
||||
if (psfhlpdst && psfhlpsrc)
|
||||
{
|
||||
- ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
|
||||
+ if (SUCCEEDED(ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl)))
|
||||
+ bSuccess = TRUE;
|
||||
/* FIXME handle move
|
||||
ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
|
||||
*/
|
||||
--
|
||||
2.7.1
|
||||
|
@ -0,0 +1,165 @@
|
||||
From f378913d8cb2e40abb4e24d4bfaf0cbe7ea8134a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 2 Apr 2016 01:39:40 +0200
|
||||
Subject: shell32: Implement insert/paste for item context menus.
|
||||
|
||||
---
|
||||
dlls/shell32/shell32.rc | 1 +
|
||||
dlls/shell32/shlview_cmenu.c | 68 +++++++++++++++++++++++++++++++++++++++-----
|
||||
2 files changed, 62 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc
|
||||
index bfba962..4f2015b 100644
|
||||
--- a/dlls/shell32/shell32.rc
|
||||
+++ b/dlls/shell32/shell32.rc
|
||||
@@ -99,6 +99,7 @@ BEGIN
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "C&ut", FCIDM_SHVIEW_CUT
|
||||
MENUITEM "&Copy", FCIDM_SHVIEW_COPY
|
||||
+ MENUITEM "&Paste", FCIDM_SHVIEW_INSERT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Create &Link", FCIDM_SHVIEW_CREATELINK
|
||||
MENUITEM "&Delete", FCIDM_SHVIEW_DELETE
|
||||
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
|
||||
index 7ce6cd9..d972922 100644
|
||||
--- a/dlls/shell32/shlview_cmenu.c
|
||||
+++ b/dlls/shell32/shlview_cmenu.c
|
||||
@@ -59,6 +59,8 @@ typedef struct
|
||||
BOOL desktop;
|
||||
} ContextMenu;
|
||||
|
||||
+static BOOL DoPaste(ContextMenu *This);
|
||||
+
|
||||
static inline ContextMenu *impl_from_IContextMenu3(IContextMenu3 *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, ContextMenu, IContextMenu3_iface);
|
||||
@@ -123,6 +125,30 @@ static ULONG WINAPI ContextMenu_Release(IContextMenu3 *iface)
|
||||
return ref;
|
||||
}
|
||||
|
||||
+static BOOL CheckClipboard(void)
|
||||
+{
|
||||
+ IDataObject *pda;
|
||||
+ BOOL ret = FALSE;
|
||||
+
|
||||
+ if (SUCCEEDED(OleGetClipboard(&pda)))
|
||||
+ {
|
||||
+ STGMEDIUM medium;
|
||||
+ FORMATETC formatetc;
|
||||
+
|
||||
+ /* Set the FORMATETC structure*/
|
||||
+ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL);
|
||||
+
|
||||
+ /* Get the pidls from IDataObject */
|
||||
+ if (SUCCEEDED(IDataObject_GetData(pda, &formatetc, &medium)))
|
||||
+ {
|
||||
+ ReleaseStgMedium(&medium);
|
||||
+ ret = TRUE;
|
||||
+ }
|
||||
+ IDataObject_Release(pda);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||
IContextMenu3 *iface,
|
||||
HMENU hmenu,
|
||||
@@ -133,6 +159,7 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||
{
|
||||
ContextMenu *This = impl_from_IContextMenu3(iface);
|
||||
INT uIDMax;
|
||||
+ DWORD attr = SFGAO_CANRENAME;
|
||||
|
||||
TRACE("(%p)->(%p %d 0x%x 0x%x 0x%x )\n", This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
|
||||
|
||||
@@ -169,6 +196,9 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||
|
||||
SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
|
||||
|
||||
+ if (This->apidl && This->cidl == 1)
|
||||
+ IShellFolder_GetAttributesOf(This->parent, 1, (LPCITEMIDLIST*)This->apidl, &attr);
|
||||
+
|
||||
if(uFlags & ~CMF_CANRENAME)
|
||||
RemoveMenu(hmenu, FCIDM_SHVIEW_RENAME, MF_BYCOMMAND);
|
||||
else
|
||||
@@ -179,16 +209,14 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
|
||||
if (!This->apidl || This->cidl > 1)
|
||||
enable |= MFS_DISABLED;
|
||||
else
|
||||
- {
|
||||
- DWORD attr = SFGAO_CANRENAME;
|
||||
-
|
||||
- IShellFolder_GetAttributesOf(This->parent, 1, (LPCITEMIDLIST*)This->apidl, &attr);
|
||||
enable |= (attr & SFGAO_CANRENAME) ? MFS_ENABLED : MFS_DISABLED;
|
||||
- }
|
||||
|
||||
EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME, enable);
|
||||
}
|
||||
|
||||
+ if ((attr & (SFGAO_FILESYSTEM|SFGAO_FOLDER)) != (SFGAO_FILESYSTEM|SFGAO_FOLDER) || !CheckClipboard())
|
||||
+ RemoveMenu(hmenu, FCIDM_SHVIEW_INSERT + idCmdFirst, MF_BYCOMMAND);
|
||||
+
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, uIDMax-idCmdFirst);
|
||||
}
|
||||
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
|
||||
@@ -447,6 +475,10 @@ static HRESULT WINAPI ItemMenu_InvokeCommand(
|
||||
TRACE("Verb FCIDM_SHVIEW_CUT\n");
|
||||
DoCopyOrCut(This, lpcmi->hwnd, TRUE);
|
||||
break;
|
||||
+ case FCIDM_SHVIEW_INSERT:
|
||||
+ TRACE("Verb FCIDM_SHVIEW_INSERT\n");
|
||||
+ DoPaste(This);
|
||||
+ break;
|
||||
case FCIDM_SHVIEW_PROPERTIES:
|
||||
TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n");
|
||||
DoOpenProperties(This, lpcmi->hwnd);
|
||||
@@ -510,6 +542,10 @@ static HRESULT WINAPI ItemMenu_GetCommandString(
|
||||
strcpy(lpszName, "copy");
|
||||
hr = S_OK;
|
||||
break;
|
||||
+ case FCIDM_SHVIEW_INSERT:
|
||||
+ strcpy(lpszName, "paste");
|
||||
+ hr = S_OK;
|
||||
+ break;
|
||||
case FCIDM_SHVIEW_CREATELINK:
|
||||
strcpy(lpszName, "link");
|
||||
hr = S_OK;
|
||||
@@ -550,6 +586,10 @@ static HRESULT WINAPI ItemMenu_GetCommandString(
|
||||
MultiByteToWideChar(CP_ACP, 0, "copy", -1, (LPWSTR)lpszName, uMaxNameLen);
|
||||
hr = S_OK;
|
||||
break;
|
||||
+ case FCIDM_SHVIEW_INSERT:
|
||||
+ MultiByteToWideChar(CP_ACP, 0, "paste", -1, (LPWSTR)lpszName, uMaxNameLen);
|
||||
+ hr = S_OK;
|
||||
+ break;
|
||||
case FCIDM_SHVIEW_CREATELINK:
|
||||
MultiByteToWideChar(CP_ACP, 0, "link", -1, (LPWSTR)lpszName, uMaxNameLen);
|
||||
hr = S_OK;
|
||||
@@ -757,8 +797,22 @@ static BOOL DoPaste(ContextMenu *This)
|
||||
if (psfFrom)
|
||||
{
|
||||
/* get source and destination shellfolder */
|
||||
- ISFHelper *psfhlpdst, *psfhlpsrc;
|
||||
- IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst);
|
||||
+ ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL;
|
||||
+
|
||||
+ /* when using an item context menu we first need to bind to the selected folder */
|
||||
+ if (This->apidl)
|
||||
+ {
|
||||
+ IShellFolder *folder;
|
||||
+
|
||||
+ if (SUCCEEDED(IShellFolder_BindToObject(This->parent, This->apidl[0], NULL, &IID_IShellFolder, (LPVOID*)&folder)))
|
||||
+ {
|
||||
+ IShellFolder_QueryInterface(folder, &IID_ISFHelper, (void**)&psfhlpdst);
|
||||
+ IShellFolder_Release(folder);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst);
|
||||
+
|
||||
IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc);
|
||||
|
||||
/* do the copy/move */
|
||||
--
|
||||
2.7.1
|
||||
|
@ -0,0 +1,35 @@
|
||||
From 540ec171b1ad3d84c2087f616151103e4a4593df Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Sat, 2 Apr 2016 03:47:48 +0200
|
||||
Subject: shell32: Correctly interpret result of SHFileOperation in UNIXFS copy
|
||||
and delete.
|
||||
|
||||
---
|
||||
dlls/shell32/shfldr_unixfs.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
|
||||
index be1ba81..17998f2 100644
|
||||
--- a/dlls/shell32/shfldr_unixfs.c
|
||||
+++ b/dlls/shell32/shfldr_unixfs.c
|
||||
@@ -847,7 +847,7 @@ static HRESULT UNIXFS_copy(LPCWSTR pwszDosSrc, LPCWSTR pwszDosDst)
|
||||
op.pFrom = pwszSrc;
|
||||
op.pTo = pwszDst;
|
||||
op.fFlags = FOF_ALLOWUNDO;
|
||||
- if (!SHFileOperationW(&op))
|
||||
+ if (SHFileOperationW(&op))
|
||||
{
|
||||
WARN("SHFileOperationW failed\n");
|
||||
res = E_FAIL;
|
||||
@@ -1981,7 +1981,7 @@ static HRESULT UNIXFS_delete_with_shfileop(UnixFolder *This, UINT cidl, const LP
|
||||
op.wFunc = FO_DELETE;
|
||||
op.pFrom = wszPathsList;
|
||||
op.fFlags = FOF_ALLOWUNDO;
|
||||
- if (!SHFileOperationW(&op))
|
||||
+ if (SHFileOperationW(&op))
|
||||
{
|
||||
WARN("SHFileOperationW failed\n");
|
||||
ret = E_FAIL;
|
||||
--
|
||||
2.7.1
|
||||
|
@ -0,0 +1,159 @@
|
||||
From 9540fdc5b1668e4b575ce00539454b8ac66457a0 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:15:02 +0200
|
||||
Subject: shell32: Add support for setting/getting PREFERREDDROPEFFECT in
|
||||
IDataObject.
|
||||
|
||||
---
|
||||
dlls/shell32/clipboard.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/shell32/dataobject.c | 24 +++++++++++++++++++++---
|
||||
dlls/shell32/shell32_main.h | 2 ++
|
||||
3 files changed, 63 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/shell32/clipboard.c b/dlls/shell32/clipboard.c
|
||||
index 82df534..9c6f284 100644
|
||||
--- a/dlls/shell32/clipboard.c
|
||||
+++ b/dlls/shell32/clipboard.c
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
+#define NONAMELESSUNION
|
||||
+
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
@@ -214,3 +216,41 @@ HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
|
||||
|
||||
return hGlobal;
|
||||
}
|
||||
+
|
||||
+HGLOBAL RenderPREFERREDDROPEFFECT (DWORD value)
|
||||
+{
|
||||
+ DWORD *pEffect;
|
||||
+ HGLOBAL hGlobal;
|
||||
+
|
||||
+ TRACE("(%d)\n", value);
|
||||
+
|
||||
+ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
|
||||
+ if(!hGlobal) return hGlobal;
|
||||
+
|
||||
+ pEffect = GlobalLock(hGlobal);
|
||||
+ if (pEffect)
|
||||
+ {
|
||||
+ *pEffect = value;
|
||||
+ GlobalUnlock(hGlobal);
|
||||
+ }
|
||||
+
|
||||
+ return hGlobal;
|
||||
+}
|
||||
+
|
||||
+HRESULT GetPREFERREDDROPEFFECT (STGMEDIUM *pmedium, DWORD *value)
|
||||
+{
|
||||
+ DWORD *pEffect;
|
||||
+ BOOL result = E_OUTOFMEMORY;
|
||||
+
|
||||
+ TRACE("(%p, %p)\n", pmedium, value);
|
||||
+
|
||||
+ pEffect = GlobalLock(pmedium->u.hGlobal);
|
||||
+ if (pEffect)
|
||||
+ {
|
||||
+ *value = *pEffect;
|
||||
+ result = S_OK;
|
||||
+ GlobalUnlock(pmedium->u.hGlobal);
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
diff --git a/dlls/shell32/dataobject.c b/dlls/shell32/dataobject.c
|
||||
index cc7b63e..5a18a1a 100644
|
||||
--- a/dlls/shell32/dataobject.c
|
||||
+++ b/dlls/shell32/dataobject.c
|
||||
@@ -197,7 +197,7 @@ LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[])
|
||||
*/
|
||||
|
||||
/* number of supported formats */
|
||||
-#define MAX_FORMATS 4
|
||||
+#define MAX_FORMATS 5
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -209,12 +209,13 @@ typedef struct
|
||||
LPITEMIDLIST pidl;
|
||||
LPITEMIDLIST * apidl;
|
||||
UINT cidl;
|
||||
+ DWORD dropEffect;
|
||||
|
||||
FORMATETC pFormatEtc[MAX_FORMATS];
|
||||
UINT cfShellIDList;
|
||||
UINT cfFileNameA;
|
||||
UINT cfFileNameW;
|
||||
-
|
||||
+ UINT cfDropEffect;
|
||||
} IDataObjectImpl;
|
||||
|
||||
static inline IDataObjectImpl *impl_from_IDataObject(IDataObject *iface)
|
||||
@@ -314,6 +315,10 @@ static HRESULT WINAPI IDataObject_fnGetData(IDataObject *iface, LPFORMATETC pfor
|
||||
if (This->cidl < 1) return(E_UNEXPECTED);
|
||||
pmedium->u.hGlobal = RenderFILENAMEW(This->pidl, This->apidl, This->cidl);
|
||||
}
|
||||
+ else if (pformatetcIn->cfFormat == This->cfDropEffect)
|
||||
+ {
|
||||
+ pmedium->u.hGlobal = RenderPREFERREDDROPEFFECT(This->dropEffect);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
FIXME("-- expected clipformat not implemented\n");
|
||||
@@ -368,7 +373,17 @@ static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(IDataObject *iface, LP
|
||||
static HRESULT WINAPI IDataObject_fnSetData(IDataObject *iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
|
||||
{
|
||||
IDataObjectImpl *This = impl_from_IDataObject(iface);
|
||||
- FIXME("(%p)->()\n", This);
|
||||
+
|
||||
+ FIXME("(%p)->(%p, %p, %u): semi-stub\n", This, pformatetc, pmedium, fRelease);
|
||||
+
|
||||
+ if (pformatetc->cfFormat == This->cfDropEffect)
|
||||
+ {
|
||||
+ if (pmedium->tymed == TYMED_HGLOBAL)
|
||||
+ return GetPREFERREDDROPEFFECT(pmedium, &This->dropEffect);
|
||||
+ else
|
||||
+ return DV_E_TYMED;
|
||||
+ }
|
||||
+
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -441,14 +456,17 @@ IDataObject* IDataObject_Constructor(HWND hwndOwner,
|
||||
dto->pidl = ILClone(pMyPidl);
|
||||
dto->apidl = _ILCopyaPidl(apidl, cidl);
|
||||
dto->cidl = cidl;
|
||||
+ dto->dropEffect = 0;
|
||||
|
||||
dto->cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
|
||||
dto->cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA);
|
||||
dto->cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW);
|
||||
+ dto->cfDropEffect = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW);
|
||||
InitFormatEtc(dto->pFormatEtc[0], dto->cfShellIDList, TYMED_HGLOBAL);
|
||||
InitFormatEtc(dto->pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL);
|
||||
InitFormatEtc(dto->pFormatEtc[2], dto->cfFileNameA, TYMED_HGLOBAL);
|
||||
InitFormatEtc(dto->pFormatEtc[3], dto->cfFileNameW, TYMED_HGLOBAL);
|
||||
+ InitFormatEtc(dto->pFormatEtc[4], dto->cfDropEffect, TYMED_HGLOBAL);
|
||||
}
|
||||
|
||||
TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl);
|
||||
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
|
||||
index 492f79f..29822b7 100644
|
||||
--- a/dlls/shell32/shell32_main.h
|
||||
+++ b/dlls/shell32/shell32_main.h
|
||||
@@ -130,6 +130,8 @@ HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECL
|
||||
HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
|
||||
HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
|
||||
HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
|
||||
+HGLOBAL RenderPREFERREDDROPEFFECT (DWORD value);
|
||||
+HRESULT GetPREFERREDDROPEFFECT (STGMEDIUM *pmedium, DWORD *value);
|
||||
|
||||
/* Change Notification */
|
||||
void InitChangeNotifications(void) DECLSPEC_HIDDEN;
|
||||
--
|
||||
2.7.1
|
||||
|
@ -0,0 +1,152 @@
|
||||
From 60a000e4b5c59b93db1ea24566ad4d7eeea9408b 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:17:19 +0200
|
||||
Subject: shell32: Add parameter to ISFHelper::DeleteItems to allow deleting
|
||||
files without confirmation.
|
||||
|
||||
---
|
||||
dlls/shell32/recyclebin.c | 6 +++---
|
||||
dlls/shell32/shellfolder.h | 4 ++--
|
||||
dlls/shell32/shfldr_fs.c | 3 ++-
|
||||
dlls/shell32/shfldr_unixfs.c | 7 ++++---
|
||||
dlls/shell32/shlview.c | 2 +-
|
||||
dlls/shell32/shlview_cmenu.c | 2 +-
|
||||
6 files changed, 13 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/dlls/shell32/recyclebin.c b/dlls/shell32/recyclebin.c
|
||||
index 28098af..f890d97 100644
|
||||
--- a/dlls/shell32/recyclebin.c
|
||||
+++ b/dlls/shell32/recyclebin.c
|
||||
@@ -182,7 +182,7 @@ static void DoErase(RecycleBinMenu *This)
|
||||
ISFHelper *helper;
|
||||
IShellFolder2_QueryInterface(This->folder,&IID_ISFHelper,(void**)&helper);
|
||||
if(helper)
|
||||
- ISFHelper_DeleteItems(helper,This->cidl,(LPCITEMIDLIST*)This->apidl);
|
||||
+ ISFHelper_DeleteItems(helper, This->cidl, (LPCITEMIDLIST *)This->apidl, TRUE);
|
||||
}
|
||||
|
||||
static void DoRestore(RecycleBinMenu *This)
|
||||
@@ -824,10 +824,10 @@ static HRESULT erase_items(HWND parent,const LPCITEMIDLIST * apidl, UINT cidl, B
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RecycleBin_DeleteItems(ISFHelper * iface, UINT cidl,
|
||||
- LPCITEMIDLIST * apidl)
|
||||
+ LPCITEMIDLIST * apidl, BOOL confirm)
|
||||
{
|
||||
TRACE("(%p,%u,%p)\n",iface,cidl,apidl);
|
||||
- return erase_items(GetActiveWindow(),apidl,cidl,TRUE);
|
||||
+ return erase_items(GetActiveWindow(), apidl, cidl, confirm);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI RecycleBin_CopyItems(ISFHelper * iface,
|
||||
diff --git a/dlls/shell32/shellfolder.h b/dlls/shell32/shellfolder.h
|
||||
index 942e0e7..b8083a2 100644
|
||||
--- a/dlls/shell32/shellfolder.h
|
||||
+++ b/dlls/shell32/shellfolder.h
|
||||
@@ -48,7 +48,7 @@ DECLARE_INTERFACE_(ISFHelper,IUnknown)
|
||||
/*** ISFHelper methods ***/
|
||||
STDMETHOD(GetUniqueName)(THIS_ LPWSTR lpName, UINT uLen) PURE;
|
||||
STDMETHOD(AddFolder)(THIS_ HWND hwnd, LPCWSTR lpName, LPITEMIDLIST * ppidlOut) PURE;
|
||||
- STDMETHOD(DeleteItems)(THIS_ UINT cidl, LPCITEMIDLIST * apidl) PURE;
|
||||
+ STDMETHOD(DeleteItems)(THIS_ UINT cidl, LPCITEMIDLIST *apidl, BOOL confirm) PURE;
|
||||
STDMETHOD(CopyItems)(THIS_ IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl) PURE;
|
||||
};
|
||||
#undef INTERFACE
|
||||
@@ -61,7 +61,7 @@ DECLARE_INTERFACE_(ISFHelper,IUnknown)
|
||||
/*** ISFHelper methods ***/
|
||||
#define ISFHelper_GetUniqueName(p,a,b) (p)->lpVtbl->GetUniqueName(p,a,b)
|
||||
#define ISFHelper_AddFolder(p,a,b,c) (p)->lpVtbl->AddFolder(p,a,b,c)
|
||||
-#define ISFHelper_DeleteItems(p,a,b) (p)->lpVtbl->DeleteItems(p,a,b)
|
||||
+#define ISFHelper_DeleteItems(p,a,b,c) (p)->lpVtbl->DeleteItems(p,a,b,c)
|
||||
#define ISFHelper_CopyItems(p,a,b,c) (p)->lpVtbl->CopyItems(p,a,b,c)
|
||||
#endif
|
||||
|
||||
diff --git a/dlls/shell32/shfldr_fs.c b/dlls/shell32/shfldr_fs.c
|
||||
index d8bcb4c..3d88fbd 100644
|
||||
--- a/dlls/shell32/shfldr_fs.c
|
||||
+++ b/dlls/shell32/shfldr_fs.c
|
||||
@@ -1230,7 +1230,7 @@ static WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, const LPCITEMIDLIS
|
||||
* deletes items in folder
|
||||
*/
|
||||
static HRESULT WINAPI
|
||||
-ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
|
||||
+ISFHelper_fnDeleteItems (ISFHelper *iface, UINT cidl, LPCITEMIDLIST *apidl, BOOL confirm)
|
||||
{
|
||||
IGenericSFImpl *This = impl_from_ISFHelper(iface);
|
||||
UINT i;
|
||||
@@ -1255,6 +1255,7 @@ ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
|
||||
op.wFunc = FO_DELETE;
|
||||
op.pFrom = wszPathsList;
|
||||
op.fFlags = FOF_ALLOWUNDO;
|
||||
+ if (!confirm) op.fFlags |= FOF_NOCONFIRMATION;
|
||||
if (SHFileOperationW(&op))
|
||||
{
|
||||
WARN("SHFileOperation failed\n");
|
||||
diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
|
||||
index 17998f2..d558efb 100644
|
||||
--- a/dlls/shell32/shfldr_unixfs.c
|
||||
+++ b/dlls/shell32/shfldr_unixfs.c
|
||||
@@ -1939,7 +1939,7 @@ static HRESULT WINAPI SFHelper_AddFolder(ISFHelper* iface, HWND hwnd, LPCWSTR pw
|
||||
* be converted, S_FALSE is returned. In such situation DeleteItems will try to delete
|
||||
* the files using syscalls
|
||||
*/
|
||||
-static HRESULT UNIXFS_delete_with_shfileop(UnixFolder *This, UINT cidl, const LPCITEMIDLIST *apidl)
|
||||
+static HRESULT UNIXFS_delete_with_shfileop(UnixFolder *This, UINT cidl, const LPCITEMIDLIST *apidl, BOOL confirm)
|
||||
{
|
||||
char szAbsolute[FILENAME_MAX], *pszRelative;
|
||||
LPWSTR wszPathsList, wszListPos;
|
||||
@@ -1981,6 +1981,7 @@ static HRESULT UNIXFS_delete_with_shfileop(UnixFolder *This, UINT cidl, const LP
|
||||
op.wFunc = FO_DELETE;
|
||||
op.pFrom = wszPathsList;
|
||||
op.fFlags = FOF_ALLOWUNDO;
|
||||
+ if (!confirm) op.fFlags |= FOF_NOCONFIRMATION;
|
||||
if (SHFileOperationW(&op))
|
||||
{
|
||||
WARN("SHFileOperationW failed\n");
|
||||
@@ -2019,7 +2020,7 @@ static HRESULT UNIXFS_delete_with_syscalls(UnixFolder *This, UINT cidl, const LP
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
-static HRESULT WINAPI SFHelper_DeleteItems(ISFHelper* iface, UINT cidl, LPCITEMIDLIST* apidl)
|
||||
+static HRESULT WINAPI SFHelper_DeleteItems(ISFHelper *iface, UINT cidl, LPCITEMIDLIST *apidl, BOOL confirm)
|
||||
{
|
||||
UnixFolder *This = impl_from_ISFHelper(iface);
|
||||
char szAbsolute[FILENAME_MAX], *pszRelative;
|
||||
@@ -2030,7 +2031,7 @@ static HRESULT WINAPI SFHelper_DeleteItems(ISFHelper* iface, UINT cidl, LPCITEMI
|
||||
|
||||
TRACE("(%p)->(%d %p)\n", This, cidl, apidl);
|
||||
|
||||
- hr = UNIXFS_delete_with_shfileop(This, cidl, apidl);
|
||||
+ hr = UNIXFS_delete_with_shfileop(This, cidl, apidl, confirm);
|
||||
if (hr == S_FALSE)
|
||||
hr = UNIXFS_delete_with_syscalls(This, cidl, apidl);
|
||||
|
||||
diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
|
||||
index b763468..1770e6f 100644
|
||||
--- a/dlls/shell32/shlview.c
|
||||
+++ b/dlls/shell32/shlview.c
|
||||
@@ -1579,7 +1579,7 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn
|
||||
}
|
||||
|
||||
/* perform the item deletion */
|
||||
- ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
|
||||
+ ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST *)pItems, TRUE);
|
||||
ISFHelper_Release(psfhlp);
|
||||
|
||||
/* free pidl array memory */
|
||||
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
|
||||
index d972922..494d95b 100644
|
||||
--- a/dlls/shell32/shlview_cmenu.c
|
||||
+++ b/dlls/shell32/shlview_cmenu.c
|
||||
@@ -275,7 +275,7 @@ static void DoDelete(ContextMenu *This)
|
||||
IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&helper);
|
||||
if (helper)
|
||||
{
|
||||
- ISFHelper_DeleteItems(helper, This->cidl, (LPCITEMIDLIST*)This->apidl);
|
||||
+ ISFHelper_DeleteItems(helper, This->cidl, (LPCITEMIDLIST *)This->apidl, TRUE);
|
||||
ISFHelper_Release(helper);
|
||||
}
|
||||
}
|
||||
--
|
||||
2.7.1
|
||||
|
@ -0,0 +1,113 @@
|
||||
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
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 47c24300c6530de5dfe32f352ef839e62ebbd520 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:41:56 +0200
|
||||
Subject: shell32: Recognize cut/copy/paste string verbs in item menu context
|
||||
menu.
|
||||
|
||||
---
|
||||
dlls/shell32/shlview_cmenu.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
|
||||
index c32a4e8..cfe88d5 100644
|
||||
--- a/dlls/shell32/shlview_cmenu.c
|
||||
+++ b/dlls/shell32/shlview_cmenu.c
|
||||
@@ -554,6 +554,12 @@ static HRESULT WINAPI ItemMenu_InvokeCommand(
|
||||
DoDelete(This);
|
||||
else if (strcmp(lpcmi->lpVerb,"properties")==0)
|
||||
DoOpenProperties(This, lpcmi->hwnd);
|
||||
+ else if (strcmp(lpcmi->lpVerb,"cut")==0)
|
||||
+ DoCopyOrCut(This, lpcmi->hwnd, TRUE);
|
||||
+ else if (strcmp(lpcmi->lpVerb,"copy")==0)
|
||||
+ DoCopyOrCut(This, lpcmi->hwnd, FALSE);
|
||||
+ else if (strcmp(lpcmi->lpVerb,"paste")==0)
|
||||
+ DoPaste(This);
|
||||
else {
|
||||
FIXME("Unhandled string verb %s\n",debugstr_a(lpcmi->lpVerb));
|
||||
return E_FAIL;
|
||||
--
|
||||
2.7.1
|
||||
|
3
patches/shell32-Context_Menu/definition
Normal file
3
patches/shell32-Context_Menu/definition
Normal file
@ -0,0 +1,3 @@
|
||||
Fixes: [34319] Add support for Paste in context menu
|
||||
Fixes: [34322] Fix implementation of Cut file operation
|
||||
Fixes: [34321] Fix Cut/Copy/Paste keyboard shortcuts in Total Commander
|
Loading…
Reference in New Issue
Block a user