21 Commits
v2.3.8 ... dev

Author SHA1 Message Date
c563d394c6 Fixed year in readme.md. 2025-05-09 17:18:08 +03:00
5f6e1cd068 Release v1.3.10 2025-05-09 16:48:53 +03:00
9a9b82b981 Added ES_NUMBER flag to editboxes of Manual Editing Dialog. 2025-05-09 16:36:09 +03:00
8bfa651cb9 Fixed updater's logging. 2025-05-09 16:19:39 +03:00
3f646683aa Fixed updater's logging codepage. 2025-05-09 14:55:53 +03:00
75b31b5489 Fixed logging codepage.
So it should work on Windows 7.
2025-05-09 14:23:09 +03:00
386f2df1da Changed path to logfile in debug mode. 2025-05-03 17:09:31 +03:00
822f0dc7b7 Dropped toolset to v142. 2025-05-03 17:07:44 +03:00
6b0a7265a7 Release 1.3.9 2025-05-03 16:59:52 +03:00
62ae981ff0 Removed old About dialog from resources. 2024-03-03 14:10:40 +03:00
bd6cabdc6b Fixed README.md. 2024-03-03 13:59:21 +03:00
7d1d7b2456 Reworked About dialog. 2024-03-03 13:38:33 +03:00
422284a81d Updated About window. 2024-03-03 12:35:10 +03:00
0de71bfe21 Fixed tray icon handling after Explorer restarts. 2024-03-02 15:57:05 +03:00
c81de4f897 Fixed README.md. 2024-02-29 18:14:11 +03:00
29ac0eff94 Removed license info from source and header files.
Also edited LICENSE and README.md files.
2024-02-29 18:02:06 +03:00
86bab7a53b Added the name of the app's icon author to the About dialog. 2024-02-26 12:01:17 +03:00
a141add693 Fixed casting wParam. 2024-02-25 21:24:58 +03:00
826a9e1c74 Fixed the popup menu not appearing after restarting the explorer. 2024-02-25 19:09:50 +03:00
2b55035234 Changed code formatting. 2024-02-16 01:17:39 +03:00
b09c969798 Fixed the algorithm of calculating window centering. 2024-02-16 00:57:20 +03:00
16 changed files with 864 additions and 1212 deletions

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2023 W0LF aka 'dreamforce'
Copyright (c) 2020-2024 Vladislav Salikov aka W0LF
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,48 +1,34 @@
## wCenterWindow
## wCenterWindow
This program centers the current active window by a `LCTRL + LWIN + C` hotkey,
or pressing `LCTRL + LWIN + MMB` (Middle Mouse Button).
Copyright (c) 2020-2025 Vladislav Salikov aka W0LF.<br>
Program icon made by Kirill Topov.
---
This program centers the current active window by a `LCTRL + LWIN + C` hotkey, or pressing `LCTRL + LWIN + MMB` (Middle Mouse Button).
`LCTRL + LWIN + V` - manual editing of size and position of the window.
You can use `LCTRL + LWIN + I` hotkey for hide/show trayicon.
You can also use commandline option `/hide` for hide trayicon at startup.
`LCTRL + LWIN + I` hotkey is used to hide/show trayicon.
You can also use commandline option `/hide` to hide trayicon at startup.
The `/noupdate` option is used to disable check for updates. By default, the program checks for updates upon startup and once a day.
The `/noupdate` commandline option is used to disable check for updates. By default, the program checks for updates upon startup and once a day.
The `Use workarea` option means that the window is centered without a taskbar, otherwise, the full resolution of the monitor will be used.
The `Use workarea` option (at popup menu) means that the window is centered without a taskbar, otherwise, the full resolution of the monitor will be used.
If some windows does not centers you should run wCenterWindow with administrative rights.
If some windows does not centers, you should run wCenterWindow with administrative rights.
## Automatic startup
Usually, to start the application when Windows starts, it is enough to put the application's shortcut in the "Startup" folder -\
"C:\Users\\<*Your user name*>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup". (The easiest way to get there - press 'WIN + R' and type 'shell:startup').\
Usually, to start the application when Windows starts, it is enough to put the application's shortcut in the "Startup" folder -
"C:\Users\\<*Your user name*>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup".
(The easiest way to get there - press 'WIN + R' and type `shell:startup`).<br>
However, in this case wCenterWindow will not be able to work with windows that are open with elevated privileges.
And if you enable the "Run as administrator" option in the shortcut, then wCenterWindow will not start. This is related to the security of Windows (maybe only in 10/11, I did not check).\
This behavior can be bypassed by creating a task in the Task Scheduler with the "Run with highest privileges" option.\
And if you enable the "Run as administrator" option in the shortcut, then wCenterWindow will not start. This is related to the security of Windows (maybe only in 10/11, I did not check).
This behavior can be bypassed by creating a task in the Task Scheduler with the "Run with highest privileges" option.<br>
**Note:** If you run wCenterWindow via the Task Scheduler, I highly recommend enabling the "Delay task for" option for 15-30 seconds, otherwise you may get an error message "Can't create tray icon".
## License
MIT License
Copyright (c) 2023 W0LF aka 'dreamforce'
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This software is licensed under a [MIT License](https://mit-license.org).<br>
This software uses the [PicoJSON](https://github.com/kazuho/picojson) - a C++ JSON parser / serializer by Kazuho Oku.

View File

@@ -1,25 +1,3 @@
## MIT License
##
## Copyright (c) 2023 W0LF aka 'dreamforce'
##
## Permission is hereby granted, free of charge, to any person obtaining a copy
## of this software and associated documentation files (the "Software"), to deal
## in the Software without restriction, including without limitation the rights
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
## copies of the Software, and to permit persons to whom the Software is
## furnished to do so, subject to the following conditions:
##
## The above copyright notice and this permission notice shall be included in all
## copies or substantial portions of the Software.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
## SOFTWARE.
# Update Version v2.1
# Required module: PSIni
# Installation: Install-Module -Name PsIni

Binary file not shown.

View File

@@ -1,25 +1,4 @@
@ECHO OFF
:: MIT License
::
:: Copyright (c) 2023 W0LF aka 'dreamforce'
::
:: Permission is hereby granted, free of charge, to any person obtaining a copy
:: of this software and associated documentation files (the "Software"), to deal
:: in the Software without restriction, including without limitation the rights
:: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
:: copies of the Software, and to permit persons to whom the Software is
:: furnished to do so, subject to the following conditions:
::
:: The above copyright notice and this permission notice shall be included in all
:: copies or substantial portions of the Software.
::
:: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
:: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
:: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
:: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
:: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
:: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
:: SOFTWARE.
:: In VisualStudio add to Pre-Build events:
:: "$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)"

View File

@@ -1,26 +1,4 @@
// MIT License
//
// Copyright (c) 2023 W0LF aka 'dreamforce'
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// wCenterWindow
// wCenterWindow
// CLogger.cpp
#include "CLogger.h"
@@ -28,80 +6,78 @@
#include <filesystem>
#include <strsafe.h>
inline wchar_t* CLogger::GetTimeStamp()
{
GetLocalTime(&lt);
StringCchPrintfW(logTimeBuffer, _countof(logTimeBuffer), L"%d-%02d-%02d %02d:%02d:%02d.%03d | ", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds);
return logTimeBuffer;
// Convert a wide Unicode string to an UTF8 string
std::string CLogger::ConvU16U8(const std::wstring& wstr) {
if (wstr.empty()) return std::string();
int size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
std::string str_out(size, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str_out[0], size, NULL, NULL);
return str_out;
}
void CLogger::Out(const wchar_t* fmt, ...)
{
if (fsLogFile.is_open())
{
va_list args;
va_start(args, fmt);
EnterCriticalSection(&cs);
StringCchVPrintfW(logBuffer, _countof(logBuffer), fmt, args);
va_end(args);
fsLogFile << GetTimeStamp() << logBuffer << std::endl;
LeaveCriticalSection(&cs);
}
inline wchar_t* CLogger::GetTimeStamp() {
GetLocalTime(&lt);
StringCchPrintfW(logTimeBuffer, _countof(logTimeBuffer), L"%d-%02d-%02d %02d:%02d:%02d.%03d | ", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds);
return logTimeBuffer;
}
void CLogger::Init()
{
wchar_t szPath[MAX_PATH] = { 0 };
DWORD dwPathLength = GetModuleFileNameW(NULL, szPath, MAX_PATH);
DWORD dwError = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == dwError)
{
MessageBoxW(NULL, L"Warning!\nPath to log file is too long! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
return;
}
if (NULL == dwPathLength)
{
MessageBoxW(NULL, L"Warning!\nCan't get application's filename! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
return;
}
void CLogger::Out(const wchar_t* fmt, ...) {
if (fsLogFile.is_open()) {
va_list args;
va_start(args, fmt);
EnterCriticalSection(&cs);
StringCchVPrintfW(logBuffer, _countof(logBuffer), fmt, args);
va_end(args);
fsLogFile << ConvU16U8(GetTimeStamp()) << ConvU16U8(logBuffer) << std::endl;
LeaveCriticalSection(&cs);
}
}
std::filesystem::path log_path = szPath;
log_path.replace_extension(L".log");
std::filesystem::path bak_path = log_path;
bak_path.replace_extension(L".bak");
void CLogger::Init() {
wchar_t szPath[MAX_PATH] = { 0 };
DWORD dwPathLength = GetModuleFileNameW(NULL, szPath, MAX_PATH);
DWORD dwError = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == dwError) {
MessageBoxW(NULL, L"Warning!\nPath to log file is too long! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
return;
}
if (NULL == dwPathLength) {
MessageBoxW(NULL, L"Warning!\nCan't get application's filename! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
return;
}
if (std::filesystem::exists(log_path)) std::filesystem::rename(log_path, bak_path);
std::filesystem::path log_path = szPath;
log_path.replace_extension(L".log");
std::filesystem::path bak_path = log_path;
bak_path.replace_extension(L".bak");
if (std::filesystem::exists(log_path)) std::filesystem::rename(log_path, bak_path);
#ifdef _DEBUG
log_path = L"D:\\test.log";
log_path = L"test.log";
#endif
fsLogFile.open(log_path, std::ios::trunc);
if (fsLogFile.is_open())
{
InitializeCriticalSection(&cs);
fsLogFile << "\xEF\xBB\xBF"; // (0xEF, 0xBB, 0xBF) - UTF-8 BOM
fsLogFile.imbue(std::locale("en-US.utf8"));
fsLogFile << GetTimeStamp() << "[ " << szAppTitleVer.c_str() << " ] Start log." << std::endl;
fsLogFile << GetTimeStamp() << "Logfile: \"" << log_path.native() << "\"" << std::endl;
}
else
{
MessageBoxW(NULL, L"Warning!\nCan't create log file! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
}
fsLogFile.open(log_path, std::ios::trunc);
if (fsLogFile.is_open()) {
InitializeCriticalSection(&cs);
fsLogFile << "\xEF\xBB\xBF"; // (0xEF, 0xBB, 0xBF) - UTF-8 BOM
fsLogFile.imbue(std::locale(".UTF-8"));
fsLogFile << ConvU16U8(GetTimeStamp()) << "[ " << ConvU16U8(szAppTitleVer).c_str() << " ] Start log." << std::endl;
fsLogFile << ConvU16U8(GetTimeStamp()) << "Logfile: \"" << ConvU16U8(log_path.native()) << "\"" << std::endl;
}
else {
MessageBoxW(NULL, L"Warning!\nCan't create log file! Working without logging.", szAppTitle.c_str(), MB_OK | MB_ICONWARNING | MB_SYSTEMMODAL);
}
}
CLogger::CLogger(const wchar_t* _appTitle)
{
szAppTitle = _appTitle;
szAppTitleVer = _appTitle;
Init();
CLogger::CLogger(const wchar_t* _appTitle) {
szAppTitle = _appTitle;
szAppTitleVer = _appTitle;
Init();
}
CLogger::~CLogger()
{
if (fsLogFile)
{
fsLogFile << GetTimeStamp() << "Stop log." << std::endl;
fsLogFile.close();
DeleteCriticalSection(&cs);
}
CLogger::~CLogger() {
if (fsLogFile) {
fsLogFile << ConvU16U8(GetTimeStamp()) << "Stop log." << std::endl;
fsLogFile.close();
DeleteCriticalSection(&cs);
}
}

View File

@@ -1,26 +1,4 @@
// MIT License
//
// Copyright (c) 2023 W0LF aka 'dreamforce'
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// wCenterWindow
// wCenterWindow
// CLogger.h
#pragma once
@@ -29,24 +7,24 @@
#define MAX_LOGBUFFER_LENGTH 512
class CLogger
{
class CLogger {
public:
void Out(const wchar_t*, ...);
CLogger(const wchar_t*);
~CLogger();
void Out(const wchar_t*, ...);
CLogger(const wchar_t*);
~CLogger();
private:
SYSTEMTIME lt;
CRITICAL_SECTION cs;
wchar_t logTimeBuffer[28]{ 0 };
wchar_t logBuffer[MAX_LOGBUFFER_LENGTH]{ 0 };
std::wofstream fsLogFile;
std::wstring szAppTitle{ 0 };
std::wstring szAppVersion{ 0 };
std::wstring szAppPlatform{ 0 };
std::wstring szAppTitleVer{ 0 };
SYSTEMTIME lt;
CRITICAL_SECTION cs;
wchar_t logTimeBuffer[28] { 0 };
wchar_t logBuffer[MAX_LOGBUFFER_LENGTH] { 0 };
std::ofstream fsLogFile;
std::wstring szAppTitle { 0 };
std::wstring szAppVersion { 0 };
std::wstring szAppPlatform { 0 };
std::wstring szAppTitleVer { 0 };
inline wchar_t* GetTimeStamp();
void Init();
std::string ConvU16U8(const std::wstring&);
inline wchar_t* GetTimeStamp();
void Init();
};

View File

@@ -1,28 +1,6 @@
// MIT License
//
// Copyright (c) 2023 W0LF aka 'dreamforce'
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// wCenterWindow
// framework.h
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

View File

@@ -2,48 +2,38 @@
// Microsoft Visual C++ generated include file.
// Used by wCenterWindow.rc
//
#define IDS_CLASSNAME 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 104
#define IDI_TRAYICON 105
#define IDR_MENU 106
#define ID_POPUPMENU_ICON 107
#define ID_POPUPMENU_AREA 108
#define ID_POPUPMENU_HELP 109
#define ID_POPUPMENU_ABOUT 110
#define ID_POPUPMENU_EXIT 111
#define IDS_HELP 112
#define IDS_ERR_MAIN 113
#define IDS_ERR_CLASS 114
#define IDS_ERR_WND 115
#define IDS_ERR_ICON 116
#define IDS_ERR_MENU 117
#define IDS_ERR_POPUP 118
#define IDS_ERR_HOOK 119
#define IDS_ERR_TIMER 120
#define IDS_ERR_HEAP 121
#define IDS_ERR_MAXMIN 122
#define IDS_RUNNING 123
#define IDT_TIMER 124
#define IDS_LICENSE 125
#define IDR_MAINFRAME 128
#define IDD_MANUAL_EDITING 129
#define IDC_EDIT_X 1000
#define IDC_EDIT_Y 1001
#define IDC_EDIT_WIDTH 1002
#define IDC_EDIT_HEIGHT 1003
#define IDC_EDIT_TITLE 1004
#define IDC_EDIT_CLASS 1005
#define IDC_BUTTON_SET 1006
#define IDC_BUTTON_CENTER 1007
#define IDC_BUTTON_CLOSE 1008
#define IDC_ABOUTHELP 1009
#define IDC_DONATIONLINK 1010
#define IDC_DONATIONTEXT 1011
#define IDC_ABOUT_PROGNAME 1012
#define IDC_ABOUT_COPYRIGHT 1013
#define IDC_ABOUT_BUILDTIME 1014
#define IDC_ABOUTEDIT 1015
#define IDS_CLASSNAME 100
#define IDS_APP_TITLE 101
#define IDI_TRAYICON 102
#define IDR_MENU 103
#define ID_POPUPMENU_ICON 104
#define ID_POPUPMENU_AREA 105
#define ID_POPUPMENU_HELP 106
#define ID_POPUPMENU_ABOUT 107
#define ID_POPUPMENU_EXIT 108
#define IDS_HELP 109
#define IDS_ERR_MAIN 110
#define IDS_ERR_CLASS 111
#define IDS_ERR_WND 112
#define IDS_ERR_ICON 113
#define IDS_ERR_MENU 114
#define IDS_ERR_POPUP 115
#define IDS_ERR_HOOK 116
#define IDS_ERR_TIMER 117
#define IDS_ERR_HEAP 118
#define IDS_ERR_MAXMIN 119
#define IDS_RUNNING 120
#define IDT_TIMER 121
#define IDD_MANUAL_EDITING 1000
#define IDC_EDIT_X 1001
#define IDC_EDIT_Y 1002
#define IDC_EDIT_WIDTH 1003
#define IDC_EDIT_HEIGHT 1004
#define IDC_EDIT_TITLE 1005
#define IDC_EDIT_CLASS 1006
#define IDC_BUTTON_SET 1007
#define IDC_BUTTON_CENTER 1008
#define IDC_BUTTON_CLOSE 1009
#define IDC_STATIC -1
// Next default values for new objects
@@ -51,9 +41,9 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_RESOURCE_VALUE 200
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1016
#define _APS_NEXT_SYMED_VALUE 126
#define _APS_NEXT_CONTROL_VALUE 1010
#define _APS_NEXT_SYMED_VALUE 122
#endif
#endif

View File

@@ -1,25 +1,5 @@
// MIT License
//
// Copyright (c) 2023 W0LF aka 'dreamforce'
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// wCenterWindow
// targetver.h
#pragma once
// // Including SDKDDKVer.h defines the highest available Windows platform.

View File

@@ -1,26 +1,4 @@
// MIT License
//
// Copyright (c) 2023 W0LF aka 'dreamforce'
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// wCenterWindow
// wCenterWindow
// updater.h
#include "wCenterWindow.h"
@@ -33,12 +11,11 @@
picojson::value json;
struct Version
{
UINT Major = 0;
UINT Minor = 0;
UINT Build = 0;
UINT Patch = 0;
struct Version {
UINT Major = 0;
UINT Minor = 0;
UINT Build = 0;
UINT Patch = 0;
} verApp, verGh;
bool GetLatestRelease(const std::wstring& urn);
@@ -46,204 +23,182 @@ void FillVersionStructure(Version& ver, const std::wstring& str);
std::vector<std::wstring> Split(const std::wstring& s, wchar_t delim);
std::wstring ConvertUtf8ToWide(const std::string& str);
UINT WINAPI Updater(void*)
{
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
logger.Out(L"[UPDT] Sleeping %d seconds", T0);
UINT WINAPI Updater(void*) {
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
logger.Out(L"[UPDT] Sleeping %d seconds", T0);
Sleep(T0 * 1000); // 10 seconds
Sleep(T0 * 1000); // 10 seconds
if (!GetLatestRelease(GITHUB_URI))
{
logger.Out(L"[UPDT] %s(%d): Failed getting releases!", TEXT(__FUNCTION__), __LINE__);
if (!GetLatestRelease(GITHUB_URI)) {
logger.Out(L"[UPDT] %s(%d): Failed getting releases!", TEXT(__FUNCTION__), __LINE__);
MessageBoxW(NULL, L"Failed getting releases!", szTitle, MB_OK | MB_ICONERROR);
return 101;
_endthreadex(101);
}
MessageBoxW(NULL, L"Failed getting releases!", szTitle, MB_OK | MB_ICONERROR);
return 101;
_endthreadex(101);
}
std::wstring j_tag_name, j_file_name, j_file_ext, j_file_url, j_page_url;
int64_t j_file_size = 0;
picojson::object obj, obj2;
picojson::object::iterator it, it2;
std::wstring j_tag_name, j_file_name, j_file_ext, j_file_url, j_page_url;
int64_t j_file_size = 0;
picojson::object obj, obj2;
picojson::object::iterator it, it2;
if (json.is<picojson::object>())
{
logger.Out(L"[UPDT] %s(%d): Parsing JSON object", TEXT(__FUNCTION__), __LINE__);
if (json.is<picojson::object>()) {
logger.Out(L"[UPDT] %s(%d): Parsing JSON object", TEXT(__FUNCTION__), __LINE__);
obj = json.get<picojson::object>();
it = obj.find("message"), it2;
if (it != obj.end())
{
std::string u = (*it).second.get<std::string>();
logger.Out(L"[UPDT] %s(%d): Error! The url is %s", TEXT(__FUNCTION__), __LINE__, u);
return 102;
_endthreadex(102);
}
obj = json.get<picojson::object>();
for (it = obj.begin(); it != obj.end(); it++)
{
if ((*it).first == "tag_name") j_tag_name = ConvertUtf8ToWide((*it).second.to_str());
if ((*it).first == "html_url") j_page_url = ConvertUtf8ToWide((*it).second.to_str());
if ((*it).first == "assets" && (*it).second.is<picojson::array>())
{
picojson::array a = (*it).second.get<picojson::array>();
obj2 = a[0].get<picojson::object>();
for (it2 = obj2.begin(); it2 != obj2.end(); it2++)
{
if ((*it2).first == "name") j_file_name = ConvertUtf8ToWide((*it2).second.to_str());
if ((*it2).first == "browser_download_url") j_file_url = ConvertUtf8ToWide((*it2).second.to_str());
if ((*it2).first == "size") j_file_size = static_cast<int64_t>((*it2).second.get<double>());
}
}
}
}
else
{
logger.Out(L"[UPDT] %s(%d): Error! Cannot recognize JSON object!", TEXT(__FUNCTION__), __LINE__);
return 103;
_endthreadex(103);
}
for (it = obj.begin(); it != obj.end(); it++) {
if ((*it).first == "tag_name") j_tag_name = ConvertUtf8ToWide((*it).second.to_str());
if ((*it).first == "html_url") j_page_url = ConvertUtf8ToWide((*it).second.to_str());
if ((*it).first == "assets" && (*it).second.is<picojson::array>()) {
picojson::array a = (*it).second.get<picojson::array>();
obj2 = a[0].get<picojson::object>();
for (it2 = obj2.begin(); it2 != obj2.end(); it2++) {
if ((*it2).first == "name") j_file_name = ConvertUtf8ToWide((*it2).second.to_str());
if ((*it2).first == "browser_download_url") j_file_url = ConvertUtf8ToWide((*it2).second.to_str());
if ((*it2).first == "size") j_file_size = static_cast<int64_t>((*it2).second.get<double>());
}
}
}
}
else {
logger.Out(L"[UPDT] %s(%d): Error! Cannot recognize JSON object!", TEXT(__FUNCTION__), __LINE__);
return 102;
_endthreadex(102);
}
size_t pos = 0;
while (std::iswdigit(j_tag_name.at(pos)) == 0) pos++;
std::wstring gh_version = j_tag_name.substr(pos);
size_t pos = 0;
while (std::iswdigit(j_tag_name.at(pos)) == 0) pos++;
std::wstring gh_version = j_tag_name.substr(pos);
logger.Out(L"[UPDT] %s(%d): AppVersion : %s", TEXT(__FUNCTION__), __LINE__, TEXT(VERSION_STR));
logger.Out(L"[UPDT] %s(%d): GitVersion : %s", TEXT(__FUNCTION__), __LINE__, gh_version.c_str());
//logger.Out(L"[UPDT] %s(%d): FileName : %s", TEXT(__FUNCTION__), __LINE__, j_file_name.c_str());
//logger.Out(L"[UPDT] %s(%d): FileSize : %d", TEXT(__FUNCTION__), __LINE__, j_file_size);
//logger.Out(L"[UPDT] %s(%d): File Url : %s", TEXT(__FUNCTION__), __LINE__, j_file_url.c_str());
//logger.Out(L"[UPDT] %s(%d): Page Url : %s", TEXT(__FUNCTION__), __LINE__, j_page_url.c_str());
logger.Out(L"[UPDT] %s(%d): AppVersion : %s", TEXT(__FUNCTION__), __LINE__, TEXT(VERSION_STR));
logger.Out(L"[UPDT] %s(%d): GitVersion : %s", TEXT(__FUNCTION__), __LINE__, gh_version.c_str());
//logger.Out(L"[UPDT] %s(%d): FileName : %s", TEXT(__FUNCTION__), __LINE__, j_file_name.c_str());
//logger.Out(L"[UPDT] %s(%d): FileSize : %d", TEXT(__FUNCTION__), __LINE__, j_file_size);
//logger.Out(L"[UPDT] %s(%d): File Url : %s", TEXT(__FUNCTION__), __LINE__, j_file_url.c_str());
//logger.Out(L"[UPDT] %s(%d): Page Url : %s", TEXT(__FUNCTION__), __LINE__, j_page_url.c_str());
FillVersionStructure(verApp, TEXT(VERSION_STR));
FillVersionStructure(verGh, gh_version);
FillVersionStructure(verApp, TEXT(VERSION_STR));
FillVersionStructure(verGh, gh_version);
if ((verGh.Major > verApp.Major) || (verGh.Minor > verApp.Minor) || (verGh.Build > verApp.Build) || (verGh.Patch > verApp.Patch))
{
if ((verGh.Major > verApp.Major) || (verGh.Minor > verApp.Minor) || (verGh.Build > verApp.Build) || (verGh.Patch > verApp.Patch)) {
logger.Out(L"[UPDT] %s(%d): An update is available!", TEXT(__FUNCTION__), __LINE__);
logger.Out(L"[UPDT] %s(%d): An update is available!", TEXT(__FUNCTION__), __LINE__);
if (IDYES == MessageBoxW(NULL, L"An update is available!\nDo you want to open the download page?", szTitle, MB_YESNO | MB_ICONINFORMATION))
{
logger.Out(L"[UPDT] %s(%d): Opening download page by default browser", TEXT(__FUNCTION__), __LINE__);
ShellExecuteW(NULL, L"open", j_page_url.c_str(), NULL, NULL, SW_SHOW);
}
else
{
logger.Out(L"[UPDT] %s(%d): The user refused the update", TEXT(__FUNCTION__), __LINE__);
}
}
else
{
logger.Out(L"[UPDT] %s(%d): No updates is available", TEXT(__FUNCTION__), __LINE__);
}
if (IDYES == MessageBoxW(NULL, L"An update is available!\nDo you want to open the download page?", szTitle, MB_YESNO | MB_ICONINFORMATION)) {
logger.Out(L"[UPDT] %s(%d): Opening download page by default browser", TEXT(__FUNCTION__), __LINE__);
ShellExecuteW(NULL, L"open", j_page_url.c_str(), NULL, NULL, SW_SHOW);
}
else {
logger.Out(L"[UPDT] %s(%d): The user refused the update", TEXT(__FUNCTION__), __LINE__);
}
}
else {
logger.Out(L"[UPDT] %s(%d): No updates is available", TEXT(__FUNCTION__), __LINE__);
}
logger.Out(L"[UPDT] Exit from the %s() function", TEXT(__FUNCTION__));
logger.Out(L"[UPDT] Exit from the %s() function", TEXT(__FUNCTION__));
return 0;
_endthreadex(0);
return 0;
_endthreadex(0);
}
bool GetLatestRelease(const std::wstring& urn)
{
std::wstring user_agent = L"User-Agent: ";
user_agent.append(szTitle);
const std::wstring url = GITHUB_URL;
bool ret = true;
DWORD err = 0;
bool GetLatestRelease(const std::wstring& urn) {
std::wstring user_agent = L"User-Agent: ";
user_agent.append(szTitle);
const std::wstring url = GITHUB_URL;
bool ret = true;
DWORD err = 0;
logger.Out(L"[UPDT] %s(%d): %s", TEXT(__FUNCTION__), __LINE__, user_agent.c_str());
logger.Out(L"[UPDT] %s(%d): %s", TEXT(__FUNCTION__), __LINE__, user_agent.c_str());
HINTERNET hInternet = InternetOpenW(user_agent.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet != NULL)
{
HINTERNET hConnect = InternetConnectW(hInternet, url.c_str(), INTERNET_DEFAULT_HTTPS_PORT, L"", L"", INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0);
if (hConnect != NULL)
{
HINTERNET hRequest = HttpOpenRequestW(hConnect, L"GET", urn.c_str(), NULL, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_UI, 0);
if (hRequest != NULL)
{
BOOL isSend = HttpSendRequestW(hRequest, NULL, 0, 0, 0);
if (isSend)
{
char szData[1024]{ 0 };
DWORD dwBytesRead = 0;
std::string buffer;
do
{
InternetReadFile(hRequest, szData, sizeof(szData), &dwBytesRead);
buffer.append(szData, dwBytesRead);
} while (dwBytesRead != 0);
HINTERNET hInternet = InternetOpenW(user_agent.c_str(), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet != NULL) {
HINTERNET hConnect = InternetConnectW(hInternet, url.c_str(), INTERNET_DEFAULT_HTTPS_PORT, L"", L"", INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0);
if (hConnect != NULL) {
HINTERNET hRequest = HttpOpenRequestW(hConnect, L"GET", urn.c_str(), NULL, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_UI, 0);
if (hRequest != NULL) {
BOOL isSend = HttpSendRequestW(hRequest, NULL, 0, 0, 0);
if (isSend) {
char szData[1024] { 0 };
DWORD dwBytesRead = 0;
std::string buffer;
do {
InternetReadFile(hRequest, szData, sizeof(szData), &dwBytesRead);
buffer.append(szData, dwBytesRead);
} while (dwBytesRead != 0);
picojson::parse(json, buffer);
std::string jerr = picojson::get_last_error();
if (!jerr.empty())
{
logger.Out(L"[UPDT] %s(%d): Error while parsing JSON object: %s", TEXT(__FUNCTION__), __LINE__, ConvertUtf8ToWide(jerr));
picojson::parse(json, buffer);
std::string jerr = picojson::get_last_error();
if (!jerr.empty()) {
logger.Out(L"[UPDT] %s(%d): Error while parsing JSON object: %s", TEXT(__FUNCTION__), __LINE__, ConvertUtf8ToWide(jerr));
MessageBoxW(NULL, L"Error while parsing JSON object!", szTitle, MB_OK | MB_ICONERROR);
ret = false;
}
}
else
{
err = GetLastError();
logger.Out(L"[UPDT] %s(%d): HttpSendRequestW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
ret = false;
}
}
else
{
err = GetLastError();
logger.Out(L"[UPDT] %s(%d): HttpOpenRequestW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
ret = false;
}
InternetCloseHandle(hRequest);
}
else
{
err = GetLastError();
logger.Out(L"[UPDT] %s(%d): InternetConnectW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
ret = false;
}
InternetCloseHandle(hConnect);
}
else
{
err = GetLastError();
logger.Out(L"[UPDT] %s(%d): InternetOpenW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
ret = false;
}
InternetCloseHandle(hInternet);
return ret;
MessageBoxW(NULL, L"Error while parsing JSON object!", szTitle, MB_OK | MB_ICONERROR);
ret = false;
}
else {
picojson::object obj = json.get<picojson::object>();
std::string msg, sts;
if (auto search = obj.find("message"); search != obj.end()) {
msg = (search->first) + ": " + (search->second).get<std::string>();
}
if (auto search = obj.find("status"); search != obj.end()) {
sts = (search->first) + ": " + (search->second).get<std::string>();
}
logger.Out(L"[UPDT] %s(%d): Error! %s", TEXT(__FUNCTION__), __LINE__, ConvertUtf8ToWide(msg + ", " + sts).c_str());
ret = false;
}
}
else {
err = GetLastError();
logger.Out(L"[UPDT] %s(%d): HttpSendRequestW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
ret = false;
}
}
else {
err = GetLastError();
logger.Out(L"[UPDT] %s(%d): HttpOpenRequestW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
ret = false;
}
InternetCloseHandle(hRequest);
}
else {
err = GetLastError();
logger.Out(L"[UPDT] %s(%d): InternetConnectW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
ret = false;
}
InternetCloseHandle(hConnect);
}
else {
err = GetLastError();
logger.Out(L"[UPDT] %s(%d): InternetOpenW() error: %d", TEXT(__FUNCTION__), __LINE__, err);
ret = false;
}
InternetCloseHandle(hInternet);
return ret;
}
std::vector<std::wstring> Split(const std::wstring& s, wchar_t delim)
{
std::vector<std::wstring> result;
std::wstringstream ss(s);
std::wstring item;
while (getline(ss, item, delim)) result.push_back(item);
return result;
std::vector<std::wstring> Split(const std::wstring& s, wchar_t delim) {
std::vector<std::wstring> result;
std::wstringstream ss(s);
std::wstring item;
while (getline(ss, item, delim)) result.push_back(item);
return result;
}
void FillVersionStructure(Version& ver, const std::wstring& str)
{
std::vector<std::wstring> v;
v = Split(str, '.');
if (v.size() < 4) v.push_back(L"0");
ver.Major = std::stoul(v[0]);
ver.Minor = std::stoul(v[1]);
ver.Build = std::stoul(v[2]);
ver.Patch = std::stoul(v[3]);
void FillVersionStructure(Version& ver, const std::wstring& str) {
std::vector<std::wstring> v;
v = Split(str, '.');
if (v.size() < 4) v.push_back(L"0");
ver.Major = std::stoul(v[0]);
ver.Minor = std::stoul(v[1]);
ver.Build = std::stoul(v[2]);
ver.Patch = std::stoul(v[3]);
}
std::wstring ConvertUtf8ToWide(const std::string& str)
{
int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
std::wstring wstr(count, 0);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count);
return wstr;
std::wstring ConvertUtf8ToWide(const std::string& str) {
int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
std::wstring wstr(count, 0);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count);
return wstr;
}

View File

@@ -1,25 +1,3 @@
// MIT License
//
// Copyright (c) 2023 W0LF aka 'dreamforce'
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// wCenterWindow
// updater.h

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,3 @@
// MIT License
//
// Copyright (c) 2023 W0LF aka 'dreamforce'
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// wCenterWindow
// wCenterWindow.h
@@ -36,7 +14,7 @@
#define ARCH 86
#endif
#define MAX_LOADSTRING 50
#define MAX_LOADSTRING 64
// Windows Header Files
#include <fstream>

Binary file not shown.

View File

@@ -30,26 +30,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@@ -100,6 +100,7 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -123,7 +124,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
@@ -147,6 +148,7 @@
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -170,7 +172,7 @@
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>