From 7cf648351ef87560c2bcb7d87c9e291ad2bfc7ab Mon Sep 17 00:00:00 2001 From: rkotten Date: Wed, 22 Mar 2023 15:43:57 +0100 Subject: [PATCH 1/3] +rfc: fallback on LoadIconWithScaleDown() failed --- language/common_res.h | 21 ++--- lexilla/Lexilla.vcxproj | 3 +- scintilla/Scintilla.vcxproj | 3 +- src/DarkMode/user32-stub/user32-stub.vcxproj | 2 +- .../uxtheme-stub/uxtheme-stub.vcxproj | 2 +- src/Notepad3.c | 82 ++++++++++--------- src/Notepad3.vcxproj | 5 +- 7 files changed, 64 insertions(+), 54 deletions(-) diff --git a/language/common_res.h b/language/common_res.h index 8f3302983..b54b60bdd 100644 --- a/language/common_res.h +++ b/language/common_res.h @@ -65,6 +65,17 @@ // ========================================== +#define IDR_MAINWND 1000 +#define IDR_MAINWNDTB 1001 +#define IDR_MAINWNDTBHOT 1002 +#define IDR_MAINWNDTBDIS 1003 +#define IDR_MAINWNDTB2 1004 +#define IDR_MAINWNDTB2HOT 1005 +#define IDR_MAINWNDTB2DIS 1006 +#define IDR_STD_DARKMODE_THEME 1050 + +// ========================================== + #ifndef IDC_STATIC #define IDC_STATIC (-1) #endif @@ -259,16 +270,6 @@ #define IDS_MUI_SB_RECODING_DOC 15505 #define IDS_MUI_SB_LEXER_STYLING 15506 -#define IDR_MAINWND 16000 -#define IDR_MAINWNDTB 16001 -#define IDR_MAINWNDTBHOT 16002 -#define IDR_MAINWNDTBDIS 16003 -#define IDR_MAINWNDTB2 16004 -#define IDR_MAINWNDTB2HOT 16005 -#define IDR_MAINWNDTB2DIS 16006 - -#define IDR_STD_DARKMODE_THEME 16050 - #define IDI_MUI_RUN 16100 #define IDI_MUI_STYLES 16101 diff --git a/lexilla/Lexilla.vcxproj b/lexilla/Lexilla.vcxproj index ce4d50678..67be12d06 100644 --- a/lexilla/Lexilla.vcxproj +++ b/lexilla/Lexilla.vcxproj @@ -252,7 +252,7 @@ MultiThreadedDebug false - + false false false true @@ -369,6 +369,7 @@ stdc17 ProgramDatabase /utf-8 %(AdditionalOptions) + false Console diff --git a/scintilla/Scintilla.vcxproj b/scintilla/Scintilla.vcxproj index 16da66d66..5056d1196 100644 --- a/scintilla/Scintilla.vcxproj +++ b/scintilla/Scintilla.vcxproj @@ -149,7 +149,7 @@ MultiThreadedDebug Level4 false - + false true @@ -189,6 +189,7 @@ true stdc17 /utf-8 %(AdditionalOptions) + false MachineX64 diff --git a/src/DarkMode/user32-stub/user32-stub.vcxproj b/src/DarkMode/user32-stub/user32-stub.vcxproj index d442e155e..c6819d452 100644 --- a/src/DarkMode/user32-stub/user32-stub.vcxproj +++ b/src/DarkMode/user32-stub/user32-stub.vcxproj @@ -61,8 +61,8 @@ Win32Proj {1f757558-0e57-4de5-82d6-a14e9d81f05f} user32stub - 10.0 user32-stub + diff --git a/src/DarkMode/uxtheme-stub/uxtheme-stub.vcxproj b/src/DarkMode/uxtheme-stub/uxtheme-stub.vcxproj index 9931596c5..55043dec0 100644 --- a/src/DarkMode/uxtheme-stub/uxtheme-stub.vcxproj +++ b/src/DarkMode/uxtheme-stub/uxtheme-stub.vcxproj @@ -61,7 +61,7 @@ Win32Proj {0873b090-7ffd-4abd-9b42-619a06c5041f} uxthemestub - 10.0 + uxtheme-stub diff --git a/src/Notepad3.c b/src/Notepad3.c index f056c2086..31f12b08b 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -91,17 +91,18 @@ CONSTANTS_T const Constants = { }; -FLAGS_T Flags; -FLAGS_T DefaultFlags; +FLAGS_T Flags = { 0 }; +FLAGS_T DefaultFlags = { 0 }; -PATHS_T Paths; -GLOBALS_T Globals; -SETTINGS_T Settings; -SETTINGS_T Defaults; -SETTINGS2_T Settings2; +GLOBALS_T Globals = { 0 }; +SETTINGS_T Settings = { 0 }; +SETTINGS_T Defaults = { 0 }; +SETTINGS2_T Settings2 = { 0 }; -FOCUSEDVIEW_T FocusedView; -FILEWATCHING_T FileWatching; +PATHS_T Paths = { 0 }; + +FOCUSEDVIEW_T FocusedView = { 0 }; +FILEWATCHING_T FileWatching = { 0 }; // set by InitScintillaHandle() HWND g_hwndEditWindow = NULL; @@ -113,8 +114,8 @@ WININFO g_DefWinInfo = INIT_WININFO; COLORREF g_colorCustom[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -prefix_t g_mxSBPrefix[STATUS_SECTOR_COUNT]; -prefix_t g_mxSBPostfix[STATUS_SECTOR_COUNT]; +prefix_t g_mxSBPrefix[STATUS_SECTOR_COUNT] = { L'\0' }; +prefix_t g_mxSBPostfix[STATUS_SECTOR_COUNT] = { L'\0' }; int g_flagMatchText = 0; bool g_iStatusbarVisible[STATUS_SECTOR_COUNT] = SBS_INIT_ZERO; @@ -125,7 +126,7 @@ HPATHL g_tchToolbarBitmap = NULL; HPATHL g_tchToolbarBitmapHot = NULL; HPATHL g_tchToolbarBitmapDisabled = NULL; -WCHAR Default_PreferredLanguageLocaleName[LOCALE_NAME_MAX_LENGTH + 1]; +WCHAR Default_PreferredLanguageLocaleName[LOCALE_NAME_MAX_LENGTH + 1] = { L'\0' }; // ------------------------------------ @@ -159,14 +160,14 @@ static bool s_bLastCopyFromMe = false; static bool s_bInMultiEditMode = false; static bool s_bCallTipEscDisabled = false; -static int s_iInitialLine; -static int s_iInitialColumn; -static int s_iInitialLexer; +static int s_iInitialLine = 0; +static int s_iInitialColumn = 0; +static int s_iInitialLexer = 0; -static int s_cyReBar; -static int s_cyReBarFrame; -static int s_cxEditFrame; -static int s_cyEditFrame; +static int s_cyReBar = 0; +static int s_cyReBarFrame = 0; +static int s_cxEditFrame = 0; +static int s_cyEditFrame = 0; static bool s_bUndoRedoScroll = false; // for tiny expression calculation @@ -712,15 +713,6 @@ static void _UpdateTitlebarDelayed(const HWND hwnd); static void _InitGlobals() { - ZeroMemory(&Paths, sizeof(PATHS_T)); - ZeroMemory(&Globals, sizeof(GLOBALS_T)); - ZeroMemory(&Defaults, sizeof(SETTINGS_T)); - ZeroMemory(&Settings, sizeof(SETTINGS_T)); - ZeroMemory(&Settings2, sizeof(SETTINGS2_T)); - ZeroMemory(&Flags, sizeof(FLAGS_T)); - - ZeroMemory(&(Globals.fvCurFile), sizeof(FILEVARS)); - Globals.hLngResContainer = NULL; Globals.hDlgIcon256 = NULL; @@ -1180,33 +1172,49 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, int const cxs = GetSystemMetrics(SM_CXSMICON) << 1; int const cys = GetSystemMetrics(SM_CYSMICON) << 1; - //UINT const fuLoad = LR_DEFAULTCOLOR | LR_SHARED; + UINT const fuLoad = LR_DEFAULTCOLOR | LR_SHARED; if (!Globals.hDlgIcon256) { - LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), 256, 256, &(Globals.hDlgIcon256)); + if (FAILED(LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), 256, 256, &(Globals.hDlgIcon256)))) { + Globals.hDlgIcon256 = LoadImage(hInstance, MAKEINTRESOURCE(IDR_MAINWND), IMAGE_ICON, 256, 256, fuLoad); + } } if (!Globals.hDlgIcon128) { - LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), 128, 128, &(Globals.hDlgIcon128)); + if (FAILED(LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), 128, 128, &(Globals.hDlgIcon128)))) { + Globals.hDlgIcon128 = LoadImage(hInstance, MAKEINTRESOURCE(IDR_MAINWND), IMAGE_ICON, 128, 128, fuLoad); + } } if (!Globals.hDlgIconBig) { - LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), cxb, cyb, &(Globals.hDlgIconBig)); + if (FAILED(LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), cxb, cyb, &(Globals.hDlgIconBig)))) { + Globals.hDlgIconBig = LoadImage(hInstance, MAKEINTRESOURCE(IDR_MAINWND), IMAGE_ICON, cxb, cyb, fuLoad); + } } if (!Globals.hDlgIconSmall) { - LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), cxs, cys, &(Globals.hDlgIconSmall)); + if (FAILED(LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), cxs, cys, &(Globals.hDlgIconSmall)))) { + Globals.hDlgIconSmall = LoadImage(hInstance, MAKEINTRESOURCE(IDR_MAINWND), IMAGE_ICON, cxs, cys, fuLoad); + } } if (!Globals.hDlgIconPrefs256) { - LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), 256, 256, &(Globals.hDlgIconPrefs256)); + if (FAILED(LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), 256, 256, &(Globals.hDlgIconPrefs256)))) { + Globals.hDlgIconPrefs256 = LoadImage(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), IMAGE_ICON, 256, 256, fuLoad); + } } if (!Globals.hDlgIconPrefs128) { - LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), 128, 128, &(Globals.hDlgIconPrefs128)); + if (FAILED(LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), 128, 128, &(Globals.hDlgIconPrefs128)))) { + Globals.hDlgIconPrefs128 = LoadImage(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), IMAGE_ICON, 128, 128, fuLoad); + } } if (!Globals.hDlgIconPrefs64) { - LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), 64, 64, &(Globals.hDlgIconPrefs64)); + if (FAILED(LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), 64, 64, &(Globals.hDlgIconPrefs64)))) { + Globals.hDlgIconPrefs64 = LoadImage(hInstance, MAKEINTRESOURCE(IDI_MUI_STYLES), IMAGE_ICON, 64, 64, fuLoad); + } } if (!Globals.hIconMsgUser) { - LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), cxb, cyb, &(Globals.hIconMsgUser)); + if (FAILED(LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDR_MAINWND), cxb, cyb, &(Globals.hIconMsgUser)))) { + Globals.hIconMsgUser = LoadImage(hInstance, MAKEINTRESOURCE(IDR_MAINWND), IMAGE_ICON, cxb, cyb, fuLoad); + } } if (!Globals.hIconMsgInfo) { LoadIconWithScaleDown(NULL, IDI_INFORMATION, cxb, cyb, &(Globals.hIconMsgInfo)); diff --git a/src/Notepad3.vcxproj b/src/Notepad3.vcxproj index 03271047f..5a8c96629 100644 --- a/src/Notepad3.vcxproj +++ b/src/Notepad3.vcxproj @@ -181,7 +181,7 @@ false /Zc:threadSafeInit /utf-8 %(AdditionalOptions) Sync - + false false true stdc17 @@ -254,8 +254,7 @@ /Zc:threadSafeInit /utf-8 %(AdditionalOptions) Sync - - + false false true stdc17 From c234a469037d86a37e593382db3f85df78667691 Mon Sep 17 00:00:00 2001 From: rkotten Date: Thu, 23 Mar 2023 18:17:09 +0100 Subject: [PATCH 2/3] Option for ASAN Dbg to not throw exception --- Notepad3_sln_ASAN.cmd | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Notepad3_sln_ASAN.cmd diff --git a/Notepad3_sln_ASAN.cmd b/Notepad3_sln_ASAN.cmd new file mode 100644 index 000000000..2a867edeb --- /dev/null +++ b/Notepad3_sln_ASAN.cmd @@ -0,0 +1,13 @@ +@echo off +setlocal enableextensions +set SDIR=%~dp0 + +set DEVENV=C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe + +set SLN=%SDIR%Notepad3.sln + +set ASAN_OPTIONS=windows_hook_legacy_allocators=false + +"%DEVENV%" "%SLN%" + +endlocal From d95cff857c81e5e9620cdd706ac87b8aab06090c Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Fri, 24 Mar 2023 13:06:23 +0100 Subject: [PATCH 3/3] + fix: Book/Change-Mmarker search: high prio on Book-Marker --- Notepad3_sln_ASAN.cmd | 7 +- src/Edit.c | 145 +++++++++++++++++++++--------------------- src/Version.h | 2 +- 3 files changed, 80 insertions(+), 74 deletions(-) diff --git a/Notepad3_sln_ASAN.cmd b/Notepad3_sln_ASAN.cmd index 2a867edeb..ca7e02e5b 100644 --- a/Notepad3_sln_ASAN.cmd +++ b/Notepad3_sln_ASAN.cmd @@ -2,12 +2,15 @@ setlocal enableextensions set SDIR=%~dp0 -set DEVENV=C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe +::set DEVENV=C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe +set DEVENV=C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.exe set SLN=%SDIR%Notepad3.sln set ASAN_OPTIONS=windows_hook_legacy_allocators=false -"%DEVENV%" "%SLN%" +start "devenv" /MAX /B "%DEVENV%" "%SLN%" endlocal +::pause +exit diff --git a/src/Edit.c b/src/Edit.c index 056084126..f9f49e46d 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -9421,16 +9421,24 @@ void EditSetBookmarkList(HWND hwnd, LPCWSTR pszBookMarks) #define NOT_FOUND_LN ((DocLn)-1) -__forceinline int _GetAllNP3Markers(const DocLn iLine) { - return (SciCall_MarkerGet(iLine) & (ALL_MARKERS_BITMASK() | CHANGE_HISTORY_MARKER_BITMASK())); -} +static int _RespectLastSearch(const int bitmask, const DocLn iLine) +{ + static int _LastSearchBitmask = BOOKMARK_BITMASK(); + static DocLn _LastSearchStart = NOT_FOUND_LN; -static int _RespectLastSearch(const int bitmask) { - static int s_LastSearchBitmask = 0; - if (!(bitmask & s_LastSearchBitmask)) { - s_LastSearchBitmask = bitmask; + if (iLine == _LastSearchStart) { + if (bitmask & _LastSearchBitmask) { + return _LastSearchBitmask; + } } - return s_LastSearchBitmask; + if (bitmask & BOOKMARK_BITMASK()) { // BOOKMARKS got prio + _LastSearchBitmask = BOOKMARK_BITMASK(); + } + else { + _LastSearchBitmask = bitmask ? bitmask : BOOKMARK_BITMASK(); + } + _LastSearchStart = iLine; + return _LastSearchBitmask; } @@ -9448,46 +9456,43 @@ static inline DocLn _MarkerNext(const DocLn iLine, const int bitmask) return SciCall_MarkerNext(iLine, bitmask); } + void EditBookmarkNext(HWND hwnd, DocLn iLine) { UNREFERENCED_PARAMETER(hwnd); - DocLn iNextLine = NOT_FOUND_LN; - bool bWrapedAround = true; - do { - int bitmask = _RespectLastSearch(_GetAllNP3Markers(iLine)); - if (!bitmask) { - bitmask = BOOKMARK_BITMASK(); + + int bitmask = _RespectLastSearch(SciCall_MarkerGet(iLine), iLine); + DocLn iNextLine = _MarkerNext(iLine + 1, bitmask); + + // skip consecutive change marker + if (bitmask & CHANGE_HISTORY_MARKER_BITMASK()) { + while ((iLine + 1) == iNextLine) { + iNextLine = _MarkerNext(++iLine + 1, bitmask); } + } + + if ((iNextLine == NOT_FOUND_LN) && (iLine > 0)) { + iNextLine = _MarkerNext(0, bitmask); // wrap around + } + + if (iNextLine == NOT_FOUND_LN) { // find any bookmark + bitmask = ALL_MARKERS_BITMASK(); iNextLine = _MarkerNext(iLine + 1, bitmask); - if (iNextLine == NOT_FOUND_LN) { + if ((iNextLine == NOT_FOUND_LN) && (iLine > 0)) { iNextLine = _MarkerNext(0, bitmask); // wrap around } - if (iNextLine == NOT_FOUND_LN) { - bitmask = ALL_MARKERS_BITMASK(); - iNextLine = _MarkerNext(iLine + 1, bitmask); // find any bookmark + } + + if (iNextLine == NOT_FOUND_LN) { // find change history marker + bitmask = CHANGE_HISTORY_MARKER_BITMASK(); + iNextLine = _MarkerNext(iLine + 1, bitmask); + if ((iNextLine == NOT_FOUND_LN) && (iLine > 0)) { + iNextLine = _MarkerNext(0, bitmask); // wrap around } - if (iNextLine == NOT_FOUND_LN) { - bitmask = CHANGE_HISTORY_MARKER_BITMASK(); - iNextLine = _MarkerNext(iLine + 1, bitmask); // find change history marker - } - if (iNextLine == NOT_FOUND_LN) { - // initial search not started from beginning? - if (iLine != 0) { - iLine = 0; - } - } - else { // check for consecutive change marker - if (bitmask & CHANGE_HISTORY_MARKER_BITMASK()) { - while ((iLine + 1) == iNextLine) { - iLine = iNextLine; - iNextLine = _MarkerNext(iLine + 1, bitmask); - } - } - } - bWrapedAround = !bWrapedAround; - } while ((iNextLine == NOT_FOUND_LN) && !bWrapedAround); + } if (iNextLine != NOT_FOUND_LN) { + _RespectLastSearch(bitmask, iNextLine); // reset SciCall_GotoLine(iNextLine); } } @@ -9512,47 +9517,45 @@ static inline DocLn _MarkerPrevious(const DocLn iLine, const int bitmask) void EditBookmarkPrevious(HWND hwnd, DocLn iLine) { UNREFERENCED_PARAMETER(hwnd); - DocLn iPrevLine = NOT_FOUND_LN; - bool bWrapedAround = true; - do { - int bitmask = _RespectLastSearch(_GetAllNP3Markers(iLine)); - if (!bitmask) { - bitmask = BOOKMARK_BITMASK(); + + DocLn const docLnCount = SciCall_GetLineCount(); + + int bitmask = _RespectLastSearch(SciCall_MarkerGet(iLine), iLine); + iLine = (iLine <= 0) ? docLnCount + 1 : iLine; + DocLn iPrevLine = _MarkerPrevious(iLine - 1, bitmask); + + // skip consecutive change marker + if (bitmask & CHANGE_HISTORY_MARKER_BITMASK()) { + while ((iLine - 1) == iPrevLine) { + iPrevLine = _MarkerPrevious(--iLine - 1, bitmask); } - iLine = (iLine <= 0) ? SciCall_GetLineCount() + 1 : iLine; + } + + if ((iPrevLine == NOT_FOUND_LN) && (iLine < docLnCount)) { + iPrevLine = _MarkerPrevious(docLnCount, bitmask); // wrap around + } + + if (iPrevLine == NOT_FOUND_LN) { // find any bookmark + bitmask = ALL_MARKERS_BITMASK(); iPrevLine = _MarkerPrevious(iLine - 1, bitmask); - if (iPrevLine == NOT_FOUND_LN) { - iPrevLine = _MarkerPrevious(SciCall_GetLineCount(), bitmask); // wrap around + if ((iPrevLine == NOT_FOUND_LN) && (iLine < docLnCount)) { + iPrevLine = _MarkerPrevious(docLnCount, bitmask); // wrap around } - if (iPrevLine == NOT_FOUND_LN) { - bitmask = ALL_MARKERS_BITMASK(); - iPrevLine = _MarkerPrevious(iLine - 1, bitmask); // find any bookmark + } + + if (iPrevLine == NOT_FOUND_LN) { // find change history marker + bitmask = CHANGE_HISTORY_MARKER_BITMASK(); + iPrevLine = _MarkerPrevious(iLine - 1, bitmask); + if ((iPrevLine == NOT_FOUND_LN) && (iLine < docLnCount)) { + iPrevLine = _MarkerPrevious(docLnCount, bitmask); // wrap around } - if (iPrevLine == NOT_FOUND_LN) { - bitmask = CHANGE_HISTORY_MARKER_BITMASK(); - iPrevLine = _MarkerPrevious(iLine - 1, bitmask); // find change history marker - } - if (iPrevLine == NOT_FOUND_LN) { - // initial search not started from bottom? - if (iLine != SciCall_GetLineCount()) { - iLine = SciCall_GetLineCount(); - } - } - else { // check for consecutive change marker - if (bitmask & CHANGE_HISTORY_MARKER_BITMASK()) { - while ((iLine - 1) == iPrevLine) { - iLine = iPrevLine; - iPrevLine = _MarkerPrevious(iLine - 1, bitmask); - } - } - } - bWrapedAround = !bWrapedAround; - } while ((iPrevLine == NOT_FOUND_LN) && !bWrapedAround); + } if (iPrevLine != NOT_FOUND_LN) { // find beginning of consecutive change marker - int const bm = _GetAllNP3Markers(iPrevLine); + int const bm = bitmask & CHANGE_HISTORY_MARKER_BITMASK(); while ((--iPrevLine >= 0) && (bm & SciCall_MarkerGet(iPrevLine))) {} + _RespectLastSearch(bitmask, iPrevLine + 1); // reset SciCall_GotoLine(iPrevLine + 1); } } diff --git a/src/Version.h b/src/Version.h index 6978065a2..7b01528c6 100644 --- a/src/Version.h +++ b/src/Version.h @@ -198,7 +198,7 @@ inline LPCWSTR _Win10BuildToReleaseId(const DWORD build) #endif #elif (_MSC_VER == 1929) #if (_MSC_FULL_VER >= 192930148) - #define VER_CPL MS Visual C++ 2019 v16.11.24 + #define VER_CPL MS Visual C++ 2019 v16.11.(24-25) #elif (_MSC_FULL_VER >= 192930147) #define VER_CPL MS Visual C++ 2019 v16 .11.(21-23) #elif (_MSC_FULL_VER >= 192930146)