From: Takashi Sawanaka Date: Sun, 8 Aug 2021 05:32:00 +0000 (+0900) Subject: Fix crash when registry is set to an unexpected value X-Git-Tag: v2.16.15~107 X-Git-Url: http://git.osdn.net/view?p=winmerge-jp%2Fwinmerge-jp.git;a=commitdiff_plain;h=4a37ddc7e29dc348fe26837ceed26e0ed8ed2f05 Fix crash when registry is set to an unexpected value --- diff --git a/Src/7zCommon.cpp b/Src/7zCommon.cpp index a9eb99a0e..b5923c2d2 100644 --- a/Src/7zCommon.cpp +++ b/Src/7zCommon.cpp @@ -145,7 +145,7 @@ bool IsArchiveFile(const String& pszFile) */ Merge7z::Format *ArchiveGuessFormat(const String& path) { - if (GetOptionsMgr()->GetInt(OPT_ARCHIVE_ENABLE) == 0) + if (!GetOptionsMgr()->GetBool(OPT_ARCHIVE_ENABLE)) return nullptr; if (paths::IsDirectory(path)) return nullptr; @@ -271,7 +271,7 @@ interface Merge7z *Merge7z::Proxy::operator->() { // Merge7z has not yet been loaded - if (GetOptionsMgr()->GetInt(OPT_ARCHIVE_ENABLE) == 0) + if (!GetOptionsMgr()->GetBool(OPT_ARCHIVE_ENABLE)) throw new CResourceException(); if (DWORD ver = VersionOf7z()) { diff --git a/Src/Common/OptionsMgr.cpp b/Src/Common/OptionsMgr.cpp index af033f952..67f1899e9 100644 --- a/Src/Common/OptionsMgr.cpp +++ b/Src/Common/OptionsMgr.cpp @@ -377,6 +377,18 @@ int COptionsMgr::AddOption(const String& name, const varprop::VariantValue& defa return retVal; } +int COptionsMgr::InitOption(const String& name, int defaultValue, int minValue, int maxValue, bool serializable) +{ + int retVal = InitOption(name, defaultValue, serializable); + if (retVal == COption::OPT_OK) + { + int ival = GetInt(name); + if (ival < minValue || ival > maxValue) + Reset(name); + } + return retVal; +} + /** * @brief Get option value from list by name. * @param [in] name Name of the option to get. diff --git a/Src/Common/OptionsMgr.h b/Src/Common/OptionsMgr.h index 1d0471311..161871144 100644 --- a/Src/Common/OptionsMgr.h +++ b/Src/Common/OptionsMgr.h @@ -134,6 +134,7 @@ public: virtual int InitOption(const String& name, const String& defaultValue) = 0; virtual int InitOption(const String& name, const TCHAR *defaultValue) = 0; virtual int InitOption(const String& name, int defaultValue, bool serializable = true) = 0; + virtual int InitOption(const String& name, int defaultValue, int minValue, int maxValue, bool serializable = true); virtual int InitOption(const String& name, bool defaultValue) = 0; virtual int SaveOption(const String& name) = 0; diff --git a/Src/DirScan.cpp b/Src/DirScan.cpp index 4f456230c..0a4185299 100644 --- a/Src/DirScan.cpp +++ b/Src/DirScan.cpp @@ -480,11 +480,8 @@ int DirScan_CompareItems(DiffFuncStruct *myStruct, DIFFITEM *parentdiffpos) { nworkers = GetOptionsMgr()->GetInt(OPT_CMP_COMPARE_THREADS); if (nworkers <= 0) - { nworkers += Environment::processorCount(); - if (nworkers <= 0) - nworkers = 1; - } + nworkers = std::clamp(nworkers, 1, static_cast(Environment::processorCount())); } ThreadPool threadPool(nworkers, nworkers); diff --git a/Src/DirView.cpp b/Src/DirView.cpp index 01fa6b4a9..ae3026e8b 100644 --- a/Src/DirView.cpp +++ b/Src/DirView.cpp @@ -1104,7 +1104,7 @@ void CDirView::OnColumnClick(NMHDR *pNMHDR, LRESULT *pResult) void CDirView::SortColumnsAppropriately() { int sortCol = GetOptionsMgr()->GetInt((GetDocument()->m_nDirs < 3) ? OPT_DIRVIEW_SORT_COLUMN : OPT_DIRVIEW_SORT_COLUMN3); - if (sortCol == -1 || sortCol >= m_pColItems->GetColCount()) + if (sortCol < 0 || sortCol >= m_pColItems->GetColCount()) return; bool bSortAscending = GetOptionsMgr()->GetBool(OPT_DIRVIEW_SORT_ASCENDING); diff --git a/Src/ImgMergeFrm.cpp b/Src/ImgMergeFrm.cpp index bf7149d4f..62195109d 100644 --- a/Src/ImgMergeFrm.cpp +++ b/Src/ImgMergeFrm.cpp @@ -602,7 +602,7 @@ BOOL CImgMergeFrame::DestroyWindow() void CImgMergeFrame::LoadOptions() { m_pImgMergeWindow->SetShowDifferences(GetOptionsMgr()->GetBool(OPT_CMP_IMG_SHOWDIFFERENCES)); - m_pImgMergeWindow->SetOverlayMode(static_cast(GetOptionsMgr()->GetInt(OPT_CMP_IMG_OVERLAYMOVE))); + m_pImgMergeWindow->SetOverlayMode(static_cast(GetOptionsMgr()->GetInt(OPT_CMP_IMG_OVERLAYMODE))); m_pImgMergeWindow->SetOverlayAlpha(GetOptionsMgr()->GetInt(OPT_CMP_IMG_OVERLAYALPHA) / 100.0); m_pImgMergeWindow->SetDraggingMode(static_cast(GetOptionsMgr()->GetInt(OPT_CMP_IMG_DRAGGING_MODE))); m_pImgMergeWindow->SetZoom(GetOptionsMgr()->GetInt(OPT_CMP_IMG_ZOOM) / 1000.0); @@ -620,7 +620,7 @@ void CImgMergeFrame::LoadOptions() void CImgMergeFrame::SaveOptions() { GetOptionsMgr()->SaveOption(OPT_CMP_IMG_SHOWDIFFERENCES, m_pImgMergeWindow->GetShowDifferences()); - GetOptionsMgr()->SaveOption(OPT_CMP_IMG_OVERLAYMOVE, m_pImgMergeWindow->GetOverlayMode()); + GetOptionsMgr()->SaveOption(OPT_CMP_IMG_OVERLAYMODE, m_pImgMergeWindow->GetOverlayMode()); GetOptionsMgr()->SaveOption(OPT_CMP_IMG_OVERLAYALPHA, static_cast(m_pImgMergeWindow->GetOverlayAlpha() * 100)); GetOptionsMgr()->SaveOption(OPT_CMP_IMG_DRAGGING_MODE, static_cast(m_pImgMergeWindow->GetDraggingMode())); GetOptionsMgr()->SaveOption(OPT_CMP_IMG_ZOOM, static_cast(m_pImgMergeWindow->GetZoom() * 1000)); diff --git a/Src/OptionsDef.h b/Src/OptionsDef.h index b8dde2b6e..3353fc8bb 100644 --- a/Src/OptionsDef.h +++ b/Src/OptionsDef.h @@ -218,7 +218,7 @@ extern const String OPT_CMP_COMPLETELY_BLANK_OUT_IGNORED_CHANGES OP("Settings/Co // Image Compare options extern const String OPT_CMP_IMG_FILEPATTERNS OP("Settings/ImageFilePatterns"); extern const String OPT_CMP_IMG_SHOWDIFFERENCES OP("Settings/ImageShowDifferences"); -extern const String OPT_CMP_IMG_OVERLAYMOVE OP("Settings/ImageOverlayMode"); +extern const String OPT_CMP_IMG_OVERLAYMODE OP("Settings/ImageOverlayMode"); extern const String OPT_CMP_IMG_OVERLAYALPHA OP("Settings/ImageOverlayAlpha"); extern const String OPT_CMP_IMG_DRAGGING_MODE OP("Settings/ImageDraggingMode"); extern const String OPT_CMP_IMG_ZOOM OP("Settings/ImageZoom"); diff --git a/Src/OptionsDiffOptions.cpp b/Src/OptionsDiffOptions.cpp index 522f80745..0500625a5 100644 --- a/Src/OptionsDiffOptions.cpp +++ b/Src/OptionsDiffOptions.cpp @@ -16,12 +16,12 @@ namespace Options { namespace DiffOptions { */ void SetDefaults(COptionsMgr *pOptionsMgr) { - pOptionsMgr->InitOption(OPT_CMP_IGNORE_WHITESPACE, (int)0); + pOptionsMgr->InitOption(OPT_CMP_IGNORE_WHITESPACE, (int)0, 0, 2); pOptionsMgr->InitOption(OPT_CMP_IGNORE_BLANKLINES, false); pOptionsMgr->InitOption(OPT_CMP_FILTER_COMMENTLINES, false); pOptionsMgr->InitOption(OPT_CMP_IGNORE_CASE, false); pOptionsMgr->InitOption(OPT_CMP_IGNORE_EOL, false); - pOptionsMgr->InitOption(OPT_CMP_DIFF_ALGORITHM, (int)0); + pOptionsMgr->InitOption(OPT_CMP_DIFF_ALGORITHM, (int)0, 0, 3); pOptionsMgr->InitOption(OPT_CMP_INDENT_HEURISTIC, true); pOptionsMgr->InitOption(OPT_CMP_COMPLETELY_BLANK_OUT_IGNORED_CHANGES, false); } diff --git a/Src/OptionsFont.cpp b/Src/OptionsFont.cpp index c2c93b79a..15f1b63c5 100644 --- a/Src/OptionsFont.cpp +++ b/Src/OptionsFont.cpp @@ -96,7 +96,7 @@ void SetDefaults(COptionsMgr *pOptionsMgr) String name = (i == 0 ? OPT_FONT_FILECMP : OPT_FONT_DIRCMP); pOptionsMgr->InitOption(name + OPT_FONT_USECUSTOM, false); - pOptionsMgr->InitOption(name + OPT_FONT_POINTSIZE, ::MulDiv(abs(thisFont.lfHeight), 72, logPixelsY)); + pOptionsMgr->InitOption(name + OPT_FONT_POINTSIZE, ::MulDiv(abs(thisFont.lfHeight), 72, logPixelsY), 1, 72); pOptionsMgr->InitOption(name + OPT_FONT_HEIGHT, thisFont.lfHeight); pOptionsMgr->InitOption(name + OPT_FONT_ESCAPEMENT, thisFont.lfEscapement); pOptionsMgr->InitOption(name + OPT_FONT_ORIENTATION, thisFont.lfOrientation); diff --git a/Src/OptionsInit.cpp b/Src/OptionsInit.cpp index 18d31cd14..e80997311 100644 --- a/Src/OptionsInit.cpp +++ b/Src/OptionsInit.cpp @@ -65,7 +65,7 @@ void Init(COptionsMgr *pOptions) pOptions->InitOption(OPT_SHOW_TOOLBAR, true); pOptions->InitOption(OPT_SHOW_STATUSBAR, true); pOptions->InitOption(OPT_SHOW_TABBAR, true); - pOptions->InitOption(OPT_TOOLBAR_SIZE, 0); + pOptions->InitOption(OPT_TOOLBAR_SIZE, 0, 0, 2); pOptions->InitOption(OPT_RESIZE_PANES, false); pOptions->InitOption(OPT_SYNTAX_HIGHLIGHT, true); @@ -76,12 +76,12 @@ void Init(COptionsMgr *pOptions) pOptions->InitOption(OPT_SCROLL_TO_FIRST, false); pOptions->InitOption(OPT_SCROLL_TO_FIRST_INLINE_DIFF, false); pOptions->InitOption(OPT_VERIFY_OPEN_PATHS, true); - pOptions->InitOption(OPT_AUTO_COMPLETE_SOURCE, (int)1); + pOptions->InitOption(OPT_AUTO_COMPLETE_SOURCE, (int)1, 0, 2); pOptions->InitOption(OPT_VIEW_FILEMARGIN, false); pOptions->InitOption(OPT_DIFF_CONTEXT, (int)-1); pOptions->InitOption(OPT_INVERT_DIFF_CONTEXT, false); pOptions->InitOption(OPT_SPLIT_HORIZONTALLY, false); - pOptions->InitOption(OPT_RENDERING_MODE, -1); + pOptions->InitOption(OPT_RENDERING_MODE, -1, 0, 6); pOptions->InitOption(OPT_FILE_SIZE_THRESHOLD, 64*1024*1024); pOptions->InitOption(OPT_WORDDIFF_HIGHLIGHT, true); @@ -89,13 +89,13 @@ void Init(COptionsMgr *pOptions) pOptions->InitOption(OPT_BACKUP_FOLDERCMP, false); pOptions->InitOption(OPT_BACKUP_FILECMP, true); - pOptions->InitOption(OPT_BACKUP_LOCATION, (int)0); + pOptions->InitOption(OPT_BACKUP_LOCATION, (int)0, 0, 1); pOptions->InitOption(OPT_BACKUP_GLOBALFOLDER, _T("")); pOptions->InitOption(OPT_BACKUP_ADD_BAK, true); pOptions->InitOption(OPT_BACKUP_ADD_TIME, false); - pOptions->InitOption(OPT_DIRVIEW_SORT_COLUMN, (int)-1); - pOptions->InitOption(OPT_DIRVIEW_SORT_COLUMN3, (int)-1); + pOptions->InitOption(OPT_DIRVIEW_SORT_COLUMN, (int)-1, -1, 128); + pOptions->InitOption(OPT_DIRVIEW_SORT_COLUMN3, (int)-1, -1, 128); pOptions->InitOption(OPT_DIRVIEW_SORT_ASCENDING, true); pOptions->InitOption(OPT_SHOW_SELECT_FILES_AT_STARTUP, false); pOptions->InitOption(OPT_DIRVIEW_EXPAND_SUBDIRS, false); @@ -104,38 +104,38 @@ void Init(COptionsMgr *pOptions) pOptions->InitOption(OPT_DIRVIEW3_COLUMN_ORDERS, _T("")); pOptions->InitOption(OPT_DIRVIEW3_COLUMN_WIDTHS, _T("")); - pOptions->InitOption(OPT_REPORTFILES_REPORTTYPE, 0); + pOptions->InitOption(OPT_REPORTFILES_REPORTTYPE, 0, 0, 3); pOptions->InitOption(OPT_REPORTFILES_COPYTOCLIPBOARD, false); pOptions->InitOption(OPT_REPORTFILES_INCLUDEFILECMPREPORT, false); pOptions->InitOption(OPT_AUTOMATIC_RESCAN, false); pOptions->InitOption(OPT_ALLOW_MIXED_EOL, false); pOptions->InitOption(OPT_COPY_FULL_LINE, false); - pOptions->InitOption(OPT_TAB_SIZE, (int)4); - pOptions->InitOption(OPT_TAB_TYPE, (int)0); // 0 means tabs inserted + pOptions->InitOption(OPT_TAB_SIZE, (int)4, 0, 64); + pOptions->InitOption(OPT_TAB_TYPE, (int)0, 0, 1); // 0 means tabs inserted pOptions->InitOption(OPT_EXT_EDITOR_CMD, _T("%windir%\\NOTEPAD.EXE")); pOptions->InitOption(OPT_USE_RECYCLE_BIN, true); - pOptions->InitOption(OPT_SINGLE_INSTANCE, 0); + pOptions->InitOption(OPT_SINGLE_INSTANCE, 0, 0, 2); pOptions->InitOption(OPT_MERGE_MODE, false); // OPT_WORDDIFF_HIGHLIGHT is initialized above pOptions->InitOption(OPT_BREAK_ON_WORDS, false); - pOptions->InitOption(OPT_BREAK_TYPE, 1); + pOptions->InitOption(OPT_BREAK_TYPE, 1, 0, 1); - pOptions->InitOption(OPT_CLOSE_WITH_ESC, 1); + pOptions->InitOption(OPT_CLOSE_WITH_ESC, 1, 0, 2); pOptions->InitOption(OPT_CLOSE_WITH_OK, false); pOptions->InitOption(OPT_IGNORE_SMALL_FILETIME, false); pOptions->InitOption(OPT_ASK_MULTIWINDOW_CLOSE, false); pOptions->InitOption(OPT_PRESERVE_FILETIMES, false); pOptions->InitOption(OPT_TREE_MODE, true); - pOptions->InitOption(OPT_CMP_METHOD, (int)CMP_CONTENT); + pOptions->InitOption(OPT_CMP_METHOD, (int)CMP_CONTENT, 0, CMP_SIZE); pOptions->InitOption(OPT_CMP_MOVED_BLOCKS, false); pOptions->InitOption(OPT_CMP_MATCH_SIMILAR_LINES, false); pOptions->InitOption(OPT_CMP_STOP_AFTER_FIRST, false); pOptions->InitOption(OPT_CMP_QUICK_LIMIT, 4 * 1024 * 1024); // 4 Megs pOptions->InitOption(OPT_CMP_BINARY_LIMIT, 64 * 1024 * 1024); // 64 Megs - pOptions->InitOption(OPT_CMP_COMPARE_THREADS, -1); + pOptions->InitOption(OPT_CMP_COMPARE_THREADS, -1, -128, 128); pOptions->InitOption(OPT_CMP_WALK_UNIQUE_DIRS, true); pOptions->InitOption(OPT_CMP_IGNORE_REPARSE_POINTS, false); pOptions->InitOption(OPT_CMP_IGNORE_CODEPAGE, false); @@ -153,18 +153,18 @@ void Init(COptionsMgr *pOptions) pOptions->InitOption(OPT_CMP_IMG_FILEPATTERNS, _T("*.bmp;*.cut;*.dds;*.exr;*.g3;*.gif;*.hdr;*.ico;*.iff;*.lbm;*.j2k;*.j2c;*.jng;*.jp2;*.jpg;*.jif;*.jpeg;*.jpe;*.jxr;*.wdp;*.hdp;*.koa;*.mng;*.pcd;*.pcx;*.pfm;*.pct;*.pict;*.pic;*.png;*.pbm;*.pgm;*.ppm;*.psd;*.ras;*.sgi;*.rgb;*.rgba;*.bw;*.tga;*.targa;*.tif;*.tiff;*.wap;*.wbmp;*.wbm;*.webp;*.xbm;*.xpm")); pOptions->InitOption(OPT_CMP_IMG_SHOWDIFFERENCES, true); - pOptions->InitOption(OPT_CMP_IMG_OVERLAYMOVE, 0); - pOptions->InitOption(OPT_CMP_IMG_OVERLAYALPHA, 30); - pOptions->InitOption(OPT_CMP_IMG_DRAGGING_MODE, 1); - pOptions->InitOption(OPT_CMP_IMG_ZOOM, 1000); + pOptions->InitOption(OPT_CMP_IMG_OVERLAYMODE, 0, 0, 3); + pOptions->InitOption(OPT_CMP_IMG_OVERLAYALPHA, 30, 0, 100); + pOptions->InitOption(OPT_CMP_IMG_DRAGGING_MODE, 1, 0, 5); + pOptions->InitOption(OPT_CMP_IMG_ZOOM, 1000, 1, 8000); pOptions->InitOption(OPT_CMP_IMG_USEBACKCOLOR, true); pOptions->InitOption(OPT_CMP_IMG_BACKCOLOR, 0xFFFFFF); - pOptions->InitOption(OPT_CMP_IMG_DIFFBLOCKSIZE, 8); - pOptions->InitOption(OPT_CMP_IMG_DIFFCOLORALPHA, 70); - pOptions->InitOption(OPT_CMP_IMG_THRESHOLD, 0); - pOptions->InitOption(OPT_CMP_IMG_INSERTIONDELETIONDETECTION_MODE, 0); - pOptions->InitOption(OPT_CMP_IMG_VECTOR_IMAGE_ZOOM_RATIO, 1000); - pOptions->InitOption(OPT_CMP_IMG_OCR_RESULT_TYPE, 0); + pOptions->InitOption(OPT_CMP_IMG_DIFFBLOCKSIZE, 8, 0, 64); + pOptions->InitOption(OPT_CMP_IMG_DIFFCOLORALPHA, 70, 0, 100); + pOptions->InitOption(OPT_CMP_IMG_THRESHOLD, 0, 0, 442); + pOptions->InitOption(OPT_CMP_IMG_INSERTIONDELETIONDETECTION_MODE, 0, 0, 2); + pOptions->InitOption(OPT_CMP_IMG_VECTOR_IMAGE_ZOOM_RATIO, 1000, 1, 8000); + pOptions->InitOption(OPT_CMP_IMG_OCR_RESULT_TYPE, 0, 0, 2); pOptions->InitOption(OPT_PROJECTS_PATH, _T("")); pOptions->InitOption(OPT_USE_SYSTEM_TEMP_PATH, true); @@ -194,7 +194,7 @@ void Init(COptionsMgr *pOptions) else pOptions->InitOption(OPT_CP_DETECT, (int)(50001 << 16) | 1); - pOptions->InitOption(OPT_ARCHIVE_ENABLE, 1); // Enable by default + pOptions->InitOption(OPT_ARCHIVE_ENABLE, true); // Enable by default pOptions->InitOption(OPT_ARCHIVE_PROBETYPE, false); pOptions->InitOption(OPT_ARCHIVE_FILTER_INDEX, 1); @@ -205,20 +205,20 @@ void Init(COptionsMgr *pOptions) pOptions->InitOption(OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION, true); pOptions->InitOption(OPT_PLUGINS_OPEN_IN_SAME_FRAME_TYPE, false); - pOptions->InitOption(OPT_PATCHCREATOR_PATCH_STYLE, 0); + pOptions->InitOption(OPT_PATCHCREATOR_PATCH_STYLE, 0, 0, 3); pOptions->InitOption(OPT_PATCHCREATOR_CONTEXT_LINES, 0); pOptions->InitOption(OPT_PATCHCREATOR_CASE_SENSITIVE, true); pOptions->InitOption(OPT_PATCHCREATOR_EOL_SENSITIVE, true); pOptions->InitOption(OPT_PATCHCREATOR_IGNORE_BLANK_LINES, false); - pOptions->InitOption(OPT_PATCHCREATOR_WHITESPACE, WHITESPACE_COMPARE_ALL); + pOptions->InitOption(OPT_PATCHCREATOR_WHITESPACE, WHITESPACE_COMPARE_ALL, WHITESPACE_COMPARE_ALL, WHITESPACE_IGNORE_ALL); pOptions->InitOption(OPT_PATCHCREATOR_OPEN_TO_EDITOR, false); pOptions->InitOption(OPT_PATCHCREATOR_INCLUDE_CMD_LINE, false); pOptions->InitOption(OPT_TABBAR_AUTO_MAXWIDTH, true); pOptions->InitOption(OPT_ACTIVE_FRAME_MAX, true); - pOptions->InitOption(OPT_ACTIVE_PANE, 0); + pOptions->InitOption(OPT_ACTIVE_PANE, 0, 0, 2); - pOptions->InitOption(OPT_MRU_MAX, 9); + pOptions->InitOption(OPT_MRU_MAX, 9, 0, 128); pOptions->InitOption(OPT_COLOR_SCHEME, _T("Default")); diff --git a/Src/PropArchive.cpp b/Src/PropArchive.cpp index 9f7145a0d..2269ee9fb 100644 --- a/Src/PropArchive.cpp +++ b/Src/PropArchive.cpp @@ -44,7 +44,7 @@ END_MESSAGE_MAP() */ void PropArchive::ReadOptions() { - int enable = GetOptionsMgr()->GetInt(OPT_ARCHIVE_ENABLE); + int enable = GetOptionsMgr()->GetBool(OPT_ARCHIVE_ENABLE); m_bEnableSupport = enable > 0; m_bProbeType = GetOptionsMgr()->GetBool(OPT_ARCHIVE_PROBETYPE); } @@ -54,7 +54,7 @@ void PropArchive::ReadOptions() */ void PropArchive::WriteOptions() { - GetOptionsMgr()->SaveOption(OPT_ARCHIVE_ENABLE, (int)(m_bEnableSupport ? 1 : 0)); + GetOptionsMgr()->SaveOption(OPT_ARCHIVE_ENABLE, m_bEnableSupport); GetOptionsMgr()->SaveOption(OPT_ARCHIVE_PROBETYPE, m_bProbeType); } diff --git a/Testing/GoogleTest/GUITests/GUITestUtils.cpp b/Testing/GoogleTest/GUITests/GUITestUtils.cpp index 7f3c41676..d0178d85b 100644 --- a/Testing/GoogleTest/GUITests/GUITestUtils.cpp +++ b/Testing/GoogleTest/GUITests/GUITestUtils.cpp @@ -333,5 +333,118 @@ const char* languageIdToName(int id) return ""; } +static std::pair splitOptionName(const std::wstring& name) +{ + std::wstring key = L"Software\\Thingamahoochie\\WinMerge"; + key += L"\\" + name.substr(0, name.find('/')); + std::wstring name2 = name.substr(name.find('/') + 1); + return { key, name2 }; +} + +std::optional regReadBool(const std::wstring& name) +{ + std::optional value; + HKEY hKey = nullptr; + auto [keyname, valuename] = splitOptionName(name); + if (ERROR_SUCCESS == RegOpenKeyW(HKEY_CURRENT_USER, keyname.c_str(), &hKey)) + { + DWORD type = REG_DWORD, data = 0, size = 4; + if (ERROR_SUCCESS == RegQueryValueExW(hKey, valuename.c_str(), nullptr, &type, reinterpret_cast(&data), &size)) + value = data != 0; + RegCloseKey(hKey); + } + return value; +} + +std::optional regReadInt(const std::wstring& name) +{ + std::optional value; + HKEY hKey = nullptr; + auto [keyname, valuename] = splitOptionName(name); + if (ERROR_SUCCESS == RegOpenKeyW(HKEY_CURRENT_USER, keyname.c_str(), &hKey)) + { + DWORD type = REG_DWORD, data = 0, size = 4; + if (ERROR_SUCCESS == RegQueryValueExW(hKey, valuename.c_str(), nullptr, &type, reinterpret_cast(&data), &size)) + value = static_cast(data); + RegCloseKey(hKey); + } + return value; +} + +std::optional regReadString(const std::wstring& name) +{ + std::optional value; + HKEY hKey = nullptr; + auto [keyname, valuename] = splitOptionName(name); + if (ERROR_SUCCESS == RegOpenKeyW(HKEY_CURRENT_USER, keyname.c_str(), &hKey)) + { + std::vector data(65536); + DWORD type = REG_SZ, size = static_cast(data.size()); + if (ERROR_SUCCESS == RegQueryValueExW(hKey, valuename.c_str(), nullptr, &type, reinterpret_cast(data.data()), &size)) + value = data.data(); + RegCloseKey(hKey); + } + return value; +} + +bool regWrite(const std::wstring& name, bool value) +{ + bool result = false; + HKEY hKey = nullptr; + auto [keyname, valuename] = splitOptionName(name); + if (ERROR_SUCCESS == RegCreateKeyW(HKEY_CURRENT_USER, keyname.c_str(), &hKey)) + { + DWORD data = value; + if (ERROR_SUCCESS == RegSetValueExW(hKey, valuename.c_str(), 0, REG_DWORD, reinterpret_cast(&data), sizeof(DWORD))) + result = true; + RegCloseKey(hKey); + } + return result; +} + +bool regWrite(const std::wstring& name, int value) +{ + bool result = false; + HKEY hKey = nullptr; + auto [keyname, valuename] = splitOptionName(name); + if (ERROR_SUCCESS == RegCreateKeyW(HKEY_CURRENT_USER, keyname.c_str(), &hKey)) + { + DWORD data = value; + if (ERROR_SUCCESS == RegSetValueExW(hKey, valuename.c_str(), 0, REG_DWORD, reinterpret_cast(&data), sizeof(DWORD))) + result = true; + RegCloseKey(hKey); + } + return result; +} + +bool regWrite(const std::wstring& name, const std::wstring& value) +{ + bool result = false; + HKEY hKey = nullptr; + auto [keyname, valuename] = splitOptionName(name); + if (ERROR_SUCCESS == RegCreateKeyW(HKEY_CURRENT_USER, keyname.c_str(), &hKey)) + { + if (ERROR_SUCCESS == RegSetValueExW(hKey, valuename.c_str(), 0, REG_SZ, reinterpret_cast(value.c_str()), + static_cast((value.length() + 1) * sizeof(wchar_t)))) + result = true; + RegCloseKey(hKey); + } + return result; +} + +bool regDelete(const std::wstring& name) +{ + bool result = false; + HKEY hKey = nullptr; + auto [keyname, valuename] = splitOptionName(name); + if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CURRENT_USER, keyname.c_str(), 0, KEY_ALL_ACCESS, &hKey)) + { + if (ERROR_SUCCESS == RegDeleteValueW(hKey, valuename.c_str())) + result = true; + RegCloseKey(hKey); + } + return result; +} + } diff --git a/Testing/GoogleTest/GUITests/GUITestUtils.h b/Testing/GoogleTest/GUITests/GUITestUtils.h index f769c34b0..f2663716f 100644 --- a/Testing/GoogleTest/GUITests/GUITestUtils.h +++ b/Testing/GoogleTest/GUITests/GUITestUtils.h @@ -1,6 +1,7 @@ #include #include #include +#include namespace GUITestUtils { @@ -26,6 +27,13 @@ namespace GUITestUtils HWND execInstaller(const std::string& args = ""); const std::set languages(); const char * languageIdToName(int id); + std::optional regReadBool(const std::wstring& name); + std::optional regReadInt(const std::wstring& name); + std::optional regReadString(const std::wstring& name); + bool regWrite(const std::wstring& name, bool value); + bool regWrite(const std::wstring& name, int value); + bool regWrite(const std::wstring& name, const std::wstring& value); + bool regDelete(const std::wstring& name); } #define selectMenuAndSaveWindowImage(id) selectMenuAndSaveWindowImageHelper(id, #id) diff --git a/Testing/GoogleTest/GUITests/GUITests.vcxproj b/Testing/GoogleTest/GUITests/GUITests.vcxproj index ee1f652ba..c22019864 100644 --- a/Testing/GoogleTest/GUITests/GUITests.vcxproj +++ b/Testing/GoogleTest/GUITests/GUITests.vcxproj @@ -320,6 +320,7 @@ + diff --git a/Testing/GoogleTest/GUITests/GUITests.vcxproj.filters b/Testing/GoogleTest/GUITests/GUITests.vcxproj.filters index 33a4bee5a..ba87416f9 100644 --- a/Testing/GoogleTest/GUITests/GUITests.vcxproj.filters +++ b/Testing/GoogleTest/GUITests/GUITests.vcxproj.filters @@ -39,6 +39,9 @@ Source Files + + Source Files +