From c355a2b61e83c6afb51827692c80a1f136bda1aa Mon Sep 17 00:00:00 2001 From: vldmr11080 <57061786+vldmr11080@users.noreply.github.com> Date: Wed, 8 Apr 2020 19:12:46 +0200 Subject: [PATCH] Use JSON data file for storing PowerRename settings instead of registry (#1909) * Use JSON data file for storing PowerRename settings instead of registry * Address PR comments and made several improvements * Remove WindowsApp.lib dependencies in test app and unit tests * Revert changes in vcxproj for unit test * Solve linker warnings generated while linking WindowsApp.lib * Don't migrate enabled flag. Always read / write from registry. --- .../powerrename/dll/PowerRenameExt.cpp | 14 +- src/modules/powerrename/dll/dllmain.cpp | 27 +- .../powerrename/lib/PowerRenameLib.vcxproj | 12 +- src/modules/powerrename/lib/Settings.cpp | 314 +++++++++--------- src/modules/powerrename/lib/Settings.h | 127 +++++-- src/modules/powerrename/lib/stdafx.h | 2 + src/modules/powerrename/lib/trace.cpp | 14 +- src/modules/powerrename/ui/PowerRenameUI.cpp | 28 +- 8 files changed, 314 insertions(+), 224 deletions(-) diff --git a/src/modules/powerrename/dll/PowerRenameExt.cpp b/src/modules/powerrename/dll/PowerRenameExt.cpp index e18508bcc3..3004a14feb 100644 --- a/src/modules/powerrename/dll/PowerRenameExt.cpp +++ b/src/modules/powerrename/dll/PowerRenameExt.cpp @@ -48,7 +48,7 @@ HRESULT CPowerRenameMenu::s_CreateInstance(_In_opt_ IUnknown*, _In_ REFIID riid, HRESULT CPowerRenameMenu::Initialize(_In_opt_ PCIDLIST_ABSOLUTE, _In_ IDataObject* pdtobj, HKEY) { // Check if we have disabled ourselves - if (!CSettings::GetEnabled()) + if (!CSettingsInstance().GetEnabled()) return E_FAIL; // Cache the data object to be used later @@ -60,11 +60,11 @@ HRESULT CPowerRenameMenu::Initialize(_In_opt_ PCIDLIST_ABSOLUTE, _In_ IDataObjec HRESULT CPowerRenameMenu::QueryContextMenu(HMENU hMenu, UINT index, UINT uIDFirst, UINT, UINT uFlags) { // Check if we have disabled ourselves - if (!CSettings::GetEnabled()) + if (!CSettingsInstance().GetEnabled()) return E_FAIL; // Check if we should only be on the extended context menu - if (CSettings::GetExtendedContextMenuOnly() && (!(uFlags & CMF_EXTENDEDVERBS))) + if (CSettingsInstance().GetExtendedContextMenuOnly() && (!(uFlags & CMF_EXTENDEDVERBS))) return E_FAIL; HRESULT hr = E_UNEXPECTED; @@ -81,7 +81,7 @@ HRESULT CPowerRenameMenu::QueryContextMenu(HMENU hMenu, UINT index, UINT uIDFirs mii.dwTypeData = (PWSTR)menuName; mii.fState = MFS_ENABLED; - if (CSettings::GetShowIconOnMenu()) + if (CSettingsInstance().GetShowIconOnMenu()) { HICON hIcon = (HICON)LoadImage(g_hInst, MAKEINTRESOURCE(IDI_RENAME), IMAGE_ICON, 16, 16, 0); if (hIcon) @@ -113,7 +113,7 @@ HRESULT CPowerRenameMenu::InvokeCommand(_In_ LPCMINVOKECOMMANDINFO pici) { HRESULT hr = E_FAIL; - if (CSettings::GetEnabled() && + if (CSettingsInstance().GetEnabled() && (IS_INTRESOURCE(pici->lpVerb)) && (LOWORD(pici->lpVerb) == 0)) { @@ -203,7 +203,7 @@ HRESULT __stdcall CPowerRenameMenu::GetTitle(IShellItemArray* /*psiItemArray*/, HRESULT __stdcall CPowerRenameMenu::GetIcon(IShellItemArray* /*psiItemArray*/, LPWSTR* ppszIcon) { - if (!CSettings::GetShowIconOnMenu()) + if (!CSettingsInstance().GetShowIconOnMenu()) { *ppszIcon = nullptr; return E_NOTIMPL; @@ -229,7 +229,7 @@ HRESULT __stdcall CPowerRenameMenu::GetCanonicalName(GUID* pguidCommandName) HRESULT __stdcall CPowerRenameMenu::GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState) { - *pCmdState = CSettings::GetEnabled() ? ECS_ENABLED : ECS_HIDDEN; + *pCmdState = CSettingsInstance().GetEnabled() ? ECS_ENABLED : ECS_HIDDEN; return S_OK; } diff --git a/src/modules/powerrename/dll/dllmain.cpp b/src/modules/powerrename/dll/dllmain.cpp index 8ab55ce2fa..a952629ca1 100644 --- a/src/modules/powerrename/dll/dllmain.cpp +++ b/src/modules/powerrename/dll/dllmain.cpp @@ -207,17 +207,17 @@ public: settings.add_bool_toogle( L"bool_persist_input", GET_RESOURCE_STRING(IDS_RESTORE_SEARCH), - CSettings::GetPersistState()); + CSettingsInstance().GetPersistState()); settings.add_bool_toogle( L"bool_mru_enabled", GET_RESOURCE_STRING(IDS_ENABLE_AUTO), - CSettings::GetMRUEnabled()); + CSettingsInstance().GetMRUEnabled()); settings.add_int_spinner( L"int_max_mru_size", GET_RESOURCE_STRING(IDS_MAX_ITEMS), - CSettings::GetMaxMRUSize(), + CSettingsInstance().GetMaxMRUSize(), 0, 20, 1); @@ -225,12 +225,12 @@ public: settings.add_bool_toogle( L"bool_show_icon_on_menu", GET_RESOURCE_STRING(IDS_ICON_CONTEXT_MENU), - CSettings::GetShowIconOnMenu()); + CSettingsInstance().GetShowIconOnMenu()); settings.add_bool_toogle( L"bool_show_extended_menu", GET_RESOURCE_STRING(IDS_EXTENDED_MENU_INFO), - CSettings::GetExtendedContextMenuOnly()); + CSettingsInstance().GetExtendedContextMenuOnly()); return settings.serialize_to_buffer(buffer, buffer_size); } @@ -245,11 +245,12 @@ public: PowerToysSettings::PowerToyValues values = PowerToysSettings::PowerToyValues::from_json_string(config); - CSettings::SetPersistState(values.get_bool_value(L"bool_persist_input").value()); - CSettings::SetMRUEnabled(values.get_bool_value(L"bool_mru_enabled").value()); - CSettings::SetMaxMRUSize(values.get_int_value(L"int_max_mru_size").value()); - CSettings::SetShowIconOnMenu(values.get_bool_value(L"bool_show_icon_on_menu").value()); - CSettings::SetExtendedContextMenuOnly(values.get_bool_value(L"bool_show_extended_menu").value()); + CSettingsInstance().SetPersistState(values.get_bool_value(L"bool_persist_input").value()); + CSettingsInstance().SetMRUEnabled(values.get_bool_value(L"bool_mru_enabled").value()); + CSettingsInstance().SetMaxMRUSize(values.get_int_value(L"int_max_mru_size").value()); + CSettingsInstance().SetShowIconOnMenu(values.get_bool_value(L"bool_show_icon_on_menu").value()); + CSettingsInstance().SetExtendedContextMenuOnly(values.get_bool_value(L"bool_show_extended_menu").value()); + CSettingsInstance().SavePowerRenameData(); Trace::SettingsChanged(); } @@ -282,13 +283,15 @@ public: void init_settings() { - m_enabled = CSettings::GetEnabled(); + CSettingsInstance().LoadPowerRenameData(); + m_enabled = CSettingsInstance().GetEnabled(); Trace::EnablePowerRename(m_enabled); } void save_settings() { - CSettings::SetEnabled(m_enabled); + CSettingsInstance().SetEnabled(m_enabled); + CSettingsInstance().SavePowerRenameData(); Trace::EnablePowerRename(m_enabled); } diff --git a/src/modules/powerrename/lib/PowerRenameLib.vcxproj b/src/modules/powerrename/lib/PowerRenameLib.vcxproj index aed76018e9..6bc9faabbd 100644 --- a/src/modules/powerrename/lib/PowerRenameLib.vcxproj +++ b/src/modules/powerrename/lib/PowerRenameLib.vcxproj @@ -85,13 +85,14 @@ - Use + Create Level4 Disabled WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) true stdcpp17 MultiThreadedDebug + stdafx.h Windows @@ -99,7 +100,7 @@ - Use + Create Level4 Disabled _DEBUG;_LIB;%(PreprocessorDefinitions) @@ -107,6 +108,7 @@ stdcpp17 MultiThreadedDebug ..\;..\..\..\common;..\..\..\common\telemetry;..\..\ + stdafx.h Windows @@ -116,7 +118,7 @@ Level3 - Use + Create MaxSpeed true true @@ -124,6 +126,7 @@ true stdcpp17 MultiThreaded + stdafx.h Windows @@ -134,7 +137,7 @@ Level3 - Use + Create MaxSpeed true true @@ -143,6 +146,7 @@ stdcpp17 MultiThreaded ..\;..\..\..\common;..\..\..\common\telemetry;..\..\ + stdafx.h Windows diff --git a/src/modules/powerrename/lib/Settings.cpp b/src/modules/powerrename/lib/Settings.cpp index 230cd2f2f8..33d223cc7d 100644 --- a/src/modules/powerrename/lib/Settings.cpp +++ b/src/modules/powerrename/lib/Settings.cpp @@ -1,171 +1,70 @@ #include "stdafx.h" -#include #include "Settings.h" #include "PowerRenameInterfaces.h" +#include "settings_helpers.h" -const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\PowerRename"; -const wchar_t c_mruSearchRegPath[] = L"SearchMRU"; -const wchar_t c_mruReplaceRegPath[] = L"ReplaceMRU"; +#include +#include -const wchar_t c_enabled[] = L"Enabled"; -const wchar_t c_showIconOnMenu[] = L"ShowIcon"; -const wchar_t c_extendedContextMenuOnly[] = L"ExtendedContextMenuOnly"; -const wchar_t c_persistState[] = L"PersistState"; -const wchar_t c_maxMRUSize[] = L"MaxMRUSize"; -const wchar_t c_flags[] = L"Flags"; -const wchar_t c_searchText[] = L"SearchText"; -const wchar_t c_replaceText[] = L"ReplaceText"; -const wchar_t c_mruEnabled[] = L"MRUEnabled"; - -const bool c_enabledDefault = true; -const bool c_showIconOnMenuDefault = true; -const bool c_extendedContextMenuOnlyDefaut = false; -const bool c_persistStateDefault = true; -const bool c_mruEnabledDefault = true; - -const DWORD c_maxMRUSizeDefault = 10; -const DWORD c_flagsDefault = 0; - -bool CSettings::GetEnabled() +namespace { - return GetRegBoolValue(c_enabled, c_enabledDefault); -} + const wchar_t c_powerRenameDataFilePath[] = L"power-rename-settings.json"; -bool CSettings::SetEnabled(_In_ bool enabled) -{ - return SetRegBoolValue(c_enabled, enabled); -} + const wchar_t c_rootRegPath[] = L"Software\\Microsoft\\PowerRename"; + const wchar_t c_mruSearchRegPath[] = L"SearchMRU"; + const wchar_t c_mruReplaceRegPath[] = L"ReplaceMRU"; -bool CSettings::GetShowIconOnMenu() -{ - return GetRegBoolValue(c_showIconOnMenu, c_showIconOnMenuDefault); -} + const wchar_t c_enabled[] = L"Enabled"; + const wchar_t c_showIconOnMenu[] = L"ShowIcon"; + const wchar_t c_extendedContextMenuOnly[] = L"ExtendedContextMenuOnly"; + const wchar_t c_persistState[] = L"PersistState"; + const wchar_t c_maxMRUSize[] = L"MaxMRUSize"; + const wchar_t c_flags[] = L"Flags"; + const wchar_t c_searchText[] = L"SearchText"; + const wchar_t c_replaceText[] = L"ReplaceText"; + const wchar_t c_mruEnabled[] = L"MRUEnabled"; -bool CSettings::SetShowIconOnMenu(_In_ bool show) -{ - return SetRegBoolValue(c_showIconOnMenu, show); -} - -bool CSettings::GetExtendedContextMenuOnly() -{ - return GetRegBoolValue(c_extendedContextMenuOnly, c_extendedContextMenuOnlyDefaut); -} - -bool CSettings::SetExtendedContextMenuOnly(_In_ bool extendedOnly) -{ - return SetRegBoolValue(c_extendedContextMenuOnly, extendedOnly); -} - -bool CSettings::GetPersistState() -{ - return GetRegBoolValue(c_persistState, c_persistStateDefault); -} - -bool CSettings::SetPersistState(_In_ bool persistState) -{ - return SetRegBoolValue(c_persistState, persistState); -} - -bool CSettings::GetMRUEnabled() -{ - return GetRegBoolValue(c_mruEnabled, c_mruEnabledDefault); -} - -bool CSettings::SetMRUEnabled(_In_ bool enabled) -{ - return SetRegBoolValue(c_mruEnabled, enabled); -} - -DWORD CSettings::GetMaxMRUSize() -{ - return GetRegDWORDValue(c_maxMRUSize, c_maxMRUSizeDefault); -} - -bool CSettings::SetMaxMRUSize(_In_ DWORD maxMRUSize) -{ - return SetRegDWORDValue(c_maxMRUSize, maxMRUSize); -} - -DWORD CSettings::GetFlags() -{ - return GetRegDWORDValue(c_flags, c_flagsDefault); -} - -bool CSettings::SetFlags(_In_ DWORD flags) -{ - return SetRegDWORDValue(c_flags, flags); -} - -bool CSettings::GetSearchText(__out_ecount(cchBuf) PWSTR text, DWORD cchBuf) -{ - return GetRegStringValue(c_searchText, text, cchBuf); -} - -bool CSettings::SetSearchText(_In_ PCWSTR text) -{ - return SetRegStringValue(c_searchText, text); -} - -bool CSettings::GetReplaceText(__out_ecount(cchBuf) PWSTR text, DWORD cchBuf) -{ - return GetRegStringValue(c_replaceText, text, cchBuf); -} - -bool CSettings::SetReplaceText(_In_ PCWSTR text) -{ - return SetRegStringValue(c_replaceText, text); -} - -bool CSettings::SetRegBoolValue(_In_ PCWSTR valueName, _In_ bool value) -{ - DWORD dwValue = value ? 1 : 0; - return SetRegDWORDValue(valueName, dwValue); -} - -bool CSettings::GetRegBoolValue(_In_ PCWSTR valueName, _In_ bool defaultValue) -{ - DWORD value = GetRegDWORDValue(valueName, (defaultValue == 0) ? false : true); - return (value == 0) ? false : true; -} - -bool CSettings::SetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD value) -{ - return (SUCCEEDED(HRESULT_FROM_WIN32(SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, REG_DWORD, &value, sizeof(value))))); -} - -DWORD CSettings::GetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD defaultValue) -{ - DWORD retVal = defaultValue; - DWORD type = REG_DWORD; - DWORD dwEnabled = 0; - DWORD cb = sizeof(dwEnabled); - if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, &type, &dwEnabled, &cb) == ERROR_SUCCESS) + long GetRegNumber(const std::wstring& valueName, long defaultValue) { - retVal = dwEnabled; + DWORD type = REG_DWORD; + DWORD data = 0; + DWORD size = sizeof(DWORD); + if (SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName.c_str(), &type, &data, &size) == ERROR_SUCCESS) + { + return data; + } + return defaultValue; } - return retVal; -} - -bool CSettings::SetRegStringValue(_In_ PCWSTR valueName, _In_ PCWSTR value) -{ - ULONG cb = (DWORD)((wcslen(value) + 1) * sizeof(*value)); - return (SUCCEEDED(HRESULT_FROM_WIN32(SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, REG_SZ, (const BYTE*)value, cb)))); -} - -bool CSettings::GetRegStringValue(_In_ PCWSTR valueName, __out_ecount(cchBuf) PWSTR value, DWORD cchBuf) -{ - if (cchBuf > 0) + void SetRegNumber(const std::wstring& valueName, long value) { + SHSetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName.c_str(), REG_DWORD, &value, sizeof(value)); + } + + bool GetRegBoolean(const std::wstring& valueName, bool defaultValue) + { + DWORD value = GetRegNumber(valueName.c_str(), defaultValue ? 1 : 0); + return (value == 0) ? false : true; + } + + void SetRegBoolean(const std::wstring& valueName, bool value) + { + SetRegNumber(valueName, value ? 1 : 0); + } + + std::wstring GetRegString(const std::wstring& valueName) { + wchar_t value[CSettings::MAX_INPUT_STRING_LEN]; value[0] = L'\0'; + DWORD type = REG_SZ; + DWORD size = CSettings::MAX_INPUT_STRING_LEN * sizeof(wchar_t); + if (SUCCEEDED(HRESULT_FROM_WIN32(SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName.c_str(), &type, value, &size) == ERROR_SUCCESS))) + { + return std::wstring(value); + } + return std::wstring{}; } - - DWORD type = REG_SZ; - ULONG cb = cchBuf * sizeof(*value); - return (SUCCEEDED(HRESULT_FROM_WIN32(SHGetValue(HKEY_CURRENT_USER, c_rootRegPath, valueName, &type, value, &cb) == ERROR_SUCCESS))); } - typedef int (CALLBACK* MRUCMPPROC)(LPCWSTR, LPCWSTR); typedef struct { @@ -470,12 +369,121 @@ void CRenameMRU::_FreeMRUList() } } +CSettings::CSettings() +{ + std::wstring result = PTSettingsHelper::get_module_save_folder_location(L"PowerRename"); + jsonFilePath = result + L"\\" + std::wstring(c_powerRenameDataFilePath); +} + +bool CSettings::GetEnabled() +{ + return GetRegBoolean(c_enabled, true); +} + +void CSettings::SetEnabled(bool enabled) +{ + SetRegBoolean(c_enabled, enabled); +} + +void CSettings::LoadPowerRenameData() +{ + if (!std::filesystem::exists(jsonFilePath)) + { + MigrateSettingsFromRegistry(); + + SavePowerRenameData(); + } + else + { + ParseJsonSettings(); + } +} + +void CSettings::SavePowerRenameData() const +{ + json::JsonObject jsonData; + + jsonData.SetNamedValue(c_showIconOnMenu, json::value(settings.showIconOnMenu)); + jsonData.SetNamedValue(c_extendedContextMenuOnly, json::value(settings.extendedContextMenuOnly)); + jsonData.SetNamedValue(c_persistState, json::value(settings.persistState)); + jsonData.SetNamedValue(c_mruEnabled, json::value(settings.MRUEnabled)); + jsonData.SetNamedValue(c_maxMRUSize, json::value(settings.maxMRUSize)); + jsonData.SetNamedValue(c_flags, json::value(settings.flags)); + jsonData.SetNamedValue(c_searchText, json::value(settings.searchText)); + jsonData.SetNamedValue(c_replaceText, json::value(settings.replaceText)); + + json::to_file(jsonFilePath, jsonData); +} + +void CSettings::MigrateSettingsFromRegistry() +{ + settings.showIconOnMenu = GetRegBoolean(c_showIconOnMenu, true); + settings.extendedContextMenuOnly = GetRegBoolean(c_extendedContextMenuOnly, false); // Disabled by default. + settings.persistState = GetRegBoolean(c_persistState, true); + settings.MRUEnabled = GetRegBoolean(c_mruEnabled, true); + settings.maxMRUSize = GetRegNumber(c_maxMRUSize, 10); + settings.flags = GetRegNumber(c_flags, 0); + settings.searchText = GetRegString(c_searchText); + settings.replaceText = GetRegString(c_replaceText); +} + +void CSettings::ParseJsonSettings() +{ + auto json = json::from_file(jsonFilePath); + if (json) + { + const json::JsonObject& jsonSettings = json.value(); + try + { + if (json::has(jsonSettings, c_showIconOnMenu, json::JsonValueType::Boolean)) + { + settings.showIconOnMenu = jsonSettings.GetNamedBoolean(c_showIconOnMenu); + } + if (json::has(jsonSettings, c_extendedContextMenuOnly, json::JsonValueType::Boolean)) + { + settings.extendedContextMenuOnly = jsonSettings.GetNamedBoolean(c_extendedContextMenuOnly); + } + if (json::has(jsonSettings, c_persistState, json::JsonValueType::Boolean)) + { + settings.persistState = jsonSettings.GetNamedBoolean(c_persistState); + } + if (json::has(jsonSettings, c_mruEnabled, json::JsonValueType::Boolean)) + { + settings.MRUEnabled = jsonSettings.GetNamedBoolean(c_mruEnabled); + } + if (json::has(jsonSettings, c_maxMRUSize, json::JsonValueType::Number)) + { + settings.maxMRUSize = (long)jsonSettings.GetNamedNumber(c_maxMRUSize); + } + if (json::has(jsonSettings, c_flags, json::JsonValueType::Number)) + { + settings.flags = (long)jsonSettings.GetNamedNumber(c_flags); + } + if (json::has(jsonSettings, c_searchText, json::JsonValueType::String)) + { + settings.searchText = jsonSettings.GetNamedString(c_searchText); + } + if (json::has(jsonSettings, c_replaceText, json::JsonValueType::String)) + { + settings.replaceText = jsonSettings.GetNamedString(c_replaceText); + } + } + catch (const winrt::hresult_error&) { } + } +} + +CSettings& CSettingsInstance() +{ + static CSettings instance; + return instance; +} + HRESULT CRenameMRUSearch_CreateInstance(_Outptr_ IUnknown** ppUnk) { - return CRenameMRU::CreateInstance(c_mruSearchRegPath, CSettings::GetMaxMRUSize(), ppUnk); + return CRenameMRU::CreateInstance(c_mruSearchRegPath, CSettingsInstance().GetMaxMRUSize(), ppUnk); } HRESULT CRenameMRUReplace_CreateInstance(_Outptr_ IUnknown** ppUnk) { - return CRenameMRU::CreateInstance(c_mruReplaceRegPath, CSettings::GetMaxMRUSize(), ppUnk); + return CRenameMRU::CreateInstance(c_mruReplaceRegPath, CSettingsInstance().GetMaxMRUSize(), ppUnk); } diff --git a/src/modules/powerrename/lib/Settings.h b/src/modules/powerrename/lib/Settings.h index 2d3a673567..b7e5fa83bf 100644 --- a/src/modules/powerrename/lib/Settings.h +++ b/src/modules/powerrename/lib/Settings.h @@ -1,45 +1,124 @@ #pragma once +#include "json.h" + +#include + class CSettings { public: static const int MAX_INPUT_STRING_LEN = 1024; - static bool GetEnabled(); - static bool SetEnabled(_In_ bool enabled); + CSettings(); - static bool GetShowIconOnMenu(); - static bool SetShowIconOnMenu(_In_ bool show); + bool GetEnabled(); - static bool GetExtendedContextMenuOnly(); - static bool SetExtendedContextMenuOnly(_In_ bool extendedOnly); + void SetEnabled(bool enabled); - static bool GetPersistState(); - static bool SetPersistState(_In_ bool extendedOnly); + inline bool GetShowIconOnMenu() const + { + return settings.showIconOnMenu; + } - static bool GetMRUEnabled(); - static bool SetMRUEnabled(_In_ bool enabled); + inline void SetShowIconOnMenu(bool show) + { + settings.showIconOnMenu = show; + } - static DWORD GetMaxMRUSize(); - static bool SetMaxMRUSize(_In_ DWORD maxMRUSize); + inline bool GetExtendedContextMenuOnly() const + { + return settings.extendedContextMenuOnly; + } - static DWORD GetFlags(); - static bool SetFlags(_In_ DWORD flags); + inline void SetExtendedContextMenuOnly(bool extendedOnly) + { + settings.extendedContextMenuOnly = extendedOnly; + } - static bool GetSearchText(__out_ecount(cchBuf) PWSTR text, DWORD cchBuf); - static bool SetSearchText(_In_ PCWSTR text); + inline bool GetPersistState() const + { + return settings.persistState; + } - static bool GetReplaceText(__out_ecount(cchBuf) PWSTR text, DWORD cchBuf); - static bool SetReplaceText(_In_ PCWSTR text); + inline void SetPersistState(bool persistState) + { + settings.persistState = persistState; + } + + inline bool GetMRUEnabled() const + { + return settings.MRUEnabled; + } + + inline void SetMRUEnabled(bool MRUEnabled) + { + settings.MRUEnabled = MRUEnabled; + } + + inline long GetMaxMRUSize() const + { + return settings.maxMRUSize; + } + + inline void SetMaxMRUSize(long maxMRUSize) + { + settings.maxMRUSize = maxMRUSize; + } + + inline long GetFlags() const + { + return settings.flags; + } + + inline void SetFlags(long flags) + { + settings.flags = flags; + } + + inline const std::wstring& GetSearchText() const + { + return settings.searchText; + } + + inline void SetSearchText(const std::wstring& text) + { + settings.searchText = text; + } + + inline const std::wstring& GetReplaceText() const + { + return settings.replaceText; + } + + inline void SetReplaceText(const std::wstring& text) + { + settings.replaceText = text; + } + + void LoadPowerRenameData(); + void SavePowerRenameData() const; private: - static bool GetRegBoolValue(_In_ PCWSTR valueName, _In_ bool defaultValue); - static bool SetRegBoolValue(_In_ PCWSTR valueName, _In_ bool value); - static bool SetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD value); - static DWORD GetRegDWORDValue(_In_ PCWSTR valueName, _In_ DWORD defaultValue); - static bool SetRegStringValue(_In_ PCWSTR valueName, _In_ PCWSTR value); - static bool GetRegStringValue(_In_ PCWSTR valueName, __out_ecount(cchBuf) PWSTR value, DWORD cchBuf); + struct Settings + { + bool showIconOnMenu{ true }; + bool extendedContextMenuOnly{ false }; // Disabled by default. + bool persistState{ true }; + bool MRUEnabled{ true }; + long maxMRUSize{ 10 }; + long flags{ 0 }; + std::wstring searchText{}; + std::wstring replaceText{}; + }; + + void MigrateSettingsFromRegistry(); + void ParseJsonSettings(); + + Settings settings; + std::wstring jsonFilePath; }; +CSettings& CSettingsInstance(); + HRESULT CRenameMRUSearch_CreateInstance(_Outptr_ IUnknown** ppUnk); HRESULT CRenameMRUReplace_CreateInstance(_Outptr_ IUnknown** ppUnk); \ No newline at end of file diff --git a/src/modules/powerrename/lib/stdafx.h b/src/modules/powerrename/lib/stdafx.h index 390657a3d9..801576c4b7 100644 --- a/src/modules/powerrename/lib/stdafx.h +++ b/src/modules/powerrename/lib/stdafx.h @@ -19,3 +19,5 @@ #include #include + +#pragma comment(lib, "windowsapp") diff --git a/src/modules/powerrename/lib/trace.cpp b/src/modules/powerrename/lib/trace.cpp index 21da33c754..da2ad630f4 100644 --- a/src/modules/powerrename/lib/trace.cpp +++ b/src/modules/powerrename/lib/trace.cpp @@ -79,11 +79,11 @@ void Trace::SettingsChanged() noexcept "PowerRename_SettingsChanged", ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance), TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE), - TraceLoggingBoolean(CSettings::GetEnabled(), "IsEnabled"), - TraceLoggingBoolean(CSettings::GetShowIconOnMenu(), "ShowIconOnMenu"), - TraceLoggingBoolean(CSettings::GetExtendedContextMenuOnly(), "ExtendedContextMenuOnly"), - TraceLoggingBoolean(CSettings::GetPersistState(), "PersistState"), - TraceLoggingBoolean(CSettings::GetMRUEnabled(), "IsMRUEnabled"), - TraceLoggingUInt64(CSettings::GetMaxMRUSize(), "MaxMRUSize"), - TraceLoggingUInt64(CSettings::GetFlags(), "Flags")); + TraceLoggingBoolean(CSettingsInstance().GetEnabled(), "IsEnabled"), + TraceLoggingBoolean(CSettingsInstance().GetShowIconOnMenu(), "ShowIconOnMenu"), + TraceLoggingBoolean(CSettingsInstance().GetExtendedContextMenuOnly(), "ExtendedContextMenuOnly"), + TraceLoggingBoolean(CSettingsInstance().GetPersistState(), "PersistState"), + TraceLoggingBoolean(CSettingsInstance().GetMRUEnabled(), "IsMRUEnabled"), + TraceLoggingUInt64(CSettingsInstance().GetMaxMRUSize(), "MaxMRUSize"), + TraceLoggingUInt64(CSettingsInstance().GetFlags(), "Flags")); } diff --git a/src/modules/powerrename/ui/PowerRenameUI.cpp b/src/modules/powerrename/ui/PowerRenameUI.cpp index e5c602e63a..e43cc9f148 100644 --- a/src/modules/powerrename/ui/PowerRenameUI.cpp +++ b/src/modules/powerrename/ui/PowerRenameUI.cpp @@ -308,7 +308,7 @@ HRESULT CPowerRenameUI::_Initialize(_In_ IPowerRenameManager* psrm, _In_opt_ IUn HRESULT CPowerRenameUI::_InitAutoComplete() { HRESULT hr = S_OK; - if (CSettings::GetMRUEnabled()) + if (CSettingsInstance().GetMRUEnabled()) { hr = CoCreateInstance(CLSID_AutoComplete, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&m_spSearchAC)); if (SUCCEEDED(hr)) @@ -387,19 +387,13 @@ HRESULT CPowerRenameUI::_ReadSettings() // Check if we should read flags from settings // or the defaults from the manager. DWORD flags = 0; - if (CSettings::GetPersistState()) + if (CSettingsInstance().GetPersistState()) { - flags = CSettings::GetFlags(); + flags = CSettingsInstance().GetFlags(); m_spsrm->put_flags(flags); - wchar_t buffer[CSettings::MAX_INPUT_STRING_LEN]; - buffer[0] = L'\0'; - CSettings::GetSearchText(buffer, ARRAYSIZE(buffer)); - SetDlgItemText(m_hwnd, IDC_EDIT_SEARCHFOR, buffer); - - buffer[0] = L'\0'; - CSettings::GetReplaceText(buffer, ARRAYSIZE(buffer)); - SetDlgItemText(m_hwnd, IDC_EDIT_REPLACEWITH, buffer); + SetDlgItemText(m_hwnd, IDC_EDIT_SEARCHFOR, CSettingsInstance().GetSearchText().c_str()); + SetDlgItemText(m_hwnd, IDC_EDIT_REPLACEWITH, CSettingsInstance().GetReplaceText().c_str()); } else { @@ -414,18 +408,18 @@ HRESULT CPowerRenameUI::_ReadSettings() HRESULT CPowerRenameUI::_WriteSettings() { // Check if we should store our settings - if (CSettings::GetPersistState()) + if (CSettingsInstance().GetPersistState()) { DWORD flags = 0; m_spsrm->get_flags(&flags); - CSettings::SetFlags(flags); + CSettingsInstance().SetFlags(flags); wchar_t buffer[CSettings::MAX_INPUT_STRING_LEN]; buffer[0] = L'\0'; GetDlgItemText(m_hwnd, IDC_EDIT_SEARCHFOR, buffer, ARRAYSIZE(buffer)); - CSettings::SetSearchText(buffer); + CSettingsInstance().SetSearchText(buffer); - if (CSettings::GetMRUEnabled() && m_spSearchACL) + if (CSettingsInstance().GetMRUEnabled() && m_spSearchACL) { CComPtr spSearchMRU; if (SUCCEEDED(m_spSearchACL->QueryInterface(IID_PPV_ARGS(&spSearchMRU)))) @@ -436,9 +430,9 @@ HRESULT CPowerRenameUI::_WriteSettings() buffer[0] = L'\0'; GetDlgItemText(m_hwnd, IDC_EDIT_REPLACEWITH, buffer, ARRAYSIZE(buffer)); - CSettings::SetReplaceText(buffer); + CSettingsInstance().SetReplaceText(buffer); - if (CSettings::GetMRUEnabled() && m_spReplaceACL) + if (CSettingsInstance().GetMRUEnabled() && m_spReplaceACL) { CComPtr spReplaceMRU; if (SUCCEEDED(m_spReplaceACL->QueryInterface(IID_PPV_ARGS(&spReplaceMRU))))