https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a938d19714f9ab659c8d9c2250f2cafc5db8f637

commit a938d19714f9ab659c8d9c2250f2cafc5db8f637
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Sat Nov 4 21:56:15 2023 +0900
Commit:     GitHub <nore...@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...@gmail.com)
+ * PURPOSE:     CopyTo and MoveTo implementation
+ * COPYRIGHT:   Copyright 2020-2023 Katayama Hirofumi MZ 
(katayama.hirofumi...@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...@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...@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...@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"

Reply via email to