[SHELL32] Add 'Properties' menu item in My Computer (#647)

- Add a Shell_DefaultContextMenuCallBack() helper function.
- Implement the IContextMenuCB interface in CDrivesFolder.
CORE-12509
This commit is contained in:
Katayama Hirofumi MZ 2018-07-09 00:01:12 +09:00 committed by Hermès BÉLUSCA - MAÏTO
parent 96c0ef4209
commit 55469633cf
6 changed files with 102 additions and 57 deletions

View file

@ -864,33 +864,7 @@ HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IData
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES) if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK; return S_OK;
PIDLIST_ABSOLUTE pidlFolder; return Shell_DefaultContextMenuCallBack(this, pdtobj);
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;
} }
/************************************************************************* /*************************************************************************

View file

@ -669,8 +669,21 @@ HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVO
} }
else if (IsEqualIID(riid, IID_IContextMenu)) else if (IsEqualIID(riid, IID_IContextMenu))
{ {
WARN("IContextMenu not implemented\n"); HKEY hKeys[16];
hr = E_NOTIMPL; 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)) else if (IsEqualIID(riid, IID_IShellView))
{ {
@ -1059,3 +1072,38 @@ HRESULT WINAPI CDrivesFolder::GetCurFolder(LPITEMIDLIST *pidl)
*pidl = ILClone(pidlRoot); *pidl = ILClone(pidlRoot);
return S_OK; 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);
}

View file

@ -27,7 +27,8 @@ class CDrivesFolder :
public CComCoClass<CDrivesFolder, &CLSID_MyComputer>, public CComCoClass<CDrivesFolder, &CLSID_MyComputer>,
public CComObjectRootEx<CComMultiThreadModelNoCS>, public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2, public IShellFolder2,
public IPersistFolder2 public IPersistFolder2,
public IContextMenuCB
{ {
private: private:
/* both paths are parsible from the desktop */ /* both paths are parsible from the desktop */
@ -69,6 +70,9 @@ class CDrivesFolder :
// IPersistFolder2 // IPersistFolder2
virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl); 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_REGISTRY_RESOURCEID(IDR_MYCOMPUTER)
DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(CDrivesFolder) DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(CDrivesFolder)
@ -80,6 +84,7 @@ class CDrivesFolder :
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder) COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2) COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist) COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IContextMenuCB, IContextMenuCB)
END_COM_MAP() END_COM_MAP()
}; };

View file

@ -1624,31 +1624,5 @@ HRESULT WINAPI CFSFolder::CallBack(IShellFolder *psf, HWND hwndOwner, IDataObjec
if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES) if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
return S_OK; return S_OK;
PIDLIST_ABSOLUTE pidlFolder; return Shell_DefaultContextMenuCallBack(this, pdtobj);
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;
} }

View file

@ -120,4 +120,7 @@ AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
return FALSE; return FALSE;
} }
HRESULT WINAPI
Shell_DefaultContextMenuCallBack(IShellFolder *psf, IDataObject *pdtobj);
#endif /* _PRECOMP_H__ */ #endif /* _PRECOMP_H__ */

View file

@ -3,6 +3,7 @@
* *
* Copyright 1997 Marcus Meissner * Copyright 1997 Marcus Meissner
* Copyright 1998, 1999, 2002 Juergen Schmied * Copyright 1998, 1999, 2002 Juergen Schmied
* Copyright 2018 Katayama Hirofumi MZ
* *
* IShellFolder2 and related interfaces * IShellFolder2 and related interfaces
* *
@ -441,3 +442,43 @@ SHOpenFolderAndSelectItems(LPITEMIDLIST pidlFolder,
else else
return E_FAIL; 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;
}