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))))