https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a938d19714f9ab659c8d9…
commit a938d19714f9ab659c8d9c2250f2cafc5db8f637
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Nov 4 21:56:15 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Nov 4 21:56:15 2023 +0900
[SHELL32] Commonize CCopyToMenu and CMoveToMenu (#5873)
Reduce code. And correctly do the filename check.
CORE-18909
---
.../{CMoveToMenu.cpp => CCopyMoveToMenu.cpp} | 187 ++++++----
dll/win32/shell32/CCopyMoveToMenu.h | 111 ++++++
dll/win32/shell32/CCopyToMenu.cpp | 381 ---------------------
dll/win32/shell32/CCopyToMoveToMenu.h | 112 ------
dll/win32/shell32/CMakeLists.txt | 3 +-
dll/win32/shell32/precomp.h | 2 +-
6 files changed, 233 insertions(+), 563 deletions(-)
diff --git a/dll/win32/shell32/CMoveToMenu.cpp b/dll/win32/shell32/CCopyMoveToMenu.cpp
similarity index 66%
rename from dll/win32/shell32/CMoveToMenu.cpp
rename to dll/win32/shell32/CCopyMoveToMenu.cpp
index a2d35f1ade1..859b05eb5b7 100644
--- a/dll/win32/shell32/CMoveToMenu.cpp
+++ b/dll/win32/shell32/CCopyMoveToMenu.cpp
@@ -1,33 +1,29 @@
/*
- * PROJECT: shell32
+ * PROJECT: ReactOS shell32
* LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
- * PURPOSE: MoveTo implementation
- * COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz(a)gmail.com)
+ * PURPOSE: CopyTo and MoveTo implementation
+ * COPYRIGHT: Copyright 2020-2023 Katayama Hirofumi MZ
(katayama.hirofumi.mz(a)gmail.com)
*/
#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-CMoveToMenu::CMoveToMenu() :
+CCopyMoveToMenu::CCopyMoveToMenu() :
m_idCmdFirst(0),
m_idCmdLast(0),
- m_idCmdMoveTo(-1),
+ m_idCmdAction(-1),
m_fnOldWndProc(NULL),
m_bIgnoreTextBoxChange(FALSE)
{
}
-CMoveToMenu::~CMoveToMenu()
-{
-}
-
static LRESULT CALLBACK
WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WCHAR szPath[MAX_PATH];
- CMoveToMenu *this_ =
- reinterpret_cast<CMoveToMenu *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ CCopyMoveToMenu *this_ =
+ reinterpret_cast<CCopyMoveToMenu *>(GetWindowLongPtr(hwnd,
GWLP_USERDATA));
switch (uMsg)
{
@@ -64,30 +60,30 @@ WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return CallWindowProcW(this_->m_fnOldWndProc, hwnd, uMsg, wParam, lParam);
}
-static int CALLBACK
+static INT CALLBACK
BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
- CMoveToMenu *this_ =
- reinterpret_cast<CMoveToMenu *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
+ CCopyMoveToMenu *this_ =
+ reinterpret_cast<CCopyMoveToMenu *>(GetWindowLongPtr(hwnd,
GWLP_USERDATA));
switch (uMsg)
{
case BFFM_INITIALIZED:
{
SetWindowLongPtr(hwnd, GWLP_USERDATA, lpData);
- this_ = reinterpret_cast<CMoveToMenu *>(lpData);
+ this_ = reinterpret_cast<CCopyMoveToMenu *>(lpData);
// Select initial directory
SendMessageW(hwnd, BFFM_SETSELECTION, FALSE,
reinterpret_cast<LPARAM>(static_cast<LPCITEMIDLIST>(this_->m_pidlFolder)));
// Set caption
- CString strCaption(MAKEINTRESOURCEW(IDS_MOVEITEMS));
+ CString strCaption(MAKEINTRESOURCEW(this_->GetCaptionStringID()));
SetWindowTextW(hwnd, strCaption);
// Set OK button text
- CString strMove(MAKEINTRESOURCEW(IDS_MOVEBUTTON));
- SetDlgItemText(hwnd, IDOK, strMove);
+ CString strCopyOrMove(MAKEINTRESOURCEW(this_->GetButtonStringID()));
+ SetDlgItemText(hwnd, IDOK, strCopyOrMove);
// Subclassing
this_->m_fnOldWndProc =
@@ -125,7 +121,8 @@ BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM
lpData)
return FALSE;
}
-HRESULT CMoveToMenu::DoRealMove(LPCMINVOKECOMMANDINFO lpici, LPCITEMIDLIST pidl)
+HRESULT
+CCopyMoveToMenu::DoRealFileOp(LPCMINVOKECOMMANDINFO lpici, LPCITEMIDLIST pidl)
{
CDataObjectHIDA pCIDA(m_pDataObject);
if (FAILED_UNEXPECTEDLY(pCIDA.hr()))
@@ -175,10 +172,7 @@ HRESULT CMoveToMenu::DoRealMove(LPCMINVOKECOMMANDINFO lpici,
LPCITEMIDLIST pidl)
return E_FAIL;
}
- SHFILEOPSTRUCTW op = { lpici->hwnd };
- op.wFunc = FO_MOVE;
- op.pFrom = strFiles;
- op.pTo = szPath;
+ SHFILEOPSTRUCTW op = { lpici->hwnd, GetFileOp(), strFiles, szPath };
op.fFlags = FOF_ALLOWUNDO;
int res = SHFileOperationW(&op);
if (res)
@@ -189,19 +183,18 @@ HRESULT CMoveToMenu::DoRealMove(LPCMINVOKECOMMANDINFO lpici,
LPCITEMIDLIST pidl)
return S_OK;
}
-CStringW CMoveToMenu::DoGetFileTitle()
+static HRESULT
+DoGetFileTitle(CStringW& strTitle, IDataObject *pDataObject)
{
- CStringW ret = L"(file)";
-
- CDataObjectHIDA pCIDA(m_pDataObject);
+ CDataObjectHIDA pCIDA(pDataObject);
if (FAILED_UNEXPECTEDLY(pCIDA.hr()))
- return ret;
+ return E_FAIL;
PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(pCIDA);
if (!pidlParent)
{
ERR("HIDA_GetPIDLFolder failed\n");
- return ret;
+ return E_FAIL;
}
WCHAR szPath[MAX_PATH];
@@ -209,28 +202,33 @@ CStringW CMoveToMenu::DoGetFileTitle()
if (!pidlRelative)
{
ERR("HIDA_GetPIDLItem failed\n");
- return ret;
+ return E_FAIL;
}
CComHeapPtr<ITEMIDLIST> pidlCombine(ILCombine(pidlParent, pidlRelative));
- if (SHGetPathFromIDListW(pidlCombine, szPath))
- ret = PathFindFileNameW(szPath);
- else
+ if (!SHGetPathFromIDListW(pidlCombine, szPath))
+ {
ERR("Cannot get path\n");
+ return E_FAIL;
+ }
+
+ strTitle = PathFindFileNameW(szPath);
+ if (strTitle.IsEmpty())
+ return E_FAIL;
if (pCIDA->cidl > 1)
- ret += L" ...";
+ strTitle += L" ...";
- return ret;
+ return S_OK;
}
-HRESULT CMoveToMenu::DoMoveToFolder(LPCMINVOKECOMMANDINFO lpici)
+HRESULT CCopyMoveToMenu::DoAction(LPCMINVOKECOMMANDINFO lpici)
{
WCHAR wszPath[MAX_PATH];
HRESULT hr = E_FAIL;
- TRACE("DoMoveToFolder(%p)\n", lpici);
+ TRACE("(%p)\n", lpici);
if (!SHGetPathFromIDListW(m_pidlFolder, wszPath))
{
@@ -238,9 +236,13 @@ HRESULT CMoveToMenu::DoMoveToFolder(LPCMINVOKECOMMANDINFO lpici)
return hr;
}
- CStringW strFileTitle = DoGetFileTitle();
+ CStringW strFileTitle;
+ hr = DoGetFileTitle(strFileTitle, m_pDataObject);
+ if (FAILED(hr))
+ return hr;
+
CStringW strTitle;
- strTitle.Format(IDS_MOVETOTITLE, static_cast<LPCWSTR>(strFileTitle));
+ strTitle.Format(GetActionTitleStringID(), static_cast<LPCWSTR>(strFileTitle));
BROWSEINFOW info = { lpici->hwnd };
info.pidlRoot = NULL;
@@ -250,14 +252,67 @@ HRESULT CMoveToMenu::DoMoveToFolder(LPCMINVOKECOMMANDINFO lpici)
info.lParam = reinterpret_cast<LPARAM>(this);
CComHeapPtr<ITEMIDLIST> pidl(SHBrowseForFolder(&info));
if (pidl)
+ hr = DoRealFileOp(lpici, pidl);
+
+ return hr;
+}
+
+STDMETHODIMP
+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);
+
+ if (uFlags & (CMF_NOVERBS | CMF_VERBSONLY))
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdFirst);
+
+ 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)
{
- hr = DoRealMove(lpici, pidl);
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE;
+ mii.fType = MFT_SEPARATOR;
+ if (InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
+ {
+ ++indexMenu;
+ ++Count;
+ }
}
- return hr;
+ // 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_idCmdAction = m_idCmdLast++;
+ ++indexMenu;
+ ++Count;
+ }
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdFirst + Count);
}
-HRESULT WINAPI
+STDMETHODIMP
CMoveToMenu::QueryContextMenu(HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
@@ -309,7 +364,7 @@ CMoveToMenu::QueryContextMenu(HMENU hMenu,
mii.wID = m_idCmdLast;
if (InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
{
- m_idCmdMoveTo = m_idCmdLast++;
+ m_idCmdAction = m_idCmdLast++;
++indexMenu;
++Count;
}
@@ -317,36 +372,33 @@ CMoveToMenu::QueryContextMenu(HMENU hMenu,
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdFirst + Count);
}
-HRESULT WINAPI
-CMoveToMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
+STDMETHODIMP
+CCopyMoveToMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
HRESULT hr = E_FAIL;
- TRACE("CMoveToMenu::InvokeCommand(%p)\n", lpici);
+ TRACE("CCopyMoveToMenu::InvokeCommand(%p)\n", lpici);
if (IS_INTRESOURCE(lpici->lpVerb))
{
- if (m_idCmdFirst + LOWORD(lpici->lpVerb) == m_idCmdMoveTo)
- {
- hr = DoMoveToFolder(lpici);
- }
+ if (m_idCmdFirst + LOWORD(lpici->lpVerb) == m_idCmdAction)
+ hr = DoAction(lpici);
}
else
{
- if (::lstrcmpiA(lpici->lpVerb, "moveto") == 0)
- {
- hr = DoMoveToFolder(lpici);
- }
+ if (::lstrcmpiA(lpici->lpVerb, GetVerb()) == 0)
+ hr = DoAction(lpici);
}
return hr;
}
-HRESULT WINAPI
-CMoveToMenu::GetCommandString(UINT_PTR idCmd,
- UINT uType,
- UINT *pwReserved,
- LPSTR pszName,
- UINT cchMax)
+STDMETHODIMP
+CCopyMoveToMenu::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);
@@ -354,29 +406,30 @@ CMoveToMenu::GetCommandString(UINT_PTR idCmd,
return E_NOTIMPL;
}
-HRESULT WINAPI
-CMoveToMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
+STDMETHODIMP
+CCopyMoveToMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TRACE("This %p uMsg %x\n", this, uMsg);
return E_NOTIMPL;
}
-HRESULT WINAPI
-CMoveToMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder,
- IDataObject *pdtobj, HKEY hkeyProgID)
+STDMETHODIMP
+CCopyMoveToMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY
hkeyProgID)
{
m_pidlFolder.Attach(ILClone(pidlFolder));
m_pDataObject = pdtobj;
return S_OK;
}
-HRESULT WINAPI CMoveToMenu::SetSite(IUnknown *pUnkSite)
+STDMETHODIMP
+CCopyMoveToMenu::SetSite(IUnknown *pUnkSite)
{
m_pSite = pUnkSite;
return S_OK;
}
-HRESULT WINAPI CMoveToMenu::GetSite(REFIID riid, void **ppvSite)
+STDMETHODIMP
+CCopyMoveToMenu::GetSite(REFIID riid, void **ppvSite)
{
if (!m_pSite)
return E_FAIL;
diff --git a/dll/win32/shell32/CCopyMoveToMenu.h b/dll/win32/shell32/CCopyMoveToMenu.h
new file mode 100644
index 00000000000..3b9de7ad91a
--- /dev/null
+++ b/dll/win32/shell32/CCopyMoveToMenu.h
@@ -0,0 +1,111 @@
+/*
+ * PROJECT: ReactOS shell32
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: CopyTo and MoveTo implementation
+ * COPYRIGHT: Copyright 2020-2023 Katayama Hirofumi MZ
(katayama.hirofumi.mz(a)gmail.com)
+ */
+#pragma once
+
+class CCopyMoveToMenu :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IContextMenu2,
+ public IObjectWithSite,
+ public IShellExtInit
+{
+protected:
+ UINT m_idCmdFirst, m_idCmdLast, m_idCmdAction;
+ CComPtr<IDataObject> m_pDataObject;
+ CComPtr<IUnknown> m_pSite;
+
+ HRESULT DoRealFileOp(LPCMINVOKECOMMANDINFO lpici, PCUIDLIST_ABSOLUTE pidl);
+ HRESULT DoAction(LPCMINVOKECOMMANDINFO lpici);
+
+public:
+ CComHeapPtr<ITEMIDLIST> m_pidlFolder;
+ WNDPROC m_fnOldWndProc;
+ BOOL m_bIgnoreTextBoxChange;
+
+ CCopyMoveToMenu();
+
+ virtual UINT GetCaptionStringID() const = 0;
+ virtual UINT GetButtonStringID() const = 0;
+ virtual UINT GetActionTitleStringID() const = 0;
+ virtual UINT GetFileOp() const = 0;
+ virtual LPCSTR GetVerb() const = 0;
+
+ // IContextMenu
+ STDMETHODIMP GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved,
LPSTR lpszName, UINT uMaxNameLen) override;
+ STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) override;
+
+ // IContextMenu2
+ STDMETHODIMP HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
+
+ // IShellExtInit
+ STDMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY
hkeyProgID) override;
+
+ // IObjectWithSite
+ STDMETHODIMP SetSite(IUnknown *pUnkSite) override;
+ STDMETHODIMP GetSite(REFIID riid, void **ppvSite) override;
+};
+
+class CCopyToMenu
+ : public CComCoClass<CCopyToMenu, &CLSID_CopyToMenu>
+ , public CCopyMoveToMenu
+{
+public:
+ CComHeapPtr<ITEMIDLIST> m_pidlFolder;
+ WNDPROC m_fnOldWndProc;
+ BOOL m_bIgnoreTextBoxChange;
+
+ CCopyToMenu() { }
+
+ // IContextMenu
+ STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT
idCmdLast, UINT uFlags) override;
+
+ 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()
+
+ UINT GetCaptionStringID() const override { return IDS_COPYITEMS; }
+ UINT GetButtonStringID() const override { return IDS_COPYBUTTON; }
+ UINT GetActionTitleStringID() const override { return IDS_COPYTOTITLE; }
+ UINT GetFileOp() const override { return FO_COPY; }
+ LPCSTR GetVerb() const override { return "copyto"; }
+};
+
+class CMoveToMenu
+ : public CComCoClass<CMoveToMenu, &CLSID_MoveToMenu>
+ , public CCopyMoveToMenu
+{
+public:
+ CMoveToMenu() { }
+
+ // IContextMenu
+ STDMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT
idCmdLast, UINT uFlags) override;
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_MOVETOMENU)
+ DECLARE_NOT_AGGREGATABLE(CMoveToMenu)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CMoveToMenu)
+ 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()
+
+ UINT GetCaptionStringID() const override { return IDS_MOVEITEMS; }
+ UINT GetButtonStringID() const override { return IDS_MOVEBUTTON; }
+ UINT GetActionTitleStringID() const override { return IDS_MOVETOTITLE; }
+ UINT GetFileOp() const override { return FO_MOVE; }
+ LPCSTR GetVerb() const override { return "moveto"; }
+};
diff --git a/dll/win32/shell32/CCopyToMenu.cpp b/dll/win32/shell32/CCopyToMenu.cpp
deleted file mode 100644
index d3da9d1f5a8..00000000000
--- a/dll/win32/shell32/CCopyToMenu.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * 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);
-
-
-CCopyToMenu::CCopyToMenu() :
- m_idCmdFirst(0),
- m_idCmdLast(0),
- m_idCmdCopyTo(-1),
- m_fnOldWndProc(NULL),
- m_bIgnoreTextBoxChange(FALSE)
-{
-}
-
-CCopyToMenu::~CCopyToMenu()
-{
-}
-
-static LRESULT CALLBACK
-WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- WCHAR szPath[MAX_PATH];
- CCopyToMenu *this_ =
- reinterpret_cast<CCopyToMenu *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
-
- switch (uMsg)
- {
- case WM_COMMAND:
- {
- switch (LOWORD(wParam))
- {
- case IDC_BROWSE_FOR_FOLDER_FOLDER_TEXT:
- {
- if (HIWORD(wParam) == EN_CHANGE)
- {
- if (!this_->m_bIgnoreTextBoxChange)
- {
- // get the text
- GetDlgItemTextW(hwnd, IDC_BROWSE_FOR_FOLDER_FOLDER_TEXT,
szPath, _countof(szPath));
- StrTrimW(szPath, L" \t");
-
- // update OK button
- BOOL bValid = !PathIsRelative(szPath) &&
PathIsDirectoryW(szPath);
- SendMessageW(hwnd, BFFM_ENABLEOK, 0, bValid);
-
- return 0;
- }
-
- // reset flag
- this_->m_bIgnoreTextBoxChange = FALSE;
- }
- break;
- }
- }
- break;
- }
- }
- 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, BFFM_ENABLEOK, 0, FALSE);
- break;
- }
- case BFFM_SELCHANGED:
- {
- if (!this_)
- break;
-
- WCHAR szPath[MAX_PATH];
- LPCITEMIDLIST pidl = reinterpret_cast<LPCITEMIDLIST>(lParam);
-
- szPath[0] = 0;
- SHGetPathFromIDListW(pidl, szPath);
-
- if (ILIsEqual(pidl, this_->m_pidlFolder))
- PostMessageW(hwnd, BFFM_ENABLEOK, 0, FALSE);
- else if (PathFileExistsW(szPath) || _ILIsDesktop(pidl))
- PostMessageW(hwnd, BFFM_ENABLEOK, 0, TRUE);
- else
- PostMessageW(hwnd, BFFM_ENABLEOK, 0, FALSE);
-
- // the text box will be updated later soon, ignore it
- this_->m_bIgnoreTextBoxChange = TRUE;
- break;
- }
- }
-
- return FALSE;
-}
-
-HRESULT CCopyToMenu::DoRealCopy(LPCMINVOKECOMMANDINFO lpici, LPCITEMIDLIST pidl)
-{
- CDataObjectHIDA pCIDA(m_pDataObject);
- if (FAILED_UNEXPECTEDLY(pCIDA.hr()))
- return pCIDA.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;
- int res = SHFileOperationW(&op);
- if (res)
- {
- ERR("SHFileOperationW failed with 0x%x\n", res);
- return E_FAIL;
- }
- return S_OK;
-}
-
-CStringW CCopyToMenu::DoGetFileTitle()
-{
- CStringW ret = L"(file)";
-
- CDataObjectHIDA pCIDA(m_pDataObject);
- if (FAILED_UNEXPECTEDLY(pCIDA.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);
-
- if (uFlags & (CMF_NOVERBS | CMF_VERBSONLY))
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdFirst);
-
- 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, idCmdFirst + Count);
-}
-
-HRESULT WINAPI
-CCopyToMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
-{
- HRESULT hr = E_FAIL;
- TRACE("CCopyToMenu::InvokeCommand(%p)\n", lpici);
-
- if (IS_INTRESOURCE(lpici->lpVerb))
- {
- 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/CCopyToMoveToMenu.h
b/dll/win32/shell32/CCopyToMoveToMenu.h
deleted file mode 100644
index 01ee85d30c7..00000000000
--- a/dll/win32/shell32/CCopyToMoveToMenu.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * PROJECT: shell32
- * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
- * PURPOSE: CopyTo and MoveTo 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;
- BOOL m_bIgnoreTextBoxChange;
-
- 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()
-};
-
-class CMoveToMenu :
- public CComCoClass<CMoveToMenu, &CLSID_MoveToMenu>,
- public CComObjectRootEx<CComMultiThreadModelNoCS>,
- public IContextMenu2,
- public IObjectWithSite,
- public IShellExtInit
-{
-protected:
- UINT m_idCmdFirst, m_idCmdLast, m_idCmdMoveTo;
- CComPtr<IDataObject> m_pDataObject;
- CComPtr<IUnknown> m_pSite;
-
- HRESULT DoMoveToFolder(LPCMINVOKECOMMANDINFO lpici);
- HRESULT DoRealMove(LPCMINVOKECOMMANDINFO lpici, PCUIDLIST_ABSOLUTE pidl);
- CStringW DoGetFileTitle();
-
-public:
- CComHeapPtr<ITEMIDLIST> m_pidlFolder;
- WNDPROC m_fnOldWndProc;
- BOOL m_bIgnoreTextBoxChange;
-
- CMoveToMenu();
- ~CMoveToMenu();
-
- // 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_MOVETOMENU)
- DECLARE_NOT_AGGREGATABLE(CMoveToMenu)
-
- DECLARE_PROTECT_FINAL_CONSTRUCT()
-
- BEGIN_COM_MAP(CMoveToMenu)
- 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/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt
index 5f972807c8b..264b116f5a2 100644
--- a/dll/win32/shell32/CMakeLists.txt
+++ b/dll/win32/shell32/CMakeLists.txt
@@ -73,8 +73,7 @@ list(APPEND SOURCE
COpenWithMenu.cpp
CNewMenu.cpp
CSendToMenu.cpp
- CCopyToMenu.cpp
- CMoveToMenu.cpp
+ CCopyMoveToMenu.cpp
CShellDispatch.cpp
CFolder.cpp
CFolderItems.cpp
diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h
index 9b422353e6c..393693885ac 100644
--- a/dll/win32/shell32/precomp.h
+++ b/dll/win32/shell32/precomp.h
@@ -95,7 +95,7 @@
#include "COpenWithMenu.h"
#include "CNewMenu.h"
#include "CSendToMenu.h"
-#include "CCopyToMoveToMenu.h"
+#include "CCopyMoveToMenu.h"
#include "dialogs/filedefext.h"
#include "dialogs/drvdefext.h"
#include "CQueryAssociations.h"