[BROWSEUI] Refactor settings and sync them between windows (#5496)

This works similarly to how our shell stores its settings from a software design standpoint.

- Add settings.cpp file and ShellSettings structure to load and save settings.
- Add a registry value to hivedef.inf for the locked toolbar state.
  This prevents a bug where the associated registry key cannot be opened or saved to.
- Add new BWM_SETTINGCHANGE window message to refresh the UI on setting changes
  and send it to every open window when saving settings to the registry.
- Add new BWM_GETSETTINGSPTR window message to share the shellbrowser settings
  structure pointer with child windows and toolbars.
This commit is contained in:
Carl J. Bialorucki 2023-08-17 03:14:41 -06:00 committed by GitHub
parent 8888311452
commit 43b3dc2034
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 141 additions and 73 deletions

View File

@ -1902,6 +1902,7 @@ HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced","ShowSuperHid
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CabinetState",,0x00000012
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CabinetState","FullPath",0x00010003,0
HKCU,"SOFTWARE\Microsoft\Internet Explorer\Main","StatusBarOther",0x00010003,1
HKCU,"SOFTWARE\Microsoft\Internet Explorer\Toolbar","Locked",0x00010003,1
; ComDlg32
HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32",,0x00000012

View File

@ -30,6 +30,7 @@ list(APPEND SOURCE
internettoolbar.cpp
parsecmdline.cpp
regtreeoptions.cpp
settings.cpp
shellbrowser.cpp
toolsband.cpp
travellog.cpp

View File

@ -250,11 +250,11 @@ HRESULT CDockSite::GetRBBandInfo(REBARBANDINFOW &bandInfo)
bandInfo.fStyle |= RBBS_BREAK;
if (fDeskBandInfo.dwModeFlags & DBIMF_TOPALIGN)
bandInfo.fStyle |= RBBS_TOPALIGN;
if (fFlags & ITF_NOGRIPPER || fToolbar->fLocked)
if (fFlags & ITF_NOGRIPPER || fToolbar->pSettings->fLocked)
bandInfo.fStyle |= RBBS_NOGRIPPER;
if (fFlags & ITF_NOTITLE)
bandInfo.fStyle |= RBBS_HIDETITLE;
if (fFlags & ITF_GRIPPERALWAYS && !fToolbar->fLocked)
if (fFlags & ITF_GRIPPERALWAYS && !fToolbar->pSettings->fLocked)
bandInfo.fStyle |= RBBS_GRIPPERALWAYS;
if (fFlags & ITF_FIXEDSIZE)
bandInfo.fStyle |= RBBS_FIXEDSIZE;
@ -607,17 +607,13 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WP
CInternetToolbar::CInternetToolbar()
{
fLocked = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Toolbar",
L"Locked",
FALSE,
TRUE);
fMainReBar = NULL;
fMenuBandWindow = NULL;
fNavigationWindow = NULL;
fMenuCallback = new CComObject<CMenuCallback>();
fToolbarWindow = NULL;
fAdviseCookie = 0;
pSettings = NULL;
}
CInternetToolbar::~CInternetToolbar()
@ -714,45 +710,40 @@ HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **pMenuBar)
}
HRESULT CInternetToolbar::LockUnlockToolbars(bool locked)
{
if (locked != pSettings->fLocked)
{
pSettings->fLocked = locked;
pSettings->Save();
RefreshLockedToolbarState();
}
return S_OK;
}
void CInternetToolbar::RefreshLockedToolbarState()
{
REBARBANDINFOW rebarBandInfo;
int bandCount;
CDockSite *dockSite;
HRESULT hResult;
if (locked != fLocked)
rebarBandInfo.cbSize = sizeof(rebarBandInfo);
rebarBandInfo.fMask = RBBIM_STYLE | RBBIM_LPARAM;
bandCount = (int)SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0);
for (INT x = 0; x < bandCount; x++)
{
DWORD dwLocked = locked ? 1 : 0;
SHRegSetUSValueW(L"Software\\Microsoft\\Internet Explorer\\Toolbar",
L"Locked",
REG_DWORD,
&dwLocked,
sizeof(dwLocked),
SHREGSET_FORCE_HKCU);
fLocked = locked;
rebarBandInfo.cbSize = sizeof(rebarBandInfo);
rebarBandInfo.fMask = RBBIM_STYLE | RBBIM_LPARAM;
bandCount = (int)SendMessage(fMainReBar, RB_GETBANDCOUNT, 0, 0);
for (INT x = 0; x < bandCount; x++)
SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo);
dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam);
if (dockSite != NULL)
{
SendMessage(fMainReBar, RB_GETBANDINFOW, x, (LPARAM)&rebarBandInfo);
dockSite = reinterpret_cast<CDockSite *>(rebarBandInfo.lParam);
if (dockSite != NULL)
{
rebarBandInfo.fStyle &= ~(RBBS_NOGRIPPER | RBBS_GRIPPERALWAYS);
if (dockSite->fFlags & CDockSite::ITF_NOGRIPPER || fLocked)
rebarBandInfo.fStyle |= RBBS_NOGRIPPER;
if (dockSite->fFlags & CDockSite::ITF_GRIPPERALWAYS && !fLocked)
rebarBandInfo.fStyle |= RBBS_GRIPPERALWAYS;
SendMessage(fMainReBar, RB_SETBANDINFOW, x, (LPARAM)&rebarBandInfo);
}
rebarBandInfo.fStyle &= ~(RBBS_NOGRIPPER | RBBS_GRIPPERALWAYS);
if (dockSite->fFlags & CDockSite::ITF_NOGRIPPER || pSettings->fLocked)
rebarBandInfo.fStyle |= RBBS_NOGRIPPER;
if (dockSite->fFlags & CDockSite::ITF_GRIPPERALWAYS && !pSettings->fLocked)
rebarBandInfo.fStyle |= RBBS_GRIPPERALWAYS;
SendMessage(fMainReBar, RB_SETBANDINFOW, x, (LPARAM)&rebarBandInfo);
}
hResult = ReserveBorderSpace(0);
// TODO: refresh view menu?
}
return S_OK;
ReserveBorderSpace(0);
}
HRESULT CInternetToolbar::SetState(const GUID *pguidCmdGroup, long commandID, OLECMD* pcmd)
@ -980,7 +971,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::ResizeBorderDW(LPCRECT prcBorder,
::GetWindowRect(fMainReBar, &availableBorderSpace);
neededBorderSpace.left = 0;
neededBorderSpace.top = availableBorderSpace.bottom - availableBorderSpace.top;
if (!fLocked)
if (!pSettings->fLocked)
neededBorderSpace.top += 3;
neededBorderSpace.right = 0;
neededBorderSpace.bottom = 0;
@ -1145,7 +1136,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGrou
break;
case ITID_TOOLBARLOCKED: // lock toolbars
prgCmds->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED;
if (fLocked)
if (pSettings->fLocked)
prgCmds->cmdf |= OLECMDF_LATCHED;
break;
default:
@ -1184,7 +1175,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::Exec(const GUID *pguidCmdGroup, DWOR
// run customize
return S_OK;
case ITID_TOOLBARLOCKED:
return LockUnlockToolbars(!fLocked);
return LockUnlockToolbars(!pSettings->fLocked);
}
}
return E_FAIL;
@ -1356,6 +1347,9 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::SetSite(IUnknown *pUnkSite)
if (ownerWindow == NULL)
return E_FAIL;
// Get settings from owner window
::SendMessageW(ownerWindow, BWM_GETSETTINGSPTR, 0, (LPARAM)&pSettings);
// create dock container
fSite = pUnkSite;
dockContainer = SHCreateWorkerWindowW(0, ownerWindow, 0,
@ -1682,7 +1676,6 @@ LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
RBHITTESTINFO hitTestInfo;
REBARBANDINFOW rebarBandInfo;
int bandID;
BOOL goButtonChecked;
clickLocation.x = LOWORD(lParam);
clickLocation.y = HIWORD(lParam);
@ -1727,9 +1720,8 @@ LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
SHCheckMenuItem(contextMenu, IDM_TOOLBARS_ADDRESSBAR, IsBandVisible(ITBBID_ADDRESSBAND) == S_OK);
SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LINKSBAR, FALSE);
SHCheckMenuItem(contextMenu, IDM_TOOLBARS_CUSTOMIZE, FALSE);
SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, fLocked);
goButtonChecked = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", FALSE, TRUE);
SHCheckMenuItem(contextMenu, IDM_TOOLBARS_GOBUTTON, goButtonChecked);
SHCheckMenuItem(contextMenu, IDM_TOOLBARS_LOCKTOOLBARS, pSettings->fLocked);
SHCheckMenuItem(contextMenu, IDM_TOOLBARS_GOBUTTON, pSettings->fShowGoButton);
// TODO: use GetSystemMetrics(SM_MENUDROPALIGNMENT) to determine menu alignment
command = TrackPopupMenu(contextMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
@ -1745,7 +1737,7 @@ LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
case IDM_TOOLBARS_LINKSBAR: // links
break;
case IDM_TOOLBARS_LOCKTOOLBARS: // lock the toolbars
LockUnlockToolbars(!fLocked);
LockUnlockToolbars(!pSettings->fLocked);
break;
case IDM_TOOLBARS_CUSTOMIZE: // customize
SendMessage(fToolbarWindow, TB_CUSTOMIZE, 0, 0);
@ -1850,7 +1842,7 @@ LRESULT CInternetToolbar::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
LRESULT CInternetToolbar::OnLDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
bHandled = FALSE;
if (fLocked)
if (pSettings->fLocked)
return 0;
if (wParam & MK_CONTROL)
@ -1928,3 +1920,11 @@ LRESULT CInternetToolbar::OnWinIniChange(UINT uMsg, WPARAM wParam, LPARAM lParam
return lres;
}
LRESULT CInternetToolbar::OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
/* Refresh toolbar locked state */
RefreshLockedToolbarState();
return 0;
}

View File

@ -92,6 +92,7 @@ public:
BOOL fSizing;
POINT fStartPosition;
LONG fStartHeight;
ShellSettings *pSettings;
public:
CInternetToolbar();
virtual ~CInternetToolbar();
@ -105,6 +106,7 @@ public:
HRESULT IsBandVisible(int BandID);
HRESULT ToggleBandVisibility(int BandID);
HRESULT SetState(const GUID *pguidCmdGroup, long commandID, OLECMD* pcmd);
void RefreshLockedToolbarState();
public:
// *** IInputObject specific methods ***
@ -200,6 +202,7 @@ public:
LRESULT OnLUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnWinIniChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
BEGIN_MSG_MAP(CInternetToolbar)
COMMAND_ID_HANDLER(IDM_GOTO_BACK, OnTravelBack)
@ -221,6 +224,7 @@ public:
MESSAGE_HANDLER(WM_LBUTTONUP, OnLUp)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_WININICHANGE, OnWinIniChange)
MESSAGE_HANDLER(BWM_SETTINGCHANGE, OnSettingsChange)
END_MSG_MAP()
DECLARE_REGISTRY_RESOURCEID(IDR_INTERNETTOOLBAR)

View File

@ -37,6 +37,10 @@
#include "resource.h"
#define BWM_SETTINGCHANGE (WM_USER + 300)
#define BWM_GETSETTINGSPTR (WM_USER + 301)
struct ShellSettings;
#include "ACLCustomMRU.h"
#include "aclhistory.h"
#include "aclistisf.h"
@ -65,4 +69,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(browseui);
struct ShellSettings
{
BOOL fLocked = FALSE;
BOOL fShowGoButton = FALSE;
BOOL fStatusBarVisible = FALSE;
BOOL Save();
BOOL Load();
};
#endif /* _BROWSEUI_PCH_ */

View File

@ -0,0 +1,36 @@
/*
* PROJECT: ReactOS browseui
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Stores settings for the file explorer UI.
* COPYRIGHT: Copyright 2023 Carl Bialorucki <cbialo2@outlook.com>
*/
#include "precomp.h"
BOOL ShellSettings::Save()
{
SHRegSetUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"StatusBarOther",
REG_DWORD, &fStatusBarVisible, sizeof(fStatusBarVisible), SHREGSET_FORCE_HKCU);
SHRegSetUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton",
REG_DWORD, &fShowGoButton, sizeof(fShowGoButton), SHREGSET_FORCE_HKCU);
SHRegSetUSValueW(L"Software\\Microsoft\\Internet Explorer\\Toolbar", L"Locked",
REG_DWORD, &fLocked, sizeof(fLocked), SHREGSET_FORCE_HKCU);
return TRUE;
}
BOOL ShellSettings::Load()
{
fStatusBarVisible = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main",
L"StatusBarOther", FALSE, FALSE);
fShowGoButton = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main",
L"ShowGoButton", FALSE, TRUE);
fLocked = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Toolbar",
L"Locked", FALSE, TRUE);
return TRUE;
}

View File

@ -292,7 +292,6 @@ private:
CComPtr<IShellView> fCurrentShellView; //
LPITEMIDLIST fCurrentDirectoryPIDL; //
HWND fStatusBar;
bool fStatusBarVisible;
CToolbarProxy fToolbarProxy;
barInfo fClientBars[3];
CComPtr<ITravelLog> fTravelLog;
@ -306,6 +305,7 @@ private:
IBindCtx *fHistoryBindContext;
HDSA menuDsa;
HACCEL m_hAccel;
ShellSettings m_settings;
public:
#if 0
ULONG InternalAddRef()
@ -350,7 +350,7 @@ public:
HRESULT UpdateUpState();
void UpdateGotoMenu(HMENU theMenu);
void UpdateViewMenu(HMENU theMenu);
void LoadSettings();
void LoadCabinetState();
/* // *** IDockingWindowFrame methods ***
virtual HRESULT STDMETHODCALLTYPE AddToolbar(IUnknown *punkSrc, LPCWSTR pwszItem, DWORD dwAddFlags);
@ -624,6 +624,8 @@ public:
LRESULT OnRefresh(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
LRESULT OnExplorerBar(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled);
LRESULT RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnGetSettingsPtr(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
HRESULT OnSearch();
static ATL::CWndClassInfo& GetWndClassInfo()
@ -674,6 +676,8 @@ public:
COMMAND_RANGE_HANDLER(IDM_GOTO_TRAVEL_FIRSTTARGET, IDM_GOTO_TRAVEL_LASTTARGET, OnGoTravel)
COMMAND_RANGE_HANDLER(IDM_EXPLORERBAND_BEGINCUSTOM, IDM_EXPLORERBAND_ENDCUSTOM, OnExplorerBar)
MESSAGE_HANDLER(WM_COMMAND, RelayCommands)
MESSAGE_HANDLER(BWM_SETTINGCHANGE, OnSettingsChange)
MESSAGE_HANDLER(BWM_GETSETTINGSPTR, OnGetSettingsPtr)
END_MSG_MAP()
BEGIN_CONNECTION_POINT_MAP(CShellBrowser)
@ -714,6 +718,7 @@ CShellBrowser::CShellBrowser()
fHistoryObject = NULL;
fHistoryStream = NULL;
fHistoryBindContext = NULL;
m_settings.Load();
}
CShellBrowser::~CShellBrowser()
@ -783,11 +788,11 @@ HRESULT CShellBrowser::Initialize()
fToolbarProxy.Initialize(m_hWnd, clientBar);
LoadSettings();
LoadCabinetState();
// create status bar
DWORD dwStatusStyle = WS_CHILD | WS_CLIPSIBLINGS | SBARS_SIZEGRIP | SBARS_TOOLTIPS;
if (fStatusBarVisible)
if (m_settings.fStatusBarVisible)
dwStatusStyle |= WS_VISIBLE;
fStatusBar = ::CreateWindowExW(0, STATUSCLASSNAMEW, NULL, dwStatusStyle,
0, 0, 500, 20, m_hWnd, (HMENU)IDC_STATUSBAR,
@ -1449,7 +1454,7 @@ void CShellBrowser::RepositionBars()
GetClientRect(&clientRect);
if (fStatusBarVisible && fStatusBar)
if (m_settings.fStatusBarVisible && fStatusBar)
{
::GetWindowRect(fStatusBar, &statusRect);
::SetWindowPos(fStatusBar, NULL, clientRect.left, clientRect.bottom - (statusRect.bottom - statusRect.top),
@ -1517,13 +1522,8 @@ void CShellBrowser::RepositionBars()
clientRect.bottom - clientRect.top, SWP_NOOWNERZORDER | SWP_NOZORDER);
}
void CShellBrowser::LoadSettings()
void CShellBrowser::LoadCabinetState()
{
fStatusBarVisible = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main",
L"StatusBarOther",
FALSE,
FALSE);
fCabinetState.fFullPathTitle = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CabinetState",
L"FullPath",
FALSE,
@ -1757,7 +1757,7 @@ void CShellBrowser::UpdateViewMenu(HMENU theMenu)
menuItemInfo.hSubMenu = toolbarMenu;
SetMenuItemInfo(theMenu, IDM_VIEW_TOOLBARS, FALSE, &menuItemInfo);
}
SHCheckMenuItem(theMenu, IDM_VIEW_STATUSBAR, fStatusBarVisible ? TRUE : FALSE);
SHCheckMenuItem(theMenu, IDM_VIEW_STATUSBAR, m_settings.fStatusBarVisible ? TRUE : FALSE);
}
HRESULT CShellBrowser::BuildExplorerBandMenu()
@ -3681,21 +3681,9 @@ LRESULT CShellBrowser::OnOrganizeFavorites(WORD wNotifyCode, WORD wID, HWND hWnd
LRESULT CShellBrowser::OnToggleStatusBarVisible(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
{
fStatusBarVisible = !fStatusBarVisible;
if (fStatusBar)
{
::ShowWindow(fStatusBar, fStatusBarVisible ? SW_SHOW : SW_HIDE);
RepositionBars();
}
DWORD dwStatusBarVisible = fStatusBarVisible;
SHRegSetUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main",
L"StatusBarOther",
REG_DWORD,
&dwStatusBarVisible,
sizeof(dwStatusBarVisible),
SHREGSET_FORCE_HKCU);
m_settings.fStatusBarVisible = !m_settings.fStatusBarVisible;
m_settings.Save();
SendMessageW(BWM_SETTINGCHANGE, 0, (LPARAM)&m_settings);
return 0;
}
@ -3800,6 +3788,30 @@ LRESULT CShellBrowser::RelayCommands(UINT uMsg, WPARAM wParam, LPARAM lParam, BO
return 0;
}
LRESULT CShellBrowser::OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
/* Refresh child windows */
::SendMessageW(fClientBars[BIInternetToolbar].hwnd, uMsg, wParam, lParam);
/* Refresh status bar */
if (fStatusBar)
{
::ShowWindow(fStatusBar, m_settings.fStatusBarVisible ? SW_SHOW : SW_HIDE);
RepositionBars();
}
return 0;
}
LRESULT CShellBrowser::OnGetSettingsPtr(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (!lParam)
return ERROR_INVALID_PARAMETER;
*(ShellSettings**)lParam = &m_settings;
return NO_ERROR;
}
HRESULT CShellBrowser_CreateInstance(REFIID riid, void **ppv)
{
return ShellObjectCreatorInit<CShellBrowser>(riid, ppv);