[EXPLORER][SHELL32] Show/hide 'Admin tools' menu (#6598)

Improve Start Menu customization.
JIRA issue: CORE-16956
- Add IsPidlPrograms helper function.
- Specify a PIDL for Programs menu.
- Check the "StartMenuAdminTools" registry value.
- Don't add "Admin Tools" menu item into
  CMenuSFToolbar::FillToolbar if necessary.
This commit is contained in:
Katayama Hirofumi MZ 2024-03-11 21:58:30 +09:00 committed by GitHub
parent 8bd071a51e
commit acb01cf568
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 59 additions and 21 deletions

View file

@ -89,7 +89,9 @@ struct CUSTOMIZE_ENTRY
static const CUSTOMIZE_ENTRY s_CustomizeEntries[] =
{
// FIXME: Make "StartMenuAdminTools" effective for IDS_ADVANCED_DISPLAY_ADMINTOOLS
{
IDS_ADVANCED_DISPLAY_ADMINTOOLS, L"StartMenuAdminTools", TRUE,
},
{
IDS_ADVANCED_DISPLAY_FAVORITES, L"StartMenuFavorites", FALSE,
REST_NOFAVORITESMENU

View file

@ -1323,6 +1323,18 @@ int CALLBACK PidlListSort(void* item1, void* item2, LPARAM lParam)
return (int)(short)LOWORD(hr);
}
static BOOL IsPidlPrograms(LPCITEMIDLIST pidlTarget)
{
WCHAR szTarget[MAX_PATH], szPath[MAX_PATH];
if (!SHGetPathFromIDListW(pidlTarget, szTarget))
return FALSE;
SHGetSpecialFolderPathW(NULL, szPath, CSIDL_COMMON_PROGRAMS, FALSE);
if (lstrcmpiW(szTarget, szPath) == 0)
return TRUE;
SHGetSpecialFolderPathW(NULL, szPath, CSIDL_PROGRAMS, FALSE);
return (lstrcmpiW(szTarget, szPath) == 0);
}
HRESULT CMenuSFToolbar::FillToolbar(BOOL clearFirst)
{
HRESULT hr;
@ -1361,17 +1373,26 @@ HRESULT CMenuSFToolbar::FillToolbar(BOOL clearFirst)
DPA_Sort(dpaSort, PidlListSort, (LPARAM) m_shellFolder.p);
BOOL StartMenuAdminTools = SHRegGetBoolUSValueW(
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
L"StartMenuAdminTools", FALSE, TRUE);
BOOL bMustHideAdminTools = IsPidlPrograms(m_idList) && StartMenuAdminTools;
TRACE("StartMenuAdminTools: %d\n", StartMenuAdminTools);
TRACE("bMustHideAdminTools: %d\n", bMustHideAdminTools);
WCHAR szAdminTools[MAX_PATH];
if (bMustHideAdminTools)
{
LoadStringW(GetModuleHandleW(L"shell32.dll"), IDS_ADMINISTRATIVETOOLS,
szAdminTools, _countof(szAdminTools));
}
for (int i = 0; i<DPA_GetPtrCount(dpaSort);)
{
PWSTR MenuString;
INT index = 0;
INT indexOpen = 0;
STRRET sr = { STRRET_CSTR, { 0 } };
item = (LPITEMIDLIST)DPA_GetPtr(dpaSort, i);
STRRET sr = { STRRET_CSTR };
hr = m_shellFolder->GetDisplayNameOf(item, SIGDN_NORMALDISPLAY, &sr);
if (FAILED_UNEXPECTEDLY(hr))
{
@ -1379,9 +1400,18 @@ HRESULT CMenuSFToolbar::FillToolbar(BOOL clearFirst)
return hr;
}
PWSTR MenuString;
StrRetToStr(&sr, NULL, &MenuString);
index = SHMapPIDLToSystemImageListIndex(m_shellFolder, item, &indexOpen);
if (bMustHideAdminTools && lstrcmpiW(MenuString, szAdminTools) == 0)
{
++i;
CoTaskMemFree(MenuString);
continue;
}
INT indexOpen = 0;
INT index = SHMapPIDLToSystemImageListIndex(m_shellFolder, item, &indexOpen);
LPCITEMIDLIST itemc = item;

View file

@ -237,26 +237,33 @@ private:
AddOrSetMenuItem(hMenu, IDM_PRINTERSANDFAXES, CSIDL_PRINTERS, bExpand, FALSE, FALSE);
}
HRESULT AddStartMenuItems(IShellMenu *pShellMenu, INT csidl, DWORD dwFlags)
HRESULT AddStartMenuItems(IShellMenu *pShellMenu, INT csidl, DWORD dwFlags, IShellFolder *psf = NULL)
{
CComHeapPtr<ITEMIDLIST> pidlMenu;
CComHeapPtr<ITEMIDLIST> pidlFolder;
CComPtr<IShellFolder> psfDesktop;
CComPtr<IShellFolder> pShellFolder;
HRESULT hr;
hr = SHGetFolderLocation(NULL, csidl, 0, 0, &pidlMenu);
hr = SHGetFolderLocation(NULL, csidl, 0, 0, &pidlFolder);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = SHGetDesktopFolder(&psfDesktop);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (psf)
{
pShellFolder = psf;
}
else
{
hr = SHGetDesktopFolder(&psfDesktop);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = psfDesktop->BindToObject(pidlMenu, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = psfDesktop->BindToObject(pidlFolder, NULL, IID_PPV_ARG(IShellFolder, &pShellFolder));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
}
hr = pShellMenu->SetShellFolder(pShellFolder, NULL, NULL, dwFlags);
hr = pShellMenu->SetShellFolder(pShellFolder, pidlFolder, NULL, dwFlags);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -281,8 +288,7 @@ private:
{
case IDM_PROGRAMS:
{
if (m_psfPrograms)
hr = pShellMenu->SetShellFolder(m_psfPrograms, NULL, NULL, SMSET_TOP);
hr = AddStartMenuItems(pShellMenu, CSIDL_PROGRAMS, SMSET_TOP, m_psfPrograms);
break;
}
case IDM_FAVORITES: