From e0a4364e5c209c39372c0ec71d52551751b978fd Mon Sep 17 00:00:00 2001 From: verylowfreq <60875431+verylowfreq@users.noreply.github.com> Date: Sat, 11 Jun 2022 07:59:49 +0900 Subject: [PATCH 1/2] Add Settings class for INI file. --- src/CMakeLists.txt | 1 + src/platform/guiwin.cpp | 88 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3fb9a9ccd..65b4336e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -356,6 +356,7 @@ if(ENABLE_GUI) platform/guiwin.cpp) target_link_libraries(solvespace PRIVATE comctl32) + target_link_libraries(solvespace PRIVATE Shlwapi) elseif(APPLE) target_compile_options(solvespace PRIVATE -fobjc-arc) target_compile_definitions(solvespace PRIVATE GL_SILENCE_DEPRECATION) diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index 45ad78375..db33fa2b0 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include // Macros to compile under XP #if !defined(LSTATUS) @@ -188,7 +190,7 @@ void FatalError(const std::string &message) { // Settings //----------------------------------------------------------------------------- -class SettingsImplWin32 final : public Settings { +class SettingsImplWin32Reg final : public Settings { public: HKEY hKey = NULL; @@ -200,7 +202,7 @@ class SettingsImplWin32 final : public Settings { return hKey; } - ~SettingsImplWin32() { + ~SettingsImplWin32Reg() { if(hKey != NULL) { sscheck(ERROR_SUCCESS == RegCloseKey(hKey)); } @@ -261,8 +263,88 @@ class SettingsImplWin32 final : public Settings { } }; +class SettingsImplWin32IniFile final : public Settings { +public: + static constexpr const char* INI_FILENAME = "solvespace.ini"; + static constexpr const char* INI_SECTION_NAME = "solvespace"; + Path iniPath; + + + ~SettingsImplWin32IniFile() { } + + void FreezeInt(const std::string &key, uint32_t value) { + FreezeString(key, std::to_string(value)); + } + + uint32_t ThawInt(const std::string &key, uint32_t defaultValue) { + std::string valueString = ThawString(key, std::to_string(defaultValue)); + return (uint32_t)strtoul(valueString.c_str(), nullptr, 10); + } + + void FreezeFloat(const std::string &key, double value) { + FreezeString(key, std::to_string(value)); + } + + double ThawFloat(const std::string &key, double defaultValue) { + std::string valueString = ThawString(key, std::to_string(defaultValue)); + return strtod(valueString.c_str(), nullptr); + } + + void FreezeString(const std::string &key, const std::string &value) { + DWORD ret = WritePrivateProfileStringW( + Widen(INI_SECTION_NAME).c_str(), + Widen(key).c_str(), Widen(value).c_str(), + Widen(iniPath.raw).c_str() + ); + } + + std::string ThawString(const std::string &key, const std::string &defaultValue) { + //FIXME: buffer length + constexpr size_t _BUF_LEN = MAX_PATH * 2; + wchar_t buf[_BUF_LEN] = {}; + DWORD ret = GetPrivateProfileStringW(Widen(INI_SECTION_NAME).c_str(), + Widen(key).c_str(), Widen(defaultValue).c_str(), + buf, _BUF_LEN, Widen(iniPath.raw).c_str()); + + return Narrow(buf); + } +}; + +static SettingsRef cachedSettingsRef = nullptr; + SettingsRef GetSettings() { - return std::make_shared(); + if (cachedSettingsRef == nullptr) { + // INI file check only first time calling. + + // FIXME: ref) https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation + WCHAR appFilePath[MAX_PATH] = {}; + if(GetModuleFileNameW(NULL, appFilePath, sizeof(appFilePath)) == 0) { + std::string mes = "Failed to GetModuleFileNameW() in GetSettings(): errorcode="; + mes += GetLastError(); + FatalError(mes); + } + Path apppath = Path::From(Narrow(appFilePath)); + Path appdirpath = apppath.Parent(); + Path inipath = appdirpath.Join(SettingsImplWin32IniFile::INI_FILENAME); + if(inipath.IsEmpty()) { + FatalError("Failed to generate INI file path."); + } + + if(PathFileExistsW(Widen(inipath.raw).c_str()) == FALSE) { + // INI file not exist. Use Registry. + + cachedSettingsRef = std::make_shared(); + + } else { + // INI file already exists. Use it. + + auto settings = std::make_shared(); + settings->iniPath = inipath; + cachedSettingsRef = settings; + } + } + + return cachedSettingsRef; } //----------------------------------------------------------------------------- From c58080847a992250ce858b2ef3280725663a4753 Mon Sep 17 00:00:00 2001 From: verylowfreq <60875431+verylowfreq@users.noreply.github.com> Date: Sat, 11 Jun 2022 16:45:46 +0900 Subject: [PATCH 2/2] Fix for building with MinGW. --- src/CMakeLists.txt | 2 +- src/platform/guiwin.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 65b4336e6..74b63e5ba 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -356,7 +356,7 @@ if(ENABLE_GUI) platform/guiwin.cpp) target_link_libraries(solvespace PRIVATE comctl32) - target_link_libraries(solvespace PRIVATE Shlwapi) + target_link_libraries(solvespace PRIVATE shlwapi) elseif(APPLE) target_compile_options(solvespace PRIVATE -fobjc-arc) target_compile_definitions(solvespace PRIVATE GL_SILENCE_DEPRECATION) diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index db33fa2b0..2246588d0 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include // Macros to compile under XP #if !defined(LSTATUS)