From 3b58b347bc1ba58540f5ecf2b0fe8f8b44640896 Mon Sep 17 00:00:00 2001 From: Whindmar Saksit Date: Sun, 7 Jun 2026 21:28:13 +0200 Subject: [PATCH] [EXPLORER][SHELL32] Forward Explorer refresh command to the Start Menu (#9108) --- base/shell/explorer/startmnu.cpp | 1 + base/shell/explorer/traywnd.cpp | 23 ++++++++++++++++++++ dll/win32/shell32/CShellDispatch.cpp | 3 +++ dll/win32/shell32/shellmenu/CMenuBand.cpp | 2 ++ dll/win32/shell32/shellmenu/CMenuDeskBar.cpp | 15 ++++++++++++- dll/win32/shell32/shellmenu/CStartMenu.cpp | 11 ++++++++-- sdk/include/reactos/shlobj_undoc.h | 1 + sdk/include/reactos/undocshell.h | 1 + 8 files changed, 54 insertions(+), 3 deletions(-) diff --git a/base/shell/explorer/startmnu.cpp b/base/shell/explorer/startmnu.cpp index 5a706a94069..a66c6c19672 100644 --- a/base/shell/explorer/startmnu.cpp +++ b/base/shell/explorer/startmnu.cpp @@ -41,6 +41,7 @@ UpdateStartMenu(IN OUT IMenuPopup *pMenuPopup, if (bRefresh) { FIXME("Refresh the Start menu with communicating with SHELL32\n"); + // TODO: TRAYCMD_RELOAD_STARTMENUCFG } return hRet; diff --git a/base/shell/explorer/traywnd.cpp b/base/shell/explorer/traywnd.cpp index f4a89cb41fc..38bdca498dd 100644 --- a/base/shell/explorer/traywnd.cpp +++ b/base/shell/explorer/traywnd.cpp @@ -9,6 +9,7 @@ #include "precomp.h" #include #include +#include #include "appbar.h" HRESULT TrayWindowCtxMenuCreator(ITrayWindow * TrayWnd, IN HWND hWndOwner, IContextMenu ** ppCtxMenu); @@ -458,11 +459,22 @@ public: ClearRecentAndMru(); } + void RefreshStartMenuSettings() + { + IUnknown_Exec(m_StartMenuPopup, CLSID_MenuBand, 0x10000000, 0, NULL, NULL); + } + LRESULT DoExitWindows() { if (SHRestricted(REST_NOCLOSE)) return 0; + if (GetAsyncKeyState(VK_SHIFT) < 0 || + !SHGetValueW(HKEY_CURRENT_USER, REGSTR_PATH_EXPLORER L"\\Advanced", L"StartMenuForceRefresh", NULL, NULL, NULL)) + { + RefreshStartMenuSettings(); + } + SaveState(); /* Display the ReactOS Shutdown Dialog */ @@ -881,13 +893,23 @@ public: Sleep(100); //DisconnectWindowsDialog(m_DesktopWnd); // FIXME: shell32 break; + case TRAYCMD_RELOAD_STARTMENUCFG: + C_ASSERT(TRAYCMD_RELOAD_STARTMENUCFG == FCIDM_SHBROWSER_REFRESH); + C_ASSERT(TRAYCMD_RELOAD_STARTMENUCFG != FCIDM_CABINET_REFRESH); + C_ASSERT(TRAYCMD_RELOAD_STARTMENUCFG != TRAYCMD_REFRESH_MENU); + RefreshStartMenuSettings(); + break; case IDM_SEARCH: case TRAYCMD_SEARCH_FILES: + C_ASSERT(TRAYCMD_SEARCH_FILES == FCIDM_SHBROWSER_FINDFILES); SHFindFiles(NULL, NULL); break; case TRAYCMD_SEARCH_COMPUTERS: + C_ASSERT(TRAYCMD_SEARCH_COMPUTERS == FCIDM_SHBROWSER_FINDCOMPUTER); SHFindComputer(NULL, NULL); break; + //case TRAYCMD_REFRESH_MENU: Does nothing on WinXP+ + // break; default: break; } @@ -2488,6 +2510,7 @@ ChangePos: #else // Update the start menu UpdateStartMenu(m_StartMenuPopup, hbmBanner, g_TaskbarSettings.sr.SmSmallIcons, TRUE); + HandleCommand(TRAYCMD_RELOAD_STARTMENUCFG); #endif } diff --git a/dll/win32/shell32/CShellDispatch.cpp b/dll/win32/shell32/CShellDispatch.cpp index 76657abd27b..386cf9bf2b5 100644 --- a/dll/win32/shell32/CShellDispatch.cpp +++ b/dll/win32/shell32/CShellDispatch.cpp @@ -258,6 +258,9 @@ HRESULT STDMETHODCALLTYPE CShellDispatch::FindComputer() HRESULT STDMETHODCALLTYPE CShellDispatch::RefreshMenu() { TRACE("(%p)\n", this); + C_ASSERT(FCIDM_CABINET_REFRESH == TRAYCMD_REFRESH_MENU); + // According to https://learn.microsoft.com/en-us/windows/win32/shell/ishelldispatch-refreshmenu + // only systems preceding Windows XP refreshes the contents of the Start menu when this is called. return PostTrayCommand(TRAYCMD_REFRESH_MENU); } diff --git a/dll/win32/shell32/shellmenu/CMenuBand.cpp b/dll/win32/shell32/shellmenu/CMenuBand.cpp index 48407ab1d59..d8f812f6879 100644 --- a/dll/win32/shell32/shellmenu/CMenuBand.cpp +++ b/dll/win32/shell32/shellmenu/CMenuBand.cpp @@ -1172,6 +1172,8 @@ HRESULT CMenuBand::AdjustForTheme(BOOL bFlatStyle) HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags) { UNIMPLEMENTED; + if (!psmd && (dwFlags & SMINV_REFRESH)) + _CallCB(SMC_REFRESH, 0, 0); return S_OK; } diff --git a/dll/win32/shell32/shellmenu/CMenuDeskBar.cpp b/dll/win32/shell32/shellmenu/CMenuDeskBar.cpp index 493e4905a1a..cb71e4e6bf1 100644 --- a/dll/win32/shell32/shellmenu/CMenuDeskBar.cpp +++ b/dll/win32/shell32/shellmenu/CMenuDeskBar.cpp @@ -125,9 +125,22 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::Exec(const GUID *pguidCmdGroup, DWORD nC return _AdjustForTheme(nCmdexecopt); } } - if (IsEqualIID(*pguidCmdGroup, CGID_Explorer)) + else if (IsEqualIID(*pguidCmdGroup, CLSID_MenuBand)) { + switch (nCmdID) + { + case 0x10000000: // refresh (sent from TRAYCMD_RELOAD_STARTMENUCFG) + { + CComPtr pSM; // We just want IShellMenu but CMenuBand::QI is broken? + if (SUCCEEDED(IUnknown_QueryService(m_Client, SID_SMenuBandBottom, IID_PPV_ARG(IShellMenu2, &pSM)))) + pSM->InvalidateItem(NULL, SMINV_REFRESH); + return S_OK; + } + } } + /*else if (IsEqualIID(*pguidCmdGroup, CGID_Explorer)) + { + }*/ else if (IsEqualIID(*pguidCmdGroup, IID_IDeskBarClient)) { switch (nCmdID) diff --git a/dll/win32/shell32/shellmenu/CStartMenu.cpp b/dll/win32/shell32/shellmenu/CStartMenu.cpp index 478982fa3bd..80d0531bb6e 100644 --- a/dll/win32/shell32/shellmenu/CStartMenu.cpp +++ b/dll/win32/shell32/shellmenu/CStartMenu.cpp @@ -25,7 +25,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(CStartMenu); //#define TEST_TRACKPOPUPMENU_SUBMENUS - +#define IDM_STARTMENUROOT ( (UINT)-1 ) /* NOTE: The following constants *MUST NOT* be changed because they're hardcoded and need to be the exact values in order to get the start menu to work! */ @@ -474,6 +474,13 @@ public: case SMC_SFEXEC: m_pTrayPriv->Execute(psmd->psf, psmd->pidlItem); break; + case SMC_REFRESH: + if (psmd->uIdParent == IDM_STARTMENUROOT) + { + // TODO: Update CascadeMyDocuments etc. + return S_OK; + } + break; case 0x10000000: // _FilterPIDL from CMenuSFToolbar if (psmd->psf->CompareIDs(0, psmd->pidlItem, m_pidlPrograms) == 0) return S_OK; @@ -619,7 +626,7 @@ RSHELL_CStartMenu_CreateInstance(REFIID riid, void **ppv) pCallback->AddRef(); // CreateInstance returns object with 0 ref count */ pCallback->Initialize(pShellMenu, pBandSite, pDeskBar); - hr = pShellMenu->Initialize(pCallback, (UINT) -1, 0, SMINIT_TOPLEVEL | SMINIT_VERTICAL); + hr = pShellMenu->Initialize(pCallback, IDM_STARTMENUROOT, 0, SMINIT_TOPLEVEL | SMINIT_VERTICAL); if (FAILED_UNEXPECTEDLY(hr)) return hr; diff --git a/sdk/include/reactos/shlobj_undoc.h b/sdk/include/reactos/shlobj_undoc.h index 947bfc1f98f..03502537c8e 100644 --- a/sdk/include/reactos/shlobj_undoc.h +++ b/sdk/include/reactos/shlobj_undoc.h @@ -94,6 +94,7 @@ struct persistState #define FCIDM_SHBROWSER_MAPNETDRIVE 0xA081 #define FCIDM_SHBROWSER_UNMAPNETDRIVE 0xA082 #define FCIDM_SHBROWSER_FINDFILES 0xA085 +#define FCIDM_SHBROWSER_FINDCOMPUTER 0xA086 #define FCIDM_SHBROWSER_OPTIONS 0xA123 #define FCIDM_CABINET_NT5_GOTO_DRIVES 0xA132 #define FCIDM_CABINET_TOGGLEITBAR 0xA201 diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index 94e14a61ea0..e00e33372a4 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -1015,6 +1015,7 @@ BOOL WINAPI LinkWindow_UnregisterClass(_In_ DWORD dwUnused); #define TRAYCMD_PRINTERS_AND_FAXES 510 #define TRAYCMD_LOCK_DESKTOP 517 #define TRAYCMD_SWITCH_USER_DIALOG 5000 +#define TRAYCMD_RELOAD_STARTMENUCFG 41061 #define TRAYCMD_SEARCH_FILES 41093 #define TRAYCMD_SEARCH_COMPUTERS 41094 #define TRAYCMD_REFRESH_MENU 41504