https://git.reactos.org/?p=reactos.git;a=commitdiff;h=85fdcdf2ccd6b569eeaa8…
commit 85fdcdf2ccd6b569eeaa8e771a98ab47a6de687c
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Aug 16 08:04:07 2020 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Aug 16 08:04:07 2020 +0900
[SHELL32] Implement Copy To Folder (retrial) (#3044)
- Add context menu item "Copy to &folder..." and implement the action.
- Implement the "Copy to &folder..." menu item of "Edit" menu
of Explorer.
CORE-11132
---
dll/win32/shell32/CCopyToMenu.cpp | 374 ++++++++++++++++++++++++++++++
dll/win32/shell32/CCopyToMenu.h | 58 +++++
dll/win32/shell32/CDefView.cpp | 21 ++
dll/win32/shell32/CDefaultContextMenu.cpp | 35 ++-
dll/win32/shell32/CMakeLists.txt | 1 +
dll/win32/shell32/lang/bg-BG.rc | 4 +
dll/win32/shell32/lang/ca-ES.rc | 4 +
dll/win32/shell32/lang/cs-CZ.rc | 4 +
dll/win32/shell32/lang/da-DK.rc | 4 +
dll/win32/shell32/lang/de-DE.rc | 4 +
dll/win32/shell32/lang/el-GR.rc | 4 +
dll/win32/shell32/lang/en-GB.rc | 4 +
dll/win32/shell32/lang/en-US.rc | 4 +
dll/win32/shell32/lang/es-ES.rc | 4 +
dll/win32/shell32/lang/et-EE.rc | 4 +
dll/win32/shell32/lang/fi-FI.rc | 4 +
dll/win32/shell32/lang/fr-FR.rc | 4 +
dll/win32/shell32/lang/he-IL.rc | 4 +
dll/win32/shell32/lang/hi-IN.rc | 4 +
dll/win32/shell32/lang/hu-HU.rc | 4 +
dll/win32/shell32/lang/id-ID.rc | 4 +
dll/win32/shell32/lang/it-IT.rc | 4 +
dll/win32/shell32/lang/ja-JP.rc | 4 +
dll/win32/shell32/lang/ko-KR.rc | 4 +
dll/win32/shell32/lang/nl-NL.rc | 4 +
dll/win32/shell32/lang/no-NO.rc | 4 +
dll/win32/shell32/lang/pl-PL.rc | 4 +
dll/win32/shell32/lang/pt-BR.rc | 4 +
dll/win32/shell32/lang/pt-PT.rc | 4 +
dll/win32/shell32/lang/ro-RO.rc | 4 +
dll/win32/shell32/lang/ru-RU.rc | 4 +
dll/win32/shell32/lang/sk-SK.rc | 4 +
dll/win32/shell32/lang/sl-SI.rc | 4 +
dll/win32/shell32/lang/sq-AL.rc | 4 +
dll/win32/shell32/lang/sv-SE.rc | 4 +
dll/win32/shell32/lang/tr-TR.rc | 4 +
dll/win32/shell32/lang/uk-UA.rc | 4 +
dll/win32/shell32/lang/zh-CN.rc | 4 +
dll/win32/shell32/lang/zh-TW.rc | 4 +
dll/win32/shell32/precomp.h | 1 +
dll/win32/shell32/res/rgs/copytomenu.rgs | 26 +++
dll/win32/shell32/rgs_res.rc | 1 +
dll/win32/shell32/shell32.cpp | 1 +
dll/win32/shell32/shresdef.h | 6 +
44 files changed, 659 insertions(+), 1 deletion(-)
diff --git a/dll/win32/shell32/CCopyToMenu.cpp b/dll/win32/shell32/CCopyToMenu.cpp
new file mode 100644
index 00000000000..bc1325bb86d
--- /dev/null
+++ b/dll/win32/shell32/CCopyToMenu.cpp
@@ -0,0 +1,374 @@
+/*
+ * PROJECT: shell32
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: CopyTo implementation
+ * COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
+ */
+
+#include "precomp.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+static HRESULT
+_GetCidlFromDataObject(IDataObject *pDataObject, CIDA** ppcida)
+{
+ static CLIPFORMAT s_cfHIDA = 0;
+ if (s_cfHIDA == 0)
+ {
+ s_cfHIDA =
static_cast<CLIPFORMAT>(RegisterClipboardFormatW(CFSTR_SHELLIDLIST));
+ }
+
+ FORMATETC fmt = { s_cfHIDA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
+ STGMEDIUM medium;
+
+ HRESULT hr = pDataObject->GetData(&fmt, &medium);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ LPVOID lpSrc = GlobalLock(medium.hGlobal);
+ SIZE_T cbSize = GlobalSize(medium.hGlobal);
+
+ *ppcida = reinterpret_cast<CIDA *>(::CoTaskMemAlloc(cbSize));
+ if (*ppcida)
+ {
+ memcpy(*ppcida, lpSrc, cbSize);
+ hr = S_OK;
+ }
+ else
+ {
+ ERR("Out of memory\n");
+ hr = E_FAIL;
+ }
+ ReleaseStgMedium(&medium);
+ return hr;
+}
+
+CCopyToMenu::CCopyToMenu() :
+ m_idCmdFirst(0),
+ m_idCmdLast(0),
+ m_idCmdCopyTo(-1)
+{
+}
+
+CCopyToMenu::~CCopyToMenu()
+{
+}
+
+#define WM_ENABLEOK (WM_USER + 0x2000)
+
+static LRESULT CALLBACK
+WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CCopyToMenu *this_ =
+ reinterpret_cast<CCopyToMenu *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
+
+ switch (uMsg)
+ {
+ case WM_ENABLEOK:
+ SendMessageW(hwnd, BFFM_ENABLEOK, 0, (BOOL)lParam);
+ return 0;
+ }
+ return CallWindowProcW(this_->m_fnOldWndProc, hwnd, uMsg, wParam, lParam);
+}
+
+static int CALLBACK
+BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+{
+ CCopyToMenu *this_ =
+ reinterpret_cast<CCopyToMenu *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
+
+ switch (uMsg)
+ {
+ case BFFM_INITIALIZED:
+ {
+ SetWindowLongPtr(hwnd, GWLP_USERDATA, lpData);
+ this_ = reinterpret_cast<CCopyToMenu *>(lpData);
+
+ // Select initial directory
+ SendMessageW(hwnd, BFFM_SETSELECTION, FALSE,
+
reinterpret_cast<LPARAM>(static_cast<LPCITEMIDLIST>(this_->m_pidlFolder)));
+
+ // Set caption
+ CString strCaption(MAKEINTRESOURCEW(IDS_COPYITEMS));
+ SetWindowTextW(hwnd, strCaption);
+
+ // Set OK button text
+ CString strCopy(MAKEINTRESOURCEW(IDS_COPYBUTTON));
+ SetDlgItemText(hwnd, IDOK, strCopy);
+
+ // Subclassing
+ this_->m_fnOldWndProc =
+ reinterpret_cast<WNDPROC>(
+ SetWindowLongPtr(hwnd, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(WindowProc)));
+
+ // Disable OK
+ PostMessageW(hwnd, WM_ENABLEOK, 0, FALSE);
+ break;
+ }
+ case BFFM_SELCHANGED:
+ {
+ WCHAR szPath[MAX_PATH];
+ LPCITEMIDLIST pidl = reinterpret_cast<LPCITEMIDLIST>(lParam);
+
+ szPath[0] = 0;
+ SHGetPathFromIDListW(pidl, szPath);
+
+ if (ILIsEqual(pidl, this_->m_pidlFolder))
+ PostMessageW(hwnd, WM_ENABLEOK, 0, FALSE);
+ else if (PathFileExistsW(szPath) || _ILIsDesktop(pidl))
+ PostMessageW(hwnd, WM_ENABLEOK, 0, TRUE);
+ else
+ PostMessageW(hwnd, WM_ENABLEOK, 0, FALSE);
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+HRESULT CCopyToMenu::DoRealCopy(LPCMINVOKECOMMANDINFO lpici, LPCITEMIDLIST pidl)
+{
+ CComHeapPtr<CIDA> pCIDA;
+ HRESULT hr = _GetCidlFromDataObject(m_pDataObject, &pCIDA);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(pCIDA);
+ if (!pidlParent)
+ {
+ ERR("HIDA_GetPIDLFolder failed\n");
+ return E_FAIL;
+ }
+
+ CStringW strFiles;
+ WCHAR szPath[MAX_PATH];
+ for (UINT n = 0; n < pCIDA->cidl; ++n)
+ {
+ PCUIDLIST_RELATIVE pidlRelative = HIDA_GetPIDLItem(pCIDA, n);
+ if (!pidlRelative)
+ continue;
+
+ CComHeapPtr<ITEMIDLIST> pidlCombine(ILCombine(pidlParent, pidlRelative));
+ if (!pidl)
+ return E_FAIL;
+
+ SHGetPathFromIDListW(pidlCombine, szPath);
+
+ if (n > 0)
+ strFiles += L'|';
+ strFiles += szPath;
+ }
+
+ strFiles += L'|'; // double null-terminated
+ strFiles.Replace(L'|', L'\0');
+
+ if (_ILIsDesktop(pidl))
+ SHGetSpecialFolderPathW(NULL, szPath, CSIDL_DESKTOPDIRECTORY, FALSE);
+ else
+ SHGetPathFromIDListW(pidl, szPath);
+ INT cchPath = lstrlenW(szPath);
+ if (cchPath + 1 < MAX_PATH)
+ {
+ szPath[cchPath + 1] = 0; // double null-terminated
+ }
+ else
+ {
+ ERR("Too long path\n");
+ return E_FAIL;
+ }
+
+ SHFILEOPSTRUCTW op = { lpici->hwnd };
+ op.wFunc = FO_COPY;
+ op.pFrom = strFiles;
+ op.pTo = szPath;
+ op.fFlags = FOF_ALLOWUNDO;
+ return ((SHFileOperation(&op) == 0) ? S_OK : E_FAIL);
+}
+
+CStringW CCopyToMenu::DoGetFileTitle()
+{
+ CStringW ret = L"(file)";
+
+ CComHeapPtr<CIDA> pCIDA;
+ HRESULT hr = _GetCidlFromDataObject(m_pDataObject, &pCIDA);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return ret;
+
+ PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(pCIDA);
+ if (!pidlParent)
+ {
+ ERR("HIDA_GetPIDLFolder failed\n");
+ return ret;
+ }
+
+ WCHAR szPath[MAX_PATH];
+ PCUIDLIST_RELATIVE pidlRelative = HIDA_GetPIDLItem(pCIDA, 0);
+ if (!pidlRelative)
+ {
+ ERR("HIDA_GetPIDLItem failed\n");
+ return ret;
+ }
+
+ CComHeapPtr<ITEMIDLIST> pidlCombine(ILCombine(pidlParent, pidlRelative));
+
+ if (SHGetPathFromIDListW(pidlCombine, szPath))
+ ret = PathFindFileNameW(szPath);
+ else
+ ERR("Cannot get path\n");
+
+ if (pCIDA->cidl > 1)
+ ret += L" ...";
+
+ return ret;
+}
+
+HRESULT CCopyToMenu::DoCopyToFolder(LPCMINVOKECOMMANDINFO lpici)
+{
+ WCHAR wszPath[MAX_PATH];
+ HRESULT hr = E_FAIL;
+
+ TRACE("DoCopyToFolder(%p)\n", lpici);
+
+ if (!SHGetPathFromIDListW(m_pidlFolder, wszPath))
+ {
+ ERR("SHGetPathFromIDListW failed\n");
+ return hr;
+ }
+
+ CStringW strFileTitle = DoGetFileTitle();
+ CStringW strTitle;
+ strTitle.Format(IDS_COPYTOTITLE, static_cast<LPCWSTR>(strFileTitle));
+
+ BROWSEINFOW info = { lpici->hwnd };
+ info.pidlRoot = NULL;
+ info.lpszTitle = strTitle;
+ info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
+ info.lpfn = BrowseCallbackProc;
+ info.lParam = reinterpret_cast<LPARAM>(this);
+ CComHeapPtr<ITEMIDLIST> pidl(SHBrowseForFolder(&info));
+ if (pidl)
+ {
+ hr = DoRealCopy(lpici, pidl);
+ }
+
+ return hr;
+}
+
+HRESULT WINAPI
+CCopyToMenu::QueryContextMenu(HMENU hMenu,
+ UINT indexMenu,
+ UINT idCmdFirst,
+ UINT idCmdLast,
+ UINT uFlags)
+{
+ MENUITEMINFOW mii;
+ UINT Count = 0;
+
+ TRACE("CCopyToMenu::QueryContextMenu(%p, %u, %u, %u, %u)\n",
+ hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
+
+ m_idCmdFirst = m_idCmdLast = idCmdFirst;
+
+ // insert separator if necessary
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE;
+ if (GetMenuItemInfoW(hMenu, indexMenu - 1, TRUE, &mii) &&
+ mii.fType != MFT_SEPARATOR)
+ {
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE;
+ mii.fType = MFT_SEPARATOR;
+ if (InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
+ {
+ ++indexMenu;
+ ++Count;
+ }
+ }
+
+ // insert "Copy to folder..."
+ CStringW strText(MAKEINTRESOURCEW(IDS_COPYTOMENU));
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID | MIIM_TYPE;
+ mii.fType = MFT_STRING;
+ mii.dwTypeData = strText.GetBuffer();
+ mii.cch = wcslen(mii.dwTypeData);
+ mii.wID = m_idCmdLast;
+ if (InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
+ {
+ m_idCmdCopyTo = m_idCmdLast++;
+ ++indexMenu;
+ ++Count;
+ }
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, Count);
+}
+
+HRESULT WINAPI
+CCopyToMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
+{
+ HRESULT hr = E_FAIL;
+ TRACE("CCopyToMenu::InvokeCommand(%p)\n", lpici);
+
+ if (HIWORD(lpici->lpVerb) == 0)
+ {
+ if (m_idCmdFirst + LOWORD(lpici->lpVerb) == m_idCmdCopyTo)
+ {
+ hr = DoCopyToFolder(lpici);
+ }
+ }
+ else
+ {
+ if (::lstrcmpiA(lpici->lpVerb, "copyto") == 0)
+ {
+ hr = DoCopyToFolder(lpici);
+ }
+ }
+
+ return hr;
+}
+
+HRESULT WINAPI
+CCopyToMenu::GetCommandString(UINT_PTR idCmd,
+ UINT uType,
+ UINT *pwReserved,
+ LPSTR pszName,
+ UINT cchMax)
+{
+ FIXME("%p %lu %u %p %p %u\n", this,
+ idCmd, uType, pwReserved, pszName, cchMax);
+
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI
+CCopyToMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ TRACE("This %p uMsg %x\n", this, uMsg);
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI
+CCopyToMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder,
+ IDataObject *pdtobj, HKEY hkeyProgID)
+{
+ m_pidlFolder.Attach(ILClone(pidlFolder));
+ m_pDataObject = pdtobj;
+ return S_OK;
+}
+
+HRESULT WINAPI CCopyToMenu::SetSite(IUnknown *pUnkSite)
+{
+ m_pSite = pUnkSite;
+ return S_OK;
+}
+
+HRESULT WINAPI CCopyToMenu::GetSite(REFIID riid, void **ppvSite)
+{
+ if (!m_pSite)
+ return E_FAIL;
+
+ return m_pSite->QueryInterface(riid, ppvSite);
+}
diff --git a/dll/win32/shell32/CCopyToMenu.h b/dll/win32/shell32/CCopyToMenu.h
new file mode 100644
index 00000000000..a56cba111de
--- /dev/null
+++ b/dll/win32/shell32/CCopyToMenu.h
@@ -0,0 +1,58 @@
+/*
+ * PROJECT: shell32
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: CopyTo implementation
+ * COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
+ */
+#pragma once
+
+class CCopyToMenu :
+ public CComCoClass<CCopyToMenu, &CLSID_CopyToMenu>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IContextMenu2,
+ public IObjectWithSite,
+ public IShellExtInit
+{
+protected:
+ UINT m_idCmdFirst, m_idCmdLast, m_idCmdCopyTo;
+ CComPtr<IDataObject> m_pDataObject;
+ CComPtr<IUnknown> m_pSite;
+
+ HRESULT DoCopyToFolder(LPCMINVOKECOMMANDINFO lpici);
+ HRESULT DoRealCopy(LPCMINVOKECOMMANDINFO lpici, PCUIDLIST_ABSOLUTE pidl);
+ CStringW DoGetFileTitle();
+
+public:
+ CComHeapPtr<ITEMIDLIST> m_pidlFolder;
+ WNDPROC m_fnOldWndProc;
+
+ CCopyToMenu();
+ ~CCopyToMenu();
+
+ // IContextMenu
+ virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags);
+ virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
+ virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT
*lpReserved, LPSTR lpszName, UINT uMaxNameLen);
+
+ // IContextMenu2
+ virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ // IShellExtInit
+ virtual HRESULT WINAPI Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj,
HKEY hkeyProgID);
+
+ // IObjectWithSite
+ virtual HRESULT WINAPI SetSite(IUnknown *pUnkSite);
+ virtual HRESULT WINAPI GetSite(REFIID riid, void **ppvSite);
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_COPYTOMENU)
+ DECLARE_NOT_AGGREGATABLE(CCopyToMenu)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CCopyToMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
+ COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
+ END_COM_MAP()
+};
diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp
index cb5dd140eb1..a42d4d495cb 100644
--- a/dll/win32/shell32/CDefView.cpp
+++ b/dll/win32/shell32/CDefView.cpp
@@ -1822,6 +1822,7 @@ LRESULT CDefView::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL &bHand
case FCIDM_SHVIEW_COPY:
case FCIDM_SHVIEW_RENAME:
case FCIDM_SHVIEW_PROPERTIES:
+ case FCIDM_SHVIEW_COPYTO:
return OnExplorerCommand(dwCmdID, TRUE);
case FCIDM_SHVIEW_INSERT:
@@ -2295,6 +2296,26 @@ LRESULT CDefView::OnInitMenuPopup(UINT uMsg, WPARAM wParam, LPARAM
lParam, BOOL
HMENU hViewMenu = GetSubmenuByID(m_hMenu, FCIDM_MENU_VIEW);
+ if (GetSelections() == 0)
+ {
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_CUT, MF_GRAYED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_COPY, MF_GRAYED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME, MF_GRAYED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_COPYTO, MF_GRAYED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_MOVETO, MF_GRAYED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_DELETE, MF_GRAYED);
+ }
+ else
+ {
+ // FIXME: Check copyable
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_CUT, MF_ENABLED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_COPY, MF_ENABLED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME, MF_ENABLED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_COPYTO, MF_ENABLED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_MOVETO, MF_ENABLED);
+ ::EnableMenuItem(hmenu, FCIDM_SHVIEW_DELETE, MF_ENABLED);
+ }
+
/* Lets try to find out what the hell wParam is */
if (hmenu == GetSubMenu(m_hMenu, nPos))
menuItemId = ReallyGetMenuItemID(m_hMenu, nPos);
diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp
b/dll/win32/shell32/CDefaultContextMenu.cpp
index d36d042c70c..a717078f70b 100644
--- a/dll/win32/shell32/CDefaultContextMenu.cpp
+++ b/dll/win32/shell32/CDefaultContextMenu.cpp
@@ -48,9 +48,9 @@ struct _StaticInvokeCommandMap_
{ "delete", FCIDM_SHVIEW_DELETE},
{ "properties", FCIDM_SHVIEW_PROPERTIES},
{ "rename", FCIDM_SHVIEW_RENAME},
+ { "copyto", FCIDM_SHVIEW_COPYTO },
};
-
class CDefaultContextMenu :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IContextMenu3,
@@ -95,6 +95,7 @@ class CDefaultContextMenu :
HRESULT DoRename(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoProperties(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFO lpici);
+ HRESULT DoCopyToFolder(LPCMINVOKECOMMANDINFO lpici);
HRESULT InvokeShellExt(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT InvokeRegVerb(LPCMINVOKECOMMANDINFO lpcmi);
DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticShellEntry
pEntry);
@@ -893,6 +894,35 @@ CDefaultContextMenu::DoProperties(
return S_OK;
}
+HRESULT
+CDefaultContextMenu::DoCopyToFolder(LPCMINVOKECOMMANDINFO lpici)
+{
+ HRESULT hr = E_FAIL;
+ if (!m_pDataObj)
+ {
+ ERR("m_pDataObj is NULL\n");
+ return hr;
+ }
+
+ CComPtr<IContextMenu> pContextMenu;
+ hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL, IID_PPV_ARG(IContextMenu,
&pContextMenu));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ CComPtr<IShellExtInit> pInit;
+ hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ lpici->lpVerb = "copyto";
+
+ return pContextMenu->InvokeCommand(lpici);
+}
+
// This code is taken from CNewMenu and should be shared between the 2 classes
HRESULT
CDefaultContextMenu::DoCreateNewFolder(
@@ -1248,6 +1278,9 @@ CDefaultContextMenu::InvokeCommand(
case FCIDM_SHVIEW_NEWFOLDER:
Result = DoCreateNewFolder(&LocalInvokeInfo);
break;
+ case FCIDM_SHVIEW_COPYTO:
+ Result = DoCopyToFolder(&LocalInvokeInfo);
+ break;
default:
Result = E_INVALIDARG;
ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
diff --git a/dll/win32/shell32/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt
index e0a84c9fe8e..aa51a47fe43 100644
--- a/dll/win32/shell32/CMakeLists.txt
+++ b/dll/win32/shell32/CMakeLists.txt
@@ -83,6 +83,7 @@ list(APPEND SOURCE
COpenWithMenu.cpp
CNewMenu.cpp
CSendToMenu.cpp
+ CCopyToMenu.cpp
CShellDispatch.cpp
CFolder.cpp
CFolderItems.cpp
diff --git a/dll/win32/shell32/lang/bg-BG.rc b/dll/win32/shell32/lang/bg-BG.rc
index 9c1a859495c..56ca1049511 100644
--- a/dll/win32/shell32/lang/bg-BG.rc
+++ b/dll/win32/shell32/lang/bg-BG.rc
@@ -999,4 +999,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/ca-ES.rc b/dll/win32/shell32/lang/ca-ES.rc
index 13595784d31..8e920649408 100644
--- a/dll/win32/shell32/lang/ca-ES.rc
+++ b/dll/win32/shell32/lang/ca-ES.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/cs-CZ.rc b/dll/win32/shell32/lang/cs-CZ.rc
index 5e41d728b22..4c86a7c5869 100644
--- a/dll/win32/shell32/lang/cs-CZ.rc
+++ b/dll/win32/shell32/lang/cs-CZ.rc
@@ -1004,4 +1004,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/da-DK.rc b/dll/win32/shell32/lang/da-DK.rc
index 48abdf760b3..6bf29e180b5 100644
--- a/dll/win32/shell32/lang/da-DK.rc
+++ b/dll/win32/shell32/lang/da-DK.rc
@@ -1004,4 +1004,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/de-DE.rc b/dll/win32/shell32/lang/de-DE.rc
index 0fdce04259d..cc4b49246a7 100644
--- a/dll/win32/shell32/lang/de-DE.rc
+++ b/dll/win32/shell32/lang/de-DE.rc
@@ -999,4 +999,8 @@ BEGIN
IDS_NO_ICONS "Die Datei '%s' enthält keine Symbole.\n\nWählen Sie ein
Symbol aus der Liste oder wählen Sie eine andere Datei."
IDS_FILE_NOT_FOUND "Die Datei '%s' wurde nicht gefunden."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/el-GR.rc b/dll/win32/shell32/lang/el-GR.rc
index cc9c8c15ba4..fd2bb3cfc42 100644
--- a/dll/win32/shell32/lang/el-GR.rc
+++ b/dll/win32/shell32/lang/el-GR.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/en-GB.rc b/dll/win32/shell32/lang/en-GB.rc
index 2fa65e383ed..4d1f9e55495 100644
--- a/dll/win32/shell32/lang/en-GB.rc
+++ b/dll/win32/shell32/lang/en-GB.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/en-US.rc b/dll/win32/shell32/lang/en-US.rc
index 0af80340d2c..21f06a42d42 100644
--- a/dll/win32/shell32/lang/en-US.rc
+++ b/dll/win32/shell32/lang/en-US.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/es-ES.rc b/dll/win32/shell32/lang/es-ES.rc
index 8b2afe4f73c..bdf04fd74a4 100644
--- a/dll/win32/shell32/lang/es-ES.rc
+++ b/dll/win32/shell32/lang/es-ES.rc
@@ -1007,4 +1007,8 @@ BEGIN
IDS_NO_ICONS "El archivo '%s' no contiene íconos.\n\nEscoja un ícono de
la lista o seleccione otro archivo."
IDS_FILE_NOT_FOUND "El archivo '%s' no pudo ser encontrado."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/et-EE.rc b/dll/win32/shell32/lang/et-EE.rc
index 9f9703ca32a..8585ad68b08 100644
--- a/dll/win32/shell32/lang/et-EE.rc
+++ b/dll/win32/shell32/lang/et-EE.rc
@@ -1005,4 +1005,8 @@ BEGIN
IDS_NO_ICONS "Fail '%s' ei sisalda ühtegi ikooni.\n\nVali ikoon
nimekirjast või määra teine fail."
IDS_FILE_NOT_FOUND "Faili '%s' ei leitud."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/fi-FI.rc b/dll/win32/shell32/lang/fi-FI.rc
index 9b112922152..80356afb3d5 100644
--- a/dll/win32/shell32/lang/fi-FI.rc
+++ b/dll/win32/shell32/lang/fi-FI.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/fr-FR.rc b/dll/win32/shell32/lang/fr-FR.rc
index fc780633ed9..019fed4cc69 100644
--- a/dll/win32/shell32/lang/fr-FR.rc
+++ b/dll/win32/shell32/lang/fr-FR.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "Le fichier '%s' ne contient pas d'icônes.\n\nVeuillez
choisir une icône dans la liste ou sélectionner un fichier différent."
IDS_FILE_NOT_FOUND "Le fichier '%s' ne peut être trouvé."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/he-IL.rc b/dll/win32/shell32/lang/he-IL.rc
index 51e94334e7f..8d469bf407e 100644
--- a/dll/win32/shell32/lang/he-IL.rc
+++ b/dll/win32/shell32/lang/he-IL.rc
@@ -1000,4 +1000,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "לא ניתן למצוא את הקובץ '%s'."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/hi-IN.rc b/dll/win32/shell32/lang/hi-IN.rc
index 101d5b5c136..59be1fd3cbf 100644
--- a/dll/win32/shell32/lang/hi-IN.rc
+++ b/dll/win32/shell32/lang/hi-IN.rc
@@ -993,4 +993,8 @@ BEGIN
IDS_NO_ICONS "फ़ाइल '%s' में कोई आइकन नहीं है।\n\nसूची से एक आइकन चुनें
या एक अलग फ़ाइल निर्दिष्ट करें।"
IDS_FILE_NOT_FOUND "फ़ाइल '%s' नहीं मिली।"
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/hu-HU.rc b/dll/win32/shell32/lang/hu-HU.rc
index 1b3a743f11e..90f964dbd7c 100644
--- a/dll/win32/shell32/lang/hu-HU.rc
+++ b/dll/win32/shell32/lang/hu-HU.rc
@@ -997,4 +997,8 @@ BEGIN
IDS_NO_ICONS "A fájl ('%s') nem tartalmaz ikonokat.\n\nVálasszon egy
ikont a listából, vagy adjon meg egy másik fájlt."
IDS_FILE_NOT_FOUND "A fájl ('%s') nem található."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/id-ID.rc b/dll/win32/shell32/lang/id-ID.rc
index 90c22133c2b..09571a9f2a6 100644
--- a/dll/win32/shell32/lang/id-ID.rc
+++ b/dll/win32/shell32/lang/id-ID.rc
@@ -994,4 +994,8 @@ BEGIN
IDS_NO_ICONS "Berkas '%s' tidak berisi ikon.\n\nPilih ikon dari daftar
atau pilih berkas yang berbeda."
IDS_FILE_NOT_FOUND "Berkas '%s' tidak ditemukan."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/it-IT.rc b/dll/win32/shell32/lang/it-IT.rc
index b1bf68e20d7..ed3dac4bfc8 100644
--- a/dll/win32/shell32/lang/it-IT.rc
+++ b/dll/win32/shell32/lang/it-IT.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/ja-JP.rc b/dll/win32/shell32/lang/ja-JP.rc
index d385640dfdd..3593c981ce7 100644
--- a/dll/win32/shell32/lang/ja-JP.rc
+++ b/dll/win32/shell32/lang/ja-JP.rc
@@ -995,4 +995,8 @@ BEGIN
IDS_NO_ICONS "ファイル '%s' にはアイコン
データがありません。.\n\nリストからアイコンを選ぶか、別のファイルを指定して下さい。"
IDS_FILE_NOT_FOUND "ファイル '%s' は見つかりませんでした。"
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/ko-KR.rc b/dll/win32/shell32/lang/ko-KR.rc
index 6fed522e97d..3c46406aab7 100644
--- a/dll/win32/shell32/lang/ko-KR.rc
+++ b/dll/win32/shell32/lang/ko-KR.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/nl-NL.rc b/dll/win32/shell32/lang/nl-NL.rc
index 14181b2cc6a..26b311387a5 100644
--- a/dll/win32/shell32/lang/nl-NL.rc
+++ b/dll/win32/shell32/lang/nl-NL.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/no-NO.rc b/dll/win32/shell32/lang/no-NO.rc
index 502648fef4e..1831921be23 100644
--- a/dll/win32/shell32/lang/no-NO.rc
+++ b/dll/win32/shell32/lang/no-NO.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/pl-PL.rc b/dll/win32/shell32/lang/pl-PL.rc
index 1b5de4427d8..b125105cb29 100644
--- a/dll/win32/shell32/lang/pl-PL.rc
+++ b/dll/win32/shell32/lang/pl-PL.rc
@@ -1004,4 +1004,8 @@ BEGIN
IDS_NO_ICONS "Plik '%s' nie zawiera ikon.\n\nWybierz ikonę z listy lub
określ inny plik."
IDS_FILE_NOT_FOUND "Nie odnaleziono pliku '%s'."
IDS_LINK_INVALID "Element '%s', do którego odwołuje się ten skrót,
został zmieniony lub przeniesiony i dlatego skrót ten nie będzie działał poprawnie."
+ IDS_COPYTOMENU "Copy To &Folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/pt-BR.rc b/dll/win32/shell32/lang/pt-BR.rc
index 0bca68bc3f4..9610e4e0fb6 100644
--- a/dll/win32/shell32/lang/pt-BR.rc
+++ b/dll/win32/shell32/lang/pt-BR.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/pt-PT.rc b/dll/win32/shell32/lang/pt-PT.rc
index 1325c971be2..f64de677bc9 100644
--- a/dll/win32/shell32/lang/pt-PT.rc
+++ b/dll/win32/shell32/lang/pt-PT.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "O arquivo '%s' não contém ícones.\n\nEscolha um ícone da
lista ou especifique um arquivo diferente."
IDS_FILE_NOT_FOUND "O arquivo '%s' não foi encontrado."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/ro-RO.rc b/dll/win32/shell32/lang/ro-RO.rc
index 1cbf12ba8aa..b4f0e6059aa 100644
--- a/dll/win32/shell32/lang/ro-RO.rc
+++ b/dll/win32/shell32/lang/ro-RO.rc
@@ -1000,4 +1000,8 @@ BEGIN
IDS_NO_ICONS "Fișierul „%s” nu conține pictograme.\n\nAlegeți o pictogramă din
listă sau specificați un alt fișier."
IDS_FILE_NOT_FOUND "Fișierul „%s” nu a fost găsit."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/ru-RU.rc b/dll/win32/shell32/lang/ru-RU.rc
index 52e20a39d8e..a12ecfe9d2b 100644
--- a/dll/win32/shell32/lang/ru-RU.rc
+++ b/dll/win32/shell32/lang/ru-RU.rc
@@ -1005,4 +1005,8 @@ BEGIN
IDS_NO_ICONS "Файл '%s' не содержит значков.\n\nВыберите значок из
списка или укажите другой файл."
IDS_FILE_NOT_FOUND "Файл '%s' не найден."
IDS_LINK_INVALID "Элемент '%s', на который ссылается этот ярлык, был
изменён или перемещён, поэтому ярлык не будет работать правильно."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/sk-SK.rc b/dll/win32/shell32/lang/sk-SK.rc
index 5fb69feaf1e..93e87e85cad 100644
--- a/dll/win32/shell32/lang/sk-SK.rc
+++ b/dll/win32/shell32/lang/sk-SK.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/sl-SI.rc b/dll/win32/shell32/lang/sl-SI.rc
index a8daae20a67..eca49866975 100644
--- a/dll/win32/shell32/lang/sl-SI.rc
+++ b/dll/win32/shell32/lang/sl-SI.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/sq-AL.rc b/dll/win32/shell32/lang/sq-AL.rc
index 36362694a9e..fa69346d878 100644
--- a/dll/win32/shell32/lang/sq-AL.rc
+++ b/dll/win32/shell32/lang/sq-AL.rc
@@ -1002,4 +1002,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/sv-SE.rc b/dll/win32/shell32/lang/sv-SE.rc
index 0eaf3eae9c9..a81f73f5c6a 100644
--- a/dll/win32/shell32/lang/sv-SE.rc
+++ b/dll/win32/shell32/lang/sv-SE.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/tr-TR.rc b/dll/win32/shell32/lang/tr-TR.rc
index c4fda54ac1e..519103301b3 100644
--- a/dll/win32/shell32/lang/tr-TR.rc
+++ b/dll/win32/shell32/lang/tr-TR.rc
@@ -1000,4 +1000,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/uk-UA.rc b/dll/win32/shell32/lang/uk-UA.rc
index 85b0ea6ee96..62d8787ec23 100644
--- a/dll/win32/shell32/lang/uk-UA.rc
+++ b/dll/win32/shell32/lang/uk-UA.rc
@@ -998,4 +998,8 @@ BEGIN
IDS_NO_ICONS "Файл '%s' не містить значків.\n\nВиберіть значок зі списку
або відкрийте інший файл."
IDS_FILE_NOT_FOUND "Файд '%s' не знайдено."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/zh-CN.rc b/dll/win32/shell32/lang/zh-CN.rc
index 70d68078cc4..a07f3cfdaf6 100644
--- a/dll/win32/shell32/lang/zh-CN.rc
+++ b/dll/win32/shell32/lang/zh-CN.rc
@@ -1008,4 +1008,8 @@ BEGIN
IDS_NO_ICONS "文件 '%s' 不包含图标\n\n从列表中选择一个图标或指定其他文件。"
IDS_FILE_NOT_FOUND "无法找到文件 '%s'。"
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/lang/zh-TW.rc b/dll/win32/shell32/lang/zh-TW.rc
index 9f01928299a..c634e81d2f4 100644
--- a/dll/win32/shell32/lang/zh-TW.rc
+++ b/dll/win32/shell32/lang/zh-TW.rc
@@ -1009,4 +1009,8 @@ BEGIN
IDS_NO_ICONS "The file '%s' contains no icons.\n\nChoose an icon from
the list or specify a different file."
IDS_FILE_NOT_FOUND "The file '%s' was not found."
IDS_LINK_INVALID "The item '%s' that this shortcut refers to has been
changed or moved, so this shortcut will no longer work properly."
+ IDS_COPYTOMENU "Copy to &folder..."
+ IDS_COPYTOTITLE "Select the place where you want to copy '%s'. Then
click the Copy button."
+ IDS_COPYITEMS "Copy Items"
+ IDS_COPYBUTTON "Copy"
END
diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h
index da9155f0bff..2703b42e817 100644
--- a/dll/win32/shell32/precomp.h
+++ b/dll/win32/shell32/precomp.h
@@ -81,6 +81,7 @@
#include "COpenWithMenu.h"
#include "CNewMenu.h"
#include "CSendToMenu.h"
+#include "CCopyToMenu.h"
#include "dialogs/filedefext.h"
#include "dialogs/drvdefext.h"
#include "CQueryAssociations.h"
diff --git a/dll/win32/shell32/res/rgs/copytomenu.rgs
b/dll/win32/shell32/res/rgs/copytomenu.rgs
new file mode 100644
index 00000000000..8f2726c811c
--- /dev/null
+++ b/dll/win32/shell32/res/rgs/copytomenu.rgs
@@ -0,0 +1,26 @@
+HKCR
+{
+ NoRemove CLSID
+ {
+ ForceRemove {C2FBB630-2971-11D1-A18C-00C04FD75D13} = s 'ReactOS CopyTo Object
Service'
+ {
+ val flags = d '1'
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ }
+ }
+ NoRemove AllFilesystemObjects
+ {
+ NoRemove shellex
+ {
+ NoRemove ContextMenuHandlers
+ {
+ ForceRemove CopyTo = s '{C2FBB630-2971-11D1-A18C-00C04FD75D13}'
+ {
+ }
+ }
+ }
+ }
+}
diff --git a/dll/win32/shell32/rgs_res.rc b/dll/win32/shell32/rgs_res.rc
index d46053ddd99..9435241aaaa 100644
--- a/dll/win32/shell32/rgs_res.rc
+++ b/dll/win32/shell32/rgs_res.rc
@@ -30,3 +30,4 @@ IDR_USERNOTIFICATION REGISTRY "res/rgs/usernotification.rgs"
IDR_SHELL REGISTRY "res/rgs/shell.rgs"
IDR_ACTIVEDESKTOP REGISTRY "res/rgs/activedesktop.rgs"
IDR_SENDTOMENU REGISTRY "res/rgs/sendtomenu.rgs"
+IDR_COPYTOMENU REGISTRY "res/rgs/copytomenu.rgs"
diff --git a/dll/win32/shell32/shell32.cpp b/dll/win32/shell32/shell32.cpp
index c244477cf6b..527cbd29342 100644
--- a/dll/win32/shell32/shell32.cpp
+++ b/dll/win32/shell32/shell32.cpp
@@ -290,6 +290,7 @@ BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_OpenWithMenu, COpenWithMenu)
OBJECT_ENTRY(CLSID_NewMenu, CNewMenu)
OBJECT_ENTRY(CLSID_SendToMenu, CSendToMenu)
+ OBJECT_ENTRY(CLSID_CopyToMenu, CCopyToMenu)
OBJECT_ENTRY(CLSID_StartMenu, CStartMenuDummy)
OBJECT_ENTRY(CLSID_MenuBandSite, CMenuSite)
OBJECT_ENTRY(CLSID_MenuBand, CMenuBand)
diff --git a/dll/win32/shell32/shresdef.h b/dll/win32/shell32/shresdef.h
index 2152134eefc..81f22f97530 100644
--- a/dll/win32/shell32/shresdef.h
+++ b/dll/win32/shell32/shresdef.h
@@ -297,6 +297,10 @@
#define IDS_NO_ICONS 30529
#define IDS_FILE_NOT_FOUND 30530
#define IDS_LINK_INVALID 30531
+#define IDS_COPYTOMENU 30532
+#define IDS_COPYTOTITLE 30533
+#define IDS_COPYITEMS 30534
+#define IDS_COPYBUTTON 30535
/* Dialogs */
@@ -796,6 +800,7 @@
#define IDM_DELETE (FCIDM_SHVIEW_DELETE - 0x7000)
#define IDM_RENAME (FCIDM_SHVIEW_RENAME - 0x7000)
#define IDM_PROPERTIES (FCIDM_SHVIEW_PROPERTIES - 0x7000)
+#define IDM_COPYTO (FCIDM_SHVIEW_COPYTO - 0x7000)
#define IDM_DRAGFILE 0xce
#define IDM_COPYHERE 0x7
@@ -836,3 +841,4 @@
#define IDR_SHELL 156
#define IDR_ACTIVEDESKTOP 157
#define IDR_SENDTOMENU 158
+#define IDR_COPYTOMENU 159