[0.4.7][SHELL32] Add 'Properties' menu item in My Computer (#647) CORE-12509
authorJoachim Henze <Joachim.Henze@reactos.org>
Sat, 26 Feb 2022 18:09:02 +0000 (19:09 +0100)
committerJoachim Henze <Joachim.Henze@reactos.org>
Sat, 26 Feb 2022 18:09:02 +0000 (19:09 +0100)
- Add a Shell_DefaultContextMenuCallBack() helper function.
- Implement the IContextMenuCB interface in CDrivesFolder.

It regressed by some unknown commit in between SVN r70702 to r73408

fix picked from 0.4.10-dev-329-g 55469633cfbf20ba34bc747a80001bd4c7c4afb4
------
and pick also the unrelated:
0.4.8-dev-53-g 9192d39f6e177683ad40d85bdcb70c443e40a13a [SHELL32] Fix multiple selection of desktop icons
which had no JIRA-ticket.

dll/win32/shell32/folders/CDesktopFolder.cpp
dll/win32/shell32/folders/CDrivesFolder.cpp
dll/win32/shell32/folders/CDrivesFolder.h
dll/win32/shell32/folders/CFSFolder.cpp
dll/win32/shell32/precomp.h
dll/win32/shell32/shlfolder.cpp

index 4c05372..222c114 100644 (file)
@@ -861,33 +861,10 @@ HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IData
         return S_OK;
     }
 
-    PIDLIST_ABSOLUTE pidlFolder;
-    PUITEMID_CHILD *apidl;
-    UINT cidl;
-    HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    if (cidl > 1)
-        ERR("SHMultiFileProperties is not yet implemented\n");
-
-    STRRET strFile;
-    hr = GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strFile);
-    if (SUCCEEDED(hr))
-    {
-        hr = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, apidl);
-        if (FAILED(hr))
-            ERR("SH_ShowPropertiesDialog failed\n");
-    }
-    else
-    {
-        ERR("Failed to get display name\n");
-    }
-
-    SHFree(pidlFolder);
-    _ILFreeaPidl(apidl, cidl);
+    if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
+        return S_OK;
 
-    return hr;
+    return Shell_DefaultContextMenuCallBack(this, pdtobj);
 }
 
 /*************************************************************************
index 7a08824..03037c4 100644 (file)
@@ -456,8 +456,21 @@ HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVO
     }
     else if (IsEqualIID(riid, IID_IContextMenu))
     {
-        WARN("IContextMenu not implemented\n");
-        hr = E_NOTIMPL;
+        HKEY hKeys[16];
+        UINT cKeys = 0;
+        AddClassKeyToArray(L"Directory\\Background", hKeys, &cKeys);
+
+        DEFCONTEXTMENU dcm;
+        dcm.hwnd = hwndOwner;
+        dcm.pcmcb = this;
+        dcm.pidlFolder = pidlRoot;
+        dcm.psf = this;
+        dcm.cidl = 0;
+        dcm.apidl = NULL;
+        dcm.cKeys = cKeys;
+        dcm.aKeys = hKeys;
+        dcm.punkAssociationInfo = NULL;
+        hr = SHCreateDefaultContextMenu(&dcm, riid, ppvOut);
     }
     else if (IsEqualIID(riid, IID_IShellView))
     {
@@ -846,3 +859,43 @@ HRESULT WINAPI CDrivesFolder::GetCurFolder(LPITEMIDLIST *pidl)
     *pidl = ILClone(pidlRoot);
     return S_OK;
 }
+
+/************************************************************************/
+/* IContextMenuCB interface */
+
+HRESULT WINAPI CDrivesFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    if (uMsg != DFM_MERGECONTEXTMENU && uMsg != DFM_INVOKECOMMAND)
+        return S_OK;
+
+    /* no data object means no selection */
+    if (!pdtobj)
+    {
+        if (uMsg == DFM_INVOKECOMMAND && wParam == 1)   // #1
+        {
+            // "System" properties
+            ShellExecuteW(hwndOwner,
+                          NULL,
+                          L"rundll32.exe",
+                          L"shell32.dll,Control_RunDLL sysdm.cpl",
+                          NULL,
+                          SW_SHOWNORMAL);
+        }
+        else if (uMsg == DFM_MERGECONTEXTMENU)
+        {
+            QCMINFO *pqcminfo = (QCMINFO *)lParam;
+            HMENU hpopup = CreatePopupMenu();
+            _InsertMenuItemW(hpopup, 0, TRUE, 0, MFT_SEPARATOR, NULL, MFS_ENABLED); // #0
+            _InsertMenuItemW(hpopup, 1, TRUE, 1, MFT_STRING, MAKEINTRESOURCEW(IDS_PROPERTIES), MFS_ENABLED); // #1
+            Shell_MergeMenus(pqcminfo->hmenu, hpopup, pqcminfo->indexMenu++, pqcminfo->idCmdFirst, pqcminfo->idCmdLast, MM_ADDSEPARATOR);
+            DestroyMenu(hpopup);
+        }
+
+        return S_OK;
+    }
+
+    if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
+        return S_OK;
+
+    return Shell_DefaultContextMenuCallBack(this, pdtobj);
+}
index f0adc49..f83057d 100644 (file)
@@ -27,7 +27,8 @@ class CDrivesFolder :
     public CComCoClass<CDrivesFolder, &CLSID_MyComputer>,
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellFolder2,
-    public IPersistFolder2
+    public IPersistFolder2,
+    public IContextMenuCB
 {
     private:
         /* both paths are parsible from the desktop */
@@ -69,6 +70,9 @@ class CDrivesFolder :
         // IPersistFolder2
         virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl);
 
+        // IContextMenuCB
+        virtual HRESULT WINAPI CallBack(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
         DECLARE_REGISTRY_RESOURCEID(IDR_MYCOMPUTER)
         DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(CDrivesFolder)
 
@@ -80,6 +84,7 @@ class CDrivesFolder :
         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
         COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
+        COM_INTERFACE_ENTRY_IID(IID_IContextMenuCB, IContextMenuCB)
         END_COM_MAP()
 };
 
index e6a7e75..9e18d9c 100644 (file)
@@ -1603,31 +1603,5 @@ HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObjec
     if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
         return S_OK;
 
-    PIDLIST_ABSOLUTE pidlFolder;
-    PUITEMID_CHILD *apidl;
-    UINT cidl;
-    HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
-
-    if (cidl > 1)
-        ERR("SHMultiFileProperties is not yet implemented\n");
-
-    STRRET strFile;
-    hr = GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strFile);
-    if (SUCCEEDED(hr))
-    {
-        hr = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, apidl);
-        if (FAILED(hr))
-            ERR("SH_ShowPropertiesDialog failed\n");
-    }
-    else
-    {
-        ERR("Failed to get display name\n");
-    }
-
-    SHFree(pidlFolder);
-    _ILFreeaPidl(apidl, cidl);
-
-    return hr;
+    return Shell_DefaultContextMenuCallBack(this, pdtobj);
 }
index 1673253..a959a4a 100644 (file)
@@ -98,4 +98,7 @@ extern const GUID CLSID_UnixDosFolder;
 extern const GUID SHELL32_AdvtShortcutProduct;
 extern const GUID SHELL32_AdvtShortcutComponent;
 
+HRESULT WINAPI
+Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj);
+
 #endif /* _PRECOMP_H__ */
index 0b4d0f1..f652378 100644 (file)
@@ -3,6 +3,7 @@
  *
  *    Copyright 1997            Marcus Meissner
  *    Copyright 1998, 1999, 2002    Juergen Schmied
+ *    Copyright 2018 Katayama Hirofumi MZ
  *
  *    IShellFolder2 and related interfaces
  *
@@ -441,3 +442,43 @@ SHOpenFolderAndSelectItems(LPITEMIDLIST pidlFolder,
     else
         return E_FAIL;
 }
+
+/*
+ * for internal use
+ */
+HRESULT WINAPI
+Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj)
+{
+    PIDLIST_ABSOLUTE pidlFolder;
+    PUITEMID_CHILD *apidl;
+    UINT cidl;
+    HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    if (cidl > 1)
+    {
+        ERR("SHMultiFileProperties is not yet implemented\n");
+        SHFree(pidlFolder);
+        _ILFreeaPidl(apidl, cidl);
+        return E_FAIL;
+    }
+
+    STRRET strFile;
+    hr = psf->GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strFile);
+    if (SUCCEEDED(hr))
+    {
+        hr = SH_ShowPropertiesDialog(strFile.pOleStr, pidlFolder, apidl);
+        if (FAILED(hr))
+            ERR("SH_ShowPropertiesDialog failed\n");
+    }
+    else
+    {
+        ERR("Failed to get display name\n");
+    }
+
+    SHFree(pidlFolder);
+    _ILFreeaPidl(apidl, cidl);
+
+    return hr;
+}