From c97c1ad4c56bcd6dc21355cc9d99e96e9ba2b825 Mon Sep 17 00:00:00 2001 From: Whindmar Saksit Date: Tue, 4 Jun 2024 18:37:19 +0200 Subject: [PATCH] [SHELL32][BROWSEUI] Implement ShellBrowser Apply/Reset default folder settings (#6912) --- dll/win32/browseui/globalfoldersettings.cpp | 126 +++++++++++++++++++- dll/win32/browseui/globalfoldersettings.h | 23 +++- dll/win32/browseui/settings.cpp | 2 +- dll/win32/browseui/settings.h | 7 +- dll/win32/browseui/shellbrowser.cpp | 50 ++++++-- dll/win32/shell32/CDefView.cpp | 21 +++- dll/win32/shell32/CFolderOptions.cpp | 52 +++++++- dll/win32/shell32/CFolderOptions.h | 13 ++ dll/win32/shell32/dialogs/view.cpp | 26 +++- dll/win32/shell32/precomp.h | 1 + sdk/include/reactos/shellutils.h | 30 +++++ sdk/include/reactos/shlobj_undoc.h | 26 +++- 12 files changed, 339 insertions(+), 38 deletions(-) diff --git a/dll/win32/browseui/globalfoldersettings.cpp b/dll/win32/browseui/globalfoldersettings.cpp index 1504446bf09..2c1fd6c502b 100644 --- a/dll/win32/browseui/globalfoldersettings.cpp +++ b/dll/win32/browseui/globalfoldersettings.cpp @@ -20,6 +20,52 @@ #include "precomp.h" +#define DEFBROWSERSTREAM L"Settings" +#define DEFAULT_VID GUID_NULL // We don't support WebView +#define CURRENT_VERSION ( DEFFOLDERSETTINGS::VER_XP ) + +template static void CopyTo(const S &Src, D &Dst) +{ + Dst.FolderSettings = Src.FolderSettings; +} + +static void EnsureValid(FOLDERSETTINGS &fs) +{ + if ((int)fs.ViewMode < FVM_AUTO || (int)fs.ViewMode > FVM_LAST) + fs.ViewMode = SBFOLDERSETTINGS::DEF_FVM; + + fs.fFlags &= ~(FWF_OWNERDATA | FWF_DESKTOP | FWF_TRANSPARENT | FWF_NOCLIENTEDGE | + FWF_NOSUBFOLDERS | FWF_NOSCROLL | FWF_NOENUMREFRESH | FWF_NOVISIBLE); +} + +static void EnsureValid(DEFFOLDERSETTINGS &dfs) +{ + EnsureValid(dfs.FolderSettings); +} + +static void InitializeDefaults(DEFFOLDERSETTINGS &dfs) +{ + C_ASSERT(FIELD_OFFSET(DEFFOLDERSETTINGS, FolderSettings) == 4); + C_ASSERT(FIELD_OFFSET(DEFFOLDERSETTINGS, ViewPriority) == DEFFOLDERSETTINGS::SIZE_IE4); + C_ASSERT(sizeof(DEFFOLDERSETTINGS) == DEFFOLDERSETTINGS::SIZE_XP); + + *(UINT*)&dfs = FALSE; // Set all unknown flags to FALSE + dfs.Statusbar = TRUE; + dfs.FolderSettings.ViewMode = SBFOLDERSETTINGS::DEF_FVM; + dfs.FolderSettings.fFlags = SBFOLDERSETTINGS::DEF_FWF; + dfs.vid = DEFAULT_VID; + dfs.Version = CURRENT_VERSION; + dfs.Counter = 0; + dfs.ViewPriority = VIEW_PRIORITY_CACHEMISS; +} + +void SBFOLDERSETTINGS::Load() +{ + DEFFOLDERSETTINGS dfs; + CGlobalFolderSettings::Load(dfs); + CopyTo(dfs, *this); +} + CGlobalFolderSettings::CGlobalFolderSettings() { } @@ -28,13 +74,83 @@ CGlobalFolderSettings::~CGlobalFolderSettings() { } -HRESULT STDMETHODCALLTYPE CGlobalFolderSettings::Get(DEFFOLDERSETTINGS *paramC, int param10) +HRESULT CGlobalFolderSettings::ResetBrowserSettings() { - return E_NOTIMPL; + return Save(NULL); } -HRESULT STDMETHODCALLTYPE CGlobalFolderSettings::Set( - const DEFFOLDERSETTINGS *paramC, int param10, unsigned int param14) +HRESULT CGlobalFolderSettings::SaveBrowserSettings(const SBFOLDERSETTINGS &sbfs) { - return E_NOTIMPL; + DEFFOLDERSETTINGS dfs; + InitializeDefaults(dfs); + CopyTo(sbfs, dfs); + return Save(&dfs); +} + +HRESULT CGlobalFolderSettings::Load(DEFFOLDERSETTINGS &dfs) +{ + HKEY hStreamsKey = SHGetShellKey(SHKEY_Key_Explorer, L"Streams", FALSE); + if (hStreamsKey) + { + DWORD cb = sizeof(DEFFOLDERSETTINGS); + DWORD err = SHRegGetValueW(hStreamsKey, NULL, DEFBROWSERSTREAM, + SRRF_RT_REG_BINARY, NULL, &dfs, &cb); + RegCloseKey(hStreamsKey); + if (!err && cb >= DEFFOLDERSETTINGS::SIZE_NT4) + { + if (cb < FIELD_OFFSET(DEFFOLDERSETTINGS, vid)) + { + dfs.FolderSettings.fFlags = SBFOLDERSETTINGS::DEF_FWF; + } + if (cb < FIELD_OFFSET(DEFFOLDERSETTINGS, Version)) + { + dfs.vid = DEFAULT_VID; + } + if (cb <= FIELD_OFFSET(DEFFOLDERSETTINGS, ViewPriority)) + { + dfs.Version = CURRENT_VERSION; + } + dfs.ViewPriority = VIEW_PRIORITY_STALECACHEHIT; + EnsureValid(dfs); + return S_OK; + } + } + InitializeDefaults(dfs); + return S_FALSE; +} + +HRESULT CGlobalFolderSettings::Save(const DEFFOLDERSETTINGS *pFDS) +{ + HKEY hStreamsKey = SHGetShellKey(SHKEY_Key_Explorer, L"Streams", TRUE); + if (!hStreamsKey) + return E_FAIL; + + HRESULT hr = E_INVALIDARG; + if (!pFDS) + { + DWORD err = SHDeleteValueW(hStreamsKey, NULL, DEFBROWSERSTREAM); + hr = (!err || err == ERROR_FILE_NOT_FOUND) ? S_OK : HResultFromWin32(err); + } + else + { + DWORD cb = sizeof(DEFFOLDERSETTINGS); + hr = HResultFromWin32(SHSetValueW(hStreamsKey, NULL, DEFBROWSERSTREAM, REG_BINARY, pFDS, cb)); + } + RegCloseKey(hStreamsKey); + return hr; +} + +HRESULT STDMETHODCALLTYPE CGlobalFolderSettings::Get(struct DEFFOLDERSETTINGS *pFDS, UINT cb) +{ + if (cb != sizeof(DEFFOLDERSETTINGS) || !pFDS) + return E_INVALIDARG; + return Load(*pFDS); +} + +HRESULT STDMETHODCALLTYPE CGlobalFolderSettings::Set(const struct DEFFOLDERSETTINGS *pFDS, UINT cb, UINT unknown) +{ + // NULL pFDS means reset + if (cb != sizeof(DEFFOLDERSETTINGS) && pFDS) + return E_INVALIDARG; + return Save(pFDS); } diff --git a/dll/win32/browseui/globalfoldersettings.h b/dll/win32/browseui/globalfoldersettings.h index 009e0264f3e..85e88459758 100644 --- a/dll/win32/browseui/globalfoldersettings.h +++ b/dll/win32/browseui/globalfoldersettings.h @@ -20,6 +20,20 @@ #pragma once +struct SBFOLDERSETTINGS // Private version of DEFFOLDERSETTINGS used by CShellBrowser +{ + FOLDERSETTINGS FolderSettings; + + enum { DEF_FVM = FVM_DETAILS }; // Windows uses FVM_ICON? + enum { DEF_FWF = FWF_NOHEADERINALLVIEWS }; + void InitializeDefaults() + { + FolderSettings.ViewMode = DEF_FVM; + FolderSettings.fFlags = DEF_FWF; + } + void Load(); +}; + class CGlobalFolderSettings : public CComCoClass, public CComObjectRootEx, @@ -30,9 +44,14 @@ public: CGlobalFolderSettings(); ~CGlobalFolderSettings(); + static HRESULT ResetBrowserSettings(); + static HRESULT SaveBrowserSettings(const SBFOLDERSETTINGS &sbfs); + static HRESULT Load(DEFFOLDERSETTINGS &dfs); + static HRESULT Save(const DEFFOLDERSETTINGS *pFDS); + // *** IGlobalFolderSettings methods *** - STDMETHOD(Get)(DEFFOLDERSETTINGS *paramC, int param10) override; - STDMETHOD(Set)(const DEFFOLDERSETTINGS *paramC, int param10, unsigned int param14) override; + STDMETHOD(Get)(struct DEFFOLDERSETTINGS *pFDS, UINT cb) override; + STDMETHOD(Set)(const struct DEFFOLDERSETTINGS *pFDS, UINT cb, UINT unknown) override; DECLARE_REGISTRY_RESOURCEID(IDR_GLOBALFOLDERSETTINGS) DECLARE_NOT_AGGREGATABLE(CGlobalFolderSettings) diff --git a/dll/win32/browseui/settings.cpp b/dll/win32/browseui/settings.cpp index 65af70c950e..0c0cf45b94d 100644 --- a/dll/win32/browseui/settings.cpp +++ b/dll/win32/browseui/settings.cpp @@ -24,7 +24,7 @@ void ShellSettings::Save() void ShellSettings::Load() { fStatusBarVisible = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", - L"StatusBarOther", FALSE, FALSE); + L"StatusBarOther", FALSE, TRUE); fShowGoButton = SHRegGetBoolUSValueW(L"Software\\Microsoft\\Internet Explorer\\Main", L"ShowGoButton", FALSE, TRUE); diff --git a/dll/win32/browseui/settings.h b/dll/win32/browseui/settings.h index 38e58c1fe99..993fb05bf01 100644 --- a/dll/win32/browseui/settings.h +++ b/dll/win32/browseui/settings.h @@ -12,12 +12,13 @@ struct ShellSettings { - BOOL fLocked = FALSE; - BOOL fShowGoButton = FALSE; - BOOL fStatusBarVisible = FALSE; + BOOL fLocked = TRUE; + BOOL fShowGoButton = TRUE; + BOOL fStatusBarVisible = TRUE; void Save(); void Load(); + void Reset() { ShellSettings().Save(); } }; struct CabinetStateSettings : CABINETSTATE diff --git a/dll/win32/browseui/shellbrowser.cpp b/dll/win32/browseui/shellbrowser.cpp index 28235334483..38ab15e1535 100644 --- a/dll/win32/browseui/shellbrowser.cpp +++ b/dll/win32/browseui/shellbrowser.cpp @@ -305,6 +305,7 @@ private: HDSA menuDsa; HACCEL m_hAccel; ShellSettings m_settings; + SBFOLDERSETTINGS m_deffoldersettings; public: #if 0 ULONG InternalAddRef() @@ -332,6 +333,7 @@ public: HRESULT ShowBand(const CLSID &classID, bool vertical); HRESULT NavigateToParent(); HRESULT DoFolderOptions(); + HRESULT ApplyBrowserDefaultFolderSettings(IShellView *pvs); static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void RepositionBars(); HRESULT BuildExplorerBandMenu(); @@ -723,6 +725,7 @@ CShellBrowser::CShellBrowser() fHistoryStream = NULL; fHistoryBindContext = NULL; m_settings.Load(); + m_deffoldersettings.Load(); gCabinetState.Load(); } @@ -802,13 +805,35 @@ HRESULT CShellBrowser::Initialize() return S_OK; } +HRESULT CShellBrowser::ApplyBrowserDefaultFolderSettings(IShellView *pvs) +{ + HRESULT hr; + if (pvs) + { + m_settings.Save(); + SBFOLDERSETTINGS &sbfs = m_deffoldersettings, defsbfs; + if (FAILED(pvs->GetCurrentInfo(&sbfs.FolderSettings))) + { + defsbfs.InitializeDefaults(); + sbfs = defsbfs; + } + hr = CGlobalFolderSettings::SaveBrowserSettings(sbfs); + } + else + { + m_settings.Reset(); + hr = CGlobalFolderSettings::ResetBrowserSettings(); + } + return hr; +} + HRESULT CShellBrowser::BrowseToPIDL(LPCITEMIDLIST pidl, long flags) { - CComPtr newFolder; - FOLDERSETTINGS newFolderSettings; - HRESULT hResult; - CLSID clsid; - BOOL HasIconViewType; + CComPtr newFolder; + FOLDERSETTINGS newFolderSettings = m_deffoldersettings.FolderSettings; + HRESULT hResult; + CLSID clsid; + BOOL HasIconViewType; // called by shell view to browse to new folder // also called by explorer band to navigate to new folder @@ -822,9 +847,6 @@ HRESULT CShellBrowser::BrowseToPIDL(LPCITEMIDLIST pidl, long flags) if (HasIconViewType) newFolderSettings.ViewMode = FVM_ICON; - else - newFolderSettings.ViewMode = FVM_DETAILS; - newFolderSettings.fFlags = 0; hResult = BrowseToPath(newFolder, pidl, &newFolderSettings, flags); if (FAILED_UNEXPECTEDLY(hResult)) return hResult; @@ -2128,8 +2150,8 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::Exec(const GUID *pguidCmdGroup, DWORD n { switch (nCmdID) { - case 1: - // Reset All Folders option in Folder Options + case DVCMDID_RESET_DEFAULTFOLDER_SETTINGS: + IUnknown_Exec(fCurrentShellView, CGID_DefView, nCmdID, OLECMDEXECOPT_DODEFAULT, NULL, NULL); break; } } @@ -2644,7 +2666,13 @@ LRESULT STDMETHODCALLTYPE CShellBrowser::WndProcBS(HWND hwnd, UINT uMsg, WPARAM HRESULT STDMETHODCALLTYPE CShellBrowser::SetAsDefFolderSettings() { - return E_NOTIMPL; + HRESULT hr = E_FAIL; + if (fCurrentShellView) + { + hr = ApplyBrowserDefaultFolderSettings(fCurrentShellView); + IUnknown_Exec(fCurrentShellView, CGID_DefView, DVCMDID_SET_DEFAULTFOLDER_SETTINGS, OLECMDEXECOPT_DODEFAULT, NULL, NULL); + } + return hr; } HRESULT STDMETHODCALLTYPE CShellBrowser::GetViewRect(RECT *prc) diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp index fa5cc407093..75dac299e7f 100644 --- a/dll/win32/shell32/CDefView.cpp +++ b/dll/win32/shell32/CDefView.cpp @@ -2451,9 +2451,7 @@ SelectExtOnRename(void) LONG error; DWORD dwValue = FALSE, cbValue; - error = RegOpenKeyExW(HKEY_CURRENT_USER, - L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer", - 0, KEY_READ, &hKey); + error = RegOpenKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_EXPLORER, 0, KEY_READ, &hKey); if (error) return dwValue; @@ -3792,6 +3790,23 @@ HRESULT WINAPI CDefView::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCm (nCmdexecopt == 0)) return 1; + if (IsEqualIID(*pguidCmdGroup, CGID_DefView)) + { + WCHAR SubKey[MAX_PATH]; + switch (nCmdID) + { + case DVCMDID_SET_DEFAULTFOLDER_SETTINGS: + SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\ShellNoRoam\\Bags"); + FIXME("Save current as default\n"); + break; + case DVCMDID_RESET_DEFAULTFOLDER_SETTINGS: + wsprintfW(SubKey, L"%s\\%s", REGSTR_PATH_EXPLORER, L"Streams\\Default"); + SHDeleteKey(HKEY_CURRENT_USER, SubKey); + SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\ShellNoRoam\\Bags"); + break; + } + } + return OLECMDERR_E_UNKNOWNGROUP; } diff --git a/dll/win32/shell32/CFolderOptions.cpp b/dll/win32/shell32/CFolderOptions.cpp index 3c0428af9b3..ba436c938fc 100644 --- a/dll/win32/shell32/CFolderOptions.cpp +++ b/dll/win32/shell32/CFolderOptions.cpp @@ -19,6 +19,7 @@ */ #include +#include WINE_DEFAULT_DEBUG_CHANNEL(fprop); @@ -42,8 +43,10 @@ INT_PTR CALLBACK FolderOptionsFileTypesDlg(HWND hwndDlg, UINT uMsg, WPARAM wPara HRESULT STDMETHODCALLTYPE CFolderOptions::AddPages(LPFNSVADDPROPSHEETPAGE pfnAddPage, LPARAM lParam) { - HPROPSHEETPAGE hPage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL, FolderOptionsGeneralDlg, 0, NULL); + HPROPSHEETPAGE hPage; + LPARAM sheetparam = (LPARAM)static_cast(this); + hPage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL, FolderOptionsGeneralDlg, sheetparam, NULL); if (hPage == NULL) { ERR("Failed to create property sheet page FolderOptionsGeneral\n"); @@ -52,7 +55,7 @@ HRESULT STDMETHODCALLTYPE CFolderOptions::AddPages(LPFNSVADDPROPSHEETPAGE pfnAdd if (!pfnAddPage(hPage, lParam)) return E_FAIL; - hPage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW, FolderOptionsViewDlg, 0, NULL); + hPage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW, FolderOptionsViewDlg, sheetparam, NULL); if (hPage == NULL) { ERR("Failed to create property sheet page FolderOptionsView\n"); @@ -61,7 +64,7 @@ HRESULT STDMETHODCALLTYPE CFolderOptions::AddPages(LPFNSVADDPROPSHEETPAGE pfnAdd if (!pfnAddPage(hPage, lParam)) return E_FAIL; - hPage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES, FolderOptionsFileTypesDlg, 0, NULL); + hPage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES, FolderOptionsFileTypesDlg, sheetparam, NULL); if (hPage == NULL) { ERR("Failed to create property sheet page FolderOptionsFileTypes\n"); @@ -90,7 +93,7 @@ HRESULT STDMETHODCALLTYPE CFolderOptions::Initialize(PCIDLIST_ABSOLUTE pidlFolde /************************************************************************* - * FolderOptions IShellExtInit interface + * FolderOptions IObjectWithSite interface */ HRESULT STDMETHODCALLTYPE CFolderOptions::SetSite(IUnknown *pUnkSite) { @@ -100,6 +103,45 @@ HRESULT STDMETHODCALLTYPE CFolderOptions::SetSite(IUnknown *pUnkSite) HRESULT STDMETHODCALLTYPE CFolderOptions::GetSite(REFIID riid, void **ppvSite) { - return m_pSite->QueryInterface(riid, ppvSite); + return m_pSite ? m_pSite->QueryInterface(riid, ppvSite) : E_FAIL; } +/************************************************************************* + * FolderOptions helper methods + */ +HRESULT CFolderOptions::HandleDefFolderSettings(int Action) +{ + IBrowserService2 *bs2; + HRESULT hr = IUnknown_QueryService(m_pSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService2, &bs2)); + if (SUCCEEDED(hr)) + { + if (Action == DFSA_APPLY) + { + hr = bs2->SetAsDefFolderSettings(); + } + else if (Action == DFSA_RESET) + { + // There does not seem to be a method in IBrowserService2 for this + IUnknown_Exec(bs2, CGID_DefView, DVCMDID_RESET_DEFAULTFOLDER_SETTINGS, OLECMDEXECOPT_DODEFAULT, NULL, NULL); + } + else + { + // FFSA_QUERY: hr is already correct + } + bs2->Release(); + } + + if (Action == DFSA_RESET) + { + IGlobalFolderSettings *pgfs; + HRESULT hr = CoCreateInstance(CLSID_GlobalFolderSettings, NULL, CLSCTX_INPROC_SERVER, + IID_IGlobalFolderSettings, (void **)&pgfs); + if (SUCCEEDED(hr)) + { + hr = pgfs->Set(NULL, 0, 0); + pgfs->Release(); + } + } + + return hr; +} diff --git a/dll/win32/shell32/CFolderOptions.h b/dll/win32/shell32/CFolderOptions.h index 8f023768a75..3bb8f2973d9 100644 --- a/dll/win32/shell32/CFolderOptions.h +++ b/dll/win32/shell32/CFolderOptions.h @@ -38,6 +38,10 @@ class CFolderOptions : //BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect); //BOOL RecycleBinIsEmpty(); + protected: + enum DEFFOLDERSETTINGACTION { DFSA_QUERY = -1, DFSA_RESET, DFSA_APPLY }; + HRESULT HandleDefFolderSettings(int Action); + public: CFolderOptions(); ~CFolderOptions(); @@ -53,6 +57,15 @@ class CFolderOptions : STDMETHOD(SetSite)(IUnknown *pUnkSite) override; STDMETHOD(GetSite)(REFIID riid, void **ppvSite) override; + bool CanSetDefFolderSettings() + { + return SUCCEEDED(HandleDefFolderSettings(DFSA_QUERY)); + } + HRESULT ApplyDefFolderSettings(bool ResetToDefault) + { + return HandleDefFolderSettings(ResetToDefault ? DFSA_RESET : DFSA_APPLY); + } + DECLARE_REGISTRY_RESOURCEID(IDR_FOLDEROPTIONS) DECLARE_NOT_AGGREGATABLE(CFolderOptions) diff --git a/dll/win32/shell32/dialogs/view.cpp b/dll/win32/shell32/dialogs/view.cpp index e8603d345d3..e24435e6b9b 100644 --- a/dll/win32/shell32/dialogs/view.cpp +++ b/dll/win32/shell32/dialogs/view.cpp @@ -618,8 +618,18 @@ ViewDlg_CreateTreeImageList(VOID) } static BOOL -ViewDlg_OnInitDialog(HWND hwndDlg) +ViewDlg_OnInitDialog(HWND hwndDlg, LPPROPSHEETPAGE psp) { + SetWindowLongPtr(hwndDlg, GWL_USERDATA, psp->lParam); + CFolderOptions *pFO = (CFolderOptions*)psp->lParam; + + if (!pFO || !pFO->CanSetDefFolderSettings()) + { + // The global options (started from rundll32 or control panel) + // has no browser to copy the current settings from. + EnableWindow(GetDlgItem(hwndDlg, IDC_VIEW_APPLY_TO_ALL), FALSE); + } + HWND hwndTreeView = GetDlgItem(hwndDlg, IDC_VIEW_TREEVIEW); s_hTreeImageList = ViewDlg_CreateTreeImageList(); @@ -941,7 +951,7 @@ FolderOptionsViewDlg( switch (uMsg) { case WM_INITDIALOG: - return ViewDlg_OnInitDialog(hwndDlg); + return ViewDlg_OnInitDialog(hwndDlg, (LPPROPSHEETPAGE)lParam); case WM_COMMAND: switch (LOWORD(wParam)) @@ -949,6 +959,18 @@ FolderOptionsViewDlg( case IDC_VIEW_RESTORE_DEFAULTS: // Restore Defaults ViewDlg_RestoreDefaults(hwndDlg); break; + + case IDC_VIEW_APPLY_TO_ALL: + case IDC_VIEW_RESET_ALL: + { + HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); + CFolderOptions *pFO = (CFolderOptions*)GetWindowLongPtr(hwndDlg, GWL_USERDATA); + if (pFO) + hr = pFO->ApplyDefFolderSettings(LOWORD(wParam) == IDC_VIEW_RESET_ALL); + if (FAILED(hr)) + SHELL_ErrorBox(hwndDlg, hr); + break; + } } break; diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h index 0d60f51fa2f..98fc09cb37b 100644 --- a/dll/win32/shell32/precomp.h +++ b/dll/win32/shell32/precomp.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/sdk/include/reactos/shellutils.h b/sdk/include/reactos/shellutils.h index 6eede011d85..e484c07c064 100644 --- a/sdk/include/reactos/shellutils.h +++ b/sdk/include/reactos/shellutils.h @@ -94,6 +94,36 @@ inline BOOL _ROS_FAILED_HELPER(HRESULT hr, const char* expr, const char* filenam } /* extern "C" */ #endif /* defined(__cplusplus) */ +static inline UINT +SHELL_ErrorBoxHelper(HWND hwndOwner, UINT Error) +{ + WCHAR buf[400]; + UINT cch; + + if (!IsWindowVisible(hwndOwner)) + hwndOwner = NULL; + if (Error == ERROR_SUCCESS) + Error = ERROR_INTERNAL_ERROR; + + cch = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, Error, 0, buf, _countof(buf), NULL); + if (!cch) + { + enum { user32_IDS_ERROR = 2 }; // IDS_ERROR from user32 resource.h ("Error" string) + cch = LoadStringW(LoadLibraryW(L"USER32"), user32_IDS_ERROR, buf, _countof(buf)); + wsprintfW(buf + cch, L"\n\n%#x (%d)", Error, Error); + } + MessageBoxW(hwndOwner, buf, NULL, MB_OK | MB_ICONSTOP); + return Error; +} +#ifdef __cplusplus +template static UINT +SHELL_ErrorBox(H hwndOwner, UINT Error = GetLastError()) +{ + return SHELL_ErrorBoxHelper(const_cast(hwndOwner), Error); +} +#endif + #ifdef __cplusplus template class CComCreatorCentralInstance diff --git a/sdk/include/reactos/shlobj_undoc.h b/sdk/include/reactos/shlobj_undoc.h index a564b36c12c..d97c0c9ece5 100644 --- a/sdk/include/reactos/shlobj_undoc.h +++ b/sdk/include/reactos/shlobj_undoc.h @@ -83,6 +83,12 @@ struct persistState #define PANE_PRIVACY 7 #endif +/***************************************************************************** + * CGID_DefView OLECMD IDs + */ +#define DVCMDID_SET_DEFAULTFOLDER_SETTINGS 0 +#define DVCMDID_RESET_DEFAULTFOLDER_SETTINGS 1 + /***************************************************************************** * IInitializeObject interface */ @@ -144,7 +150,15 @@ DECLARE_INTERFACE_(IBanneredBar, IUnknown)//, "596A9A94-013E-11d1-8D34-00A0C90F2 */ struct DEFFOLDERSETTINGS { - long offset0; + enum { SIZE_NT4 = 8, SIZE_IE4 = 36, SIZE_XP = 40 }; + enum { VER_98 = 0, VER_2000 = 3, VER_XP = 4 }; // Win98SE with IE5 writes 0, not 3 as the version + UINT Statusbar : 1; // "StatusBarOther" is the new location for this + UINT Toolbar : 1; // Not used when Explorer uses ReBar + FOLDERSETTINGS FolderSettings; + SHELLVIEWID vid; + UINT Version; + UINT Counter; // Incremented every time default folder settings are applied. Invalidates a cache? + UINT ViewPriority; // VIEW_PRIORITY_* }; #undef INTERFACE @@ -152,12 +166,12 @@ struct DEFFOLDERSETTINGS DECLARE_INTERFACE_(IGlobalFolderSettings, IUnknown) { /*** IUnknown ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppv) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void **ppv) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; /*** IGlobalFolderSettings ***/ - STDMETHOD(Get)(THIS_ struct DEFFOLDERSETTINGS *buffer, int theSize) PURE; - STDMETHOD(Set)(THIS_ const struct DEFFOLDERSETTINGS *buffer, int theSize, unsigned int param14) PURE; + STDMETHOD(Get)(THIS_ struct DEFFOLDERSETTINGS *pFDS, UINT cb) PURE; + STDMETHOD(Set)(THIS_ const struct DEFFOLDERSETTINGS *pFDS, UINT cb, UINT unknown) PURE; }; #undef INTERFACE