https://git.reactos.org/?p=reactos.git;a=commitdiff;h=55469633cfbf20ba34bc7…
commit 55469633cfbf20ba34bc747a80001bd4c7c4afb4
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Jul 9 00:01:12 2018 +0900
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Jul 8 17:01:12 2018 +0200
[SHELL32] Add 'Properties' menu item in My Computer (#647)
- Add a Shell_DefaultContextMenuCallBack() helper function.
- Implement the IContextMenuCB interface in CDrivesFolder.
CORE-12509
---
dll/win32/shell32/folders/CDesktopFolder.cpp | 28 +--------------
dll/win32/shell32/folders/CDrivesFolder.cpp | 52 ++++++++++++++++++++++++++--
dll/win32/shell32/folders/CDrivesFolder.h | 7 +++-
dll/win32/shell32/folders/CFSFolder.cpp | 28 +--------------
dll/win32/shell32/precomp.h | 3 ++
dll/win32/shell32/shlfolder.cpp | 41 ++++++++++++++++++++++
6 files changed, 102 insertions(+), 57 deletions(-)
diff --git a/dll/win32/shell32/folders/CDesktopFolder.cpp
b/dll/win32/shell32/folders/CDesktopFolder.cpp
index 9a1a452ea8..b5bb839603 100644
--- a/dll/win32/shell32/folders/CDesktopFolder.cpp
+++ b/dll/win32/shell32/folders/CDesktopFolder.cpp
@@ -864,33 +864,7 @@ HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND
hwndOwner, IData
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);
}
/*************************************************************************
diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp
b/dll/win32/shell32/folders/CDrivesFolder.cpp
index 77f6420196..15ccef2da8 100644
--- a/dll/win32/shell32/folders/CDrivesFolder.cpp
+++ b/dll/win32/shell32/folders/CDrivesFolder.cpp
@@ -669,8 +669,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))
{
@@ -1059,3 +1072,38 @@ 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 shell32.dll,Control_RunDLL
sysdm.cpl", NULL, 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);
+}
diff --git a/dll/win32/shell32/folders/CDrivesFolder.h
b/dll/win32/shell32/folders/CDrivesFolder.h
index f0adc4960a..f83057d79d 100644
--- a/dll/win32/shell32/folders/CDrivesFolder.h
+++ b/dll/win32/shell32/folders/CDrivesFolder.h
@@ -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()
};
diff --git a/dll/win32/shell32/folders/CFSFolder.cpp
b/dll/win32/shell32/folders/CFSFolder.cpp
index 77d87e6f82..ad205c47e1 100644
--- a/dll/win32/shell32/folders/CFSFolder.cpp
+++ b/dll/win32/shell32/folders/CFSFolder.cpp
@@ -1624,31 +1624,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);
}
diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h
index 75c136664d..4e694f7b86 100644
--- a/dll/win32/shell32/precomp.h
+++ b/dll/win32/shell32/precomp.h
@@ -120,4 +120,7 @@ AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
return FALSE;
}
+HRESULT WINAPI
+Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj);
+
#endif /* _PRECOMP_H__ */
diff --git a/dll/win32/shell32/shlfolder.cpp b/dll/win32/shell32/shlfolder.cpp
index 0b4d0f19a9..f652378616 100644
--- a/dll/win32/shell32/shlfolder.cpp
+++ b/dll/win32/shell32/shlfolder.cpp
@@ -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;
+}