mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[BROWSEUI] Save/Restore ShellBrowser bar states (#7035)
Save/Restore the state of the ShellBrowser toolbar/addressbar/statusbar. Windows shares the state of the Go button and the locked state between Explorer and Internet Explorer but the bar states are not shared. Notes: - Seems to fix CORE-17236. - The stream layout does not match Windows so it uses a different name. The toolbar customize dialog needs to be fixed before it makes sense trying to save the toolbar state and the layout of other bands. CORE-17236
This commit is contained in:
parent
75db8c633a
commit
674136bcd0
6 changed files with 141 additions and 22 deletions
|
@ -75,6 +75,19 @@ TODO:
|
|||
|
||||
extern HRESULT WINAPI SHBindToFolder(LPCITEMIDLIST path, IShellFolder **newFolder);
|
||||
|
||||
struct ITBARSTATE
|
||||
{
|
||||
static const UINT SIG = ('R' << 0) | ('O' << 8) | ('S' << 16) | (('i' ^ 't' ^ 'b') << 24);
|
||||
UINT cbSize;
|
||||
UINT Signature; // Note: Windows has something else here (12 bytes)
|
||||
UINT StdToolbar : 1;
|
||||
UINT Addressbar : 1;
|
||||
UINT Linksbar : 1;
|
||||
UINT Throbber : 1; // toastytech.com/files/throboff.html
|
||||
UINT Menubar : 1; // ..\Explorer\Advanced\AlwaysShowMenus for NT6?
|
||||
// Note: Windows 8/10 stores the Ribbon state in ..\Explorer\Ribbon
|
||||
};
|
||||
|
||||
HRESULT IUnknown_RelayWinEvent(IUnknown * punk, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
|
||||
{
|
||||
CComPtr<IWinEventHandler> menuWinEventHandler;
|
||||
|
@ -614,6 +627,7 @@ CInternetToolbar::CInternetToolbar()
|
|||
fToolbarWindow = NULL;
|
||||
fAdviseCookie = 0;
|
||||
pSettings = NULL;
|
||||
fIgnoreChanges = FALSE;
|
||||
}
|
||||
|
||||
CInternetToolbar::~CInternetToolbar()
|
||||
|
@ -893,6 +907,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
|
|||
return hResult;
|
||||
}
|
||||
|
||||
#if 0 // Why should showing the IDockingWindow change all bands? Related to CORE-17236
|
||||
if (fMenuBar)
|
||||
{
|
||||
hResult = IUnknown_ShowDW(fMenuBar, fShow);
|
||||
|
@ -918,6 +933,7 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
|
|||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
}
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1001,6 +1017,14 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::GetClassID(CLSID *pClassID)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInternetToolbar::SetDirty()
|
||||
{
|
||||
if (fIgnoreChanges)
|
||||
return S_OK;
|
||||
IUnknown_Exec(fSite, CGID_ShellBrowser, IDM_NOTIFYITBARDIRTY, 0, NULL, NULL);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
|
@ -1008,12 +1032,35 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::IsDirty()
|
|||
|
||||
HRESULT STDMETHODCALLTYPE CInternetToolbar::Load(IStream *pStm)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
fIgnoreChanges = TRUE;
|
||||
HRESULT hr = InitNew();
|
||||
ITBARSTATE state;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = S_FALSE;
|
||||
ULONG cb = sizeof(state);
|
||||
if (pStm->Read(&state, cb, &cb) == S_OK && state.Signature == state.SIG)
|
||||
{
|
||||
SetBandVisibility(ITBBID_MENUBAND, state.Menubar);
|
||||
SetBandVisibility(ITBBID_TOOLSBAND, state.StdToolbar);
|
||||
SetBandVisibility(ITBBID_ADDRESSBAND, state.Addressbar);
|
||||
//SetBandVisibility(ITBBID_?, state.Linksbar);
|
||||
//SetBandVisibility(ITBBID_?, state.Throbber);
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
fIgnoreChanges = FALSE;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CInternetToolbar::Save(IStream *pStm, BOOL fClearDirty)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
ITBARSTATE state = { sizeof(state), state.SIG };
|
||||
state.Menubar = IsBandVisible(ITBBID_MENUBAND) == S_OK;
|
||||
state.StdToolbar = IsBandVisible(ITBBID_TOOLSBAND) == S_OK;
|
||||
state.Addressbar = IsBandVisible(ITBBID_ADDRESSBAND) == S_OK;
|
||||
state.Linksbar = FALSE;
|
||||
return pStm->Write(&state, sizeof(state), NULL);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CInternetToolbar::GetSizeMax(ULARGE_INTEGER *pcbSize)
|
||||
|
@ -1080,24 +1127,34 @@ HRESULT CInternetToolbar::IsBandVisible(int BandID)
|
|||
return (bandInfo.fStyle & RBBS_HIDDEN) ? S_FALSE : S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInternetToolbar::ToggleBandVisibility(int BandID)
|
||||
HRESULT CInternetToolbar::SetBandVisibility(int BandID, int Show)
|
||||
{
|
||||
int index = (int)SendMessage(fMainReBar, RB_IDTOINDEX, BandID, 0);
|
||||
REBARBANDINFOW bandInfo = {sizeof(REBARBANDINFOW), RBBIM_STYLE | RBBIM_CHILD};
|
||||
if (!SendMessage(fMainReBar, RB_GETBANDINFOW, index, (LPARAM)&bandInfo))
|
||||
return E_FAIL;
|
||||
|
||||
REBARBANDINFOW bandInfo = {sizeof(REBARBANDINFOW), RBBIM_STYLE};
|
||||
SendMessage(fMainReBar, RB_GETBANDINFOW, index, (LPARAM)&bandInfo);
|
||||
|
||||
if (bandInfo.fStyle & RBBS_HIDDEN)
|
||||
if (Show < 0)
|
||||
bandInfo.fStyle ^= RBBS_HIDDEN; // Toggle
|
||||
else if (Show)
|
||||
bandInfo.fStyle &= ~RBBS_HIDDEN;
|
||||
else
|
||||
bandInfo.fStyle |= RBBS_HIDDEN;
|
||||
|
||||
bandInfo.fMask &= ~RBBIM_CHILD;
|
||||
::ShowWindow(bandInfo.hwndChild, (bandInfo.fStyle & RBBS_HIDDEN) ? SW_HIDE : SW_SHOW); // CORE-17236
|
||||
SendMessage(fMainReBar, RB_SETBANDINFOW, index, (LPARAM)&bandInfo);
|
||||
|
||||
ReserveBorderSpace(0);
|
||||
SetDirty();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInternetToolbar::ToggleBandVisibility(int BandID)
|
||||
{
|
||||
return SetBandVisibility(BandID, -1);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CInternetToolbar::QueryStatus(const GUID *pguidCmdGroup,
|
||||
ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
|
||||
{
|
||||
|
@ -1685,7 +1742,6 @@ LRESULT CInternetToolbar::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
|
|||
if (hitTestInfo.iBand == -1)
|
||||
return 0;
|
||||
|
||||
pSettings->Load();
|
||||
rebarBandInfo.cbSize = sizeof(rebarBandInfo);
|
||||
rebarBandInfo.fMask = RBBIM_ID;
|
||||
SendMessage(fMainReBar, RB_GETBANDINFOW, hitTestInfo.iBand, (LPARAM)&rebarBandInfo);
|
||||
|
@ -1930,3 +1986,19 @@ LRESULT CInternetToolbar::OnSettingsChange(UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CInternetToolbar::GetStream(UINT StreamFor, DWORD Stgm, IStream **ppS)
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
LPCWSTR subkey = NULL;
|
||||
switch (StreamFor)
|
||||
{
|
||||
case ITBARSTREAM_SHELLBROWSER: subkey = L"ShellBrowser"; break;
|
||||
case ITBARSTREAM_WEBBROWSER: subkey = L"WebBrowser"; break;
|
||||
case ITBARSTREAM_EXPLORER: subkey = L"Explorer"; break;
|
||||
default: return E_INVALIDARG;
|
||||
}
|
||||
wsprintfW(path, L"Software\\Microsoft\\Internet Explorer\\Toolbar\\%s", subkey);
|
||||
*ppS = SHOpenRegStream2W(HKEY_CURRENT_USER, path, L"RosITBarLayout", Stgm); // ROS prefix until we figure out the correct format
|
||||
return *ppS ? S_OK : E_FAIL;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#define ITBARSTREAM_SHELLBROWSER 0
|
||||
#define ITBARSTREAM_WEBBROWSER 1
|
||||
#define ITBARSTREAM_EXPLORER 2
|
||||
|
||||
static const int gSearchCommandID = 1003;
|
||||
static const int gFoldersCommandID = 1004;
|
||||
static const int gMoveToCommandID = FCIDM_SHVIEW_MOVETO;
|
||||
|
@ -93,6 +97,7 @@ public:
|
|||
POINT fStartPosition;
|
||||
LONG fStartHeight;
|
||||
ShellSettings *pSettings;
|
||||
BOOL fIgnoreChanges;
|
||||
public:
|
||||
CInternetToolbar();
|
||||
virtual ~CInternetToolbar();
|
||||
|
@ -104,9 +109,13 @@ public:
|
|||
HRESULT CommandStateChanged(bool newValue, int commandID);
|
||||
HRESULT CreateAndInitBandProxy();
|
||||
HRESULT IsBandVisible(int BandID);
|
||||
HRESULT SetBandVisibility(int BandID, int Show);
|
||||
HRESULT ToggleBandVisibility(int BandID);
|
||||
HRESULT SetState(const GUID *pguidCmdGroup, long commandID, OLECMD* pcmd);
|
||||
void RefreshLockedToolbarState();
|
||||
HRESULT SetDirty();
|
||||
|
||||
static HRESULT GetStream(UINT StreamFor, DWORD Stgm, IStream **ppS);
|
||||
|
||||
public:
|
||||
// *** IInputObject specific methods ***
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
|
||||
/* Random id for band close button, feel free to change it */
|
||||
#define IDM_BASEBAR_CLOSE 0xA200
|
||||
#define IDM_NOTIFYITBARDIRTY 0xA239 /* Arbitrary id */
|
||||
|
||||
/* User-installed explorer band IDs according to API Monitor traces */
|
||||
#define IDM_EXPLORERBAND_BEGINCUSTOM 0xA240
|
||||
|
|
|
@ -35,6 +35,7 @@ void ShellSettings::Load()
|
|||
|
||||
void CabinetStateSettings::Load()
|
||||
{
|
||||
this->cLength = sizeof(CABINETSTATE);
|
||||
ReadCabinetState(this, this->cLength);
|
||||
|
||||
/* Overrides */
|
||||
|
|
|
@ -351,8 +351,10 @@ public:
|
|||
HRESULT UpdateUpState();
|
||||
void UpdateGotoMenu(HMENU theMenu);
|
||||
void UpdateViewMenu(HMENU theMenu);
|
||||
HRESULT IsInternetToolbarBandShown(UINT ITId);
|
||||
void RefreshCabinetState();
|
||||
void UpdateWindowTitle();
|
||||
void SaveITBarLayout();
|
||||
|
||||
/* // *** IDockingWindowFrame methods ***
|
||||
STDMETHOD(AddToolbar)(IUnknown *punkSrc, LPCWSTR pwszItem, DWORD dwAddFlags) override;
|
||||
|
@ -771,19 +773,11 @@ HRESULT CShellBrowser::Initialize()
|
|||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
|
||||
// TODO: create settingsStream from registry entry
|
||||
//if (settingsStream.p)
|
||||
//{
|
||||
// hResult = persistStreamInit->Load(settingsStream);
|
||||
// if (FAILED_UNEXPECTEDLY(hResult))
|
||||
// return hResult;
|
||||
//}
|
||||
//else
|
||||
{
|
||||
hResult = persistStreamInit->InitNew();
|
||||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
}
|
||||
CComPtr<IStream> pITBarStream;
|
||||
hResult = CInternetToolbar::GetStream(ITBARSTREAM_EXPLORER, STGM_READ, &pITBarStream);
|
||||
hResult = SUCCEEDED(hResult) ? persistStreamInit->Load(pITBarStream) : persistStreamInit->InitNew();
|
||||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
return hResult;
|
||||
|
||||
hResult = IUnknown_ShowDW(clientBar, TRUE);
|
||||
if (FAILED_UNEXPECTEDLY(hResult))
|
||||
|
@ -2136,6 +2130,9 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::Exec(const GUID *pguidCmdGroup, DWORD n
|
|||
{
|
||||
case 40994:
|
||||
return NavigateToParent();
|
||||
case IDM_NOTIFYITBARDIRTY:
|
||||
SaveITBarLayout();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (IsEqualIID(*pguidCmdGroup, CGID_IExplorerToolbar))
|
||||
|
@ -2383,7 +2380,7 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::QueryService(REFGUID guidService, REFII
|
|||
return this->QueryInterface(riid, ppvObject);
|
||||
if (IsEqualIID(guidService, SID_SProxyBrowser))
|
||||
return this->QueryInterface(riid, ppvObject);
|
||||
if (IsEqualIID(guidService, SID_IExplorerToolbar))
|
||||
if (IsEqualIID(guidService, SID_IExplorerToolbar) && fClientBars[BIInternetToolbar].clientBar.p)
|
||||
return fClientBars[BIInternetToolbar].clientBar->QueryInterface(riid, ppvObject);
|
||||
if (IsEqualIID(riid, IID_IShellBrowser))
|
||||
return this->QueryInterface(riid, ppvObject);
|
||||
|
@ -2495,6 +2492,9 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::ShowControlWindow(UINT id, BOOL fShow)
|
|||
return S_OK;
|
||||
case FCW_TREE:
|
||||
return Exec(&CGID_Explorer, SBCMDID_EXPLORERBARFOLDERS, 0, NULL, NULL);
|
||||
case FCW_ADDRESSBAR:
|
||||
return IUnknown_Exec(fClientBars[BIInternetToolbar].clientBar,
|
||||
CGID_PrivCITCommands, ITID_ADDRESSBANDSHOWN, 0, NULL, NULL);
|
||||
}
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
@ -2515,6 +2515,10 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::IsControlWindowShown(UINT id, BOOL *pfS
|
|||
shown = cmd.cmdf & OLECMDF_LATCHED;
|
||||
break;
|
||||
}
|
||||
case FCW_ADDRESSBAR:
|
||||
hr = IsInternetToolbarBandShown(ITID_ADDRESSBANDSHOWN);
|
||||
shown = hr == S_OK;
|
||||
break;
|
||||
default:
|
||||
hr = E_NOTIMPL;
|
||||
}
|
||||
|
@ -2526,6 +2530,14 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::IsControlWindowShown(UINT id, BOOL *pfS
|
|||
return SUCCEEDED(hr) ? (shown ? S_OK : S_FALSE) : hr;
|
||||
}
|
||||
|
||||
HRESULT CShellBrowser::IsInternetToolbarBandShown(UINT ITId)
|
||||
{
|
||||
OLECMD cmd = { ITId };
|
||||
HRESULT hr = IUnknown_QueryStatus(fClientBars[BIInternetToolbar].clientBar,
|
||||
CGID_PrivCITCommands, 1, &cmd, NULL);
|
||||
return SUCCEEDED(hr) ? (cmd.cmdf & OLECMDF_LATCHED) ? S_OK : S_FALSE : hr;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE CShellBrowser::IEGetDisplayName(LPCITEMIDLIST pidl, LPWSTR pwszName, UINT uFlags)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
|
@ -3986,3 +3998,25 @@ void CShellBrowser::UpdateWindowTitle()
|
|||
if (SUCCEEDED(IEGetNameAndFlags(fCurrentDirectoryPIDL, flags, title, _countof(title), NULL)))
|
||||
SetWindowText(title);
|
||||
}
|
||||
|
||||
void CShellBrowser::SaveITBarLayout()
|
||||
{
|
||||
if (!gCabinetState.fSaveLocalView)
|
||||
return;
|
||||
#if 0 // If CDesktopBrowser aggregates us, skip saving
|
||||
FOLDERSETTINGS fs;
|
||||
if (fCurrentShellView && SUCCEEDED(fCurrentShellView->GetCurrentInfo(&fs)) && (fs.fFlags & FWF_DESKTOP))
|
||||
return;
|
||||
#endif
|
||||
|
||||
CComPtr<IPersistStreamInit> pPSI;
|
||||
CComPtr<IStream> pITBarStream;
|
||||
if (!fClientBars[BIInternetToolbar].clientBar.p)
|
||||
return;
|
||||
HRESULT hr = fClientBars[BIInternetToolbar].clientBar->QueryInterface(IID_PPV_ARG(IPersistStreamInit, &pPSI));
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
if (FAILED(hr = CInternetToolbar::GetStream(ITBARSTREAM_EXPLORER, STGM_WRITE, &pITBarStream)))
|
||||
return;
|
||||
pPSI->Save(pITBarStream, TRUE);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
extern "C" {
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#define FCW_ADDRESSBAR 9 // GetControlWindow/IsControlWindowShown
|
||||
|
||||
// Name is IETHREADPARAM according to symbols / mangled function names
|
||||
#ifdef _WIN64
|
||||
typedef struct IEThreadParamBlock
|
||||
|
|
Loading…
Reference in a new issue