36 Commits

Author SHA1 Message Date
849689b286 Release v2.3.8 2024-01-23 14:50:43 +03:00
dfbf103b2e Added TODOs. 2024-01-23 14:43:55 +03:00
b5ade2a064 Added MB_SYSTEMMODAL flag to MessageBox function in the CLogger class. 2024-01-23 14:33:27 +03:00
82c90d4628 Changed some Logger's output strings. 2024-01-23 14:20:57 +03:00
3e8b3b906b Changed NOTIFYICONDATA structure to version 4 (Vista and later). 2024-01-20 21:37:22 +03:00
016e42bbf2 Added _WIN32_WINNT macro. 2024-01-20 17:40:07 +03:00
f19e8178d6 Added TODO. 2024-01-17 16:42:51 +03:00
181403098c Added KillTimer() function. 2023-12-26 14:07:30 +03:00
4d230a850f Moved popup menu creation to the wWinMain() function. 2023-12-26 14:04:28 +03:00
53a70e1ad7 Fixed menu tracking according to Microsoft documentation. 2023-12-26 13:22:15 +03:00
bac58b056a Fixed tray icon with LoadIconMetric() function. 2023-12-26 12:52:17 +03:00
6cb3b2aabd Fixed tray icon that disappears after explorer restart. 2023-12-26 10:11:35 +03:00
c5b377b22f Added the 'Center' button and the ability to center the window from the 'Manual editing' dialog. 2023-12-18 18:20:28 +03:00
4228258e80 Added license info into About dialog. 2023-12-18 17:50:51 +03:00
21c65369ec Updated README and Help text. 2023-12-18 17:34:34 +03:00
34ec99e90b Updated README and Help text. 2023-12-18 17:24:41 +03:00
2fea7600fb Fixed memory leak with szWinTitleBuffer. 2023-12-16 04:56:02 +03:00
e7609c1a34 Added output of the help text. 2023-12-16 04:48:23 +03:00
2b340791b9 Added 'Help' item into the popup menu. 2023-12-16 04:26:33 +03:00
b067ea9be4 Made the MoveWindowToMonitorCenter() function static because the Visual Studio strongly recommends it. 2023-12-15 22:18:23 +03:00
d26aa77af3 Fixes and improvements. 2023-12-15 22:09:36 +03:00
450173f0ee Moved creating hooks to WinMain() function. 2023-12-15 20:47:02 +03:00
ce275c0fcc Changed signature of ShowError() function. 2023-12-15 19:33:29 +03:00
6ba949de4b Changed C-style type conversion to C++ style. 2023-12-11 21:25:59 +03:00
5b205ad2e4 Merge branch 'x64' into dev 2023-12-07 21:13:41 +03:00
b8ce96ee99 Added platform architecture information to About dialog and CLogger::Out() method. 2023-12-07 20:53:38 +03:00
76be5eb941 Moved function to inner scope. 2023-12-07 19:54:34 +03:00
d0f211d931 Create LICENSE 2023-12-07 19:02:47 +03:00
abed2c3fd0 Create LICENSE 2023-12-07 18:59:17 +03:00
W0LF
a103c80745 Create LICENSE 2023-12-07 18:44:33 +03:00
f558df6bf9 Preparations for the release of the 64-bit version. 2023-12-03 20:23:51 +03:00
8c570ab1e9 Update check timers have been fixed. 2023-12-03 18:42:59 +03:00
6b592d78c1 Changed some CRT functions by WinApi functions. 2023-11-29 01:58:38 +03:00
a6d6527ff3 Moved hHeap global variable to local scope. 2023-11-29 00:50:55 +03:00
72158f53d7 Moved handle of main window variable from global scope to local. 2023-11-29 00:09:46 +03:00
4bfcf90e2a Added check for error allocating heap memory. 2023-11-28 23:38:50 +03:00
18 changed files with 620 additions and 233 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
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.

View File

@@ -7,9 +7,10 @@ or pressing `LCTRL + LWIN + MMB` (Middle Mouse Button).
You can use `LCTRL + LWIN + I` hotkey for hide/show trayicon.
You can also use commandline option `/hide` for hide trayicon at startup.
The `/noupdate` option is used to disable check for updates. By default, the check is repeated once a day.
`Use workarea` option means that the window is centered without a taskbar, otherwise, the full resolution of the monitor will be used.
The `/noupdate` 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.
If some windows does not centers you should run wCenterWindow with administrative rights.
@@ -21,3 +22,27 @@ However, in this case wCenterWindow will not be able to work with windows that a
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.\
**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.

View File

@@ -1,3 +1,25 @@
## 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
@@ -45,6 +67,7 @@ function makeVersionString([string]$vmaj, [string]$vmin, [string]$vbld, [string]
[string]$buildDateTime = [string]$vs = [string]$vn = [string]$intName = [string]$origName = $null
[int]$pys = [int]$spanDays = [int]$spanSecs = $null
[int]$currentYear = [int]$currentMonth = [int]$currentDay = [int]$currentHour = [int]$currentMinute = [int]$currentSecond = $null
[string]$platformArch = $args[0]
[string]$iniFile = ".\Version.ini"
#endregion
@@ -103,8 +126,8 @@ $currentSecond = $date.Second
$buildDateTime = "Build date: $($date.GetDateTimeFormats('u').Replace('Z', ''))"
$spanDays = [math]::Round((New-TimeSpan -Start $(Get-Date -Month 1 -Day 1 -Year 2000) -End $date).TotalDays)
$spanSecs = [math]::Round((New-TimeSpan -Start $($date.Date) -End $($date.DateTime)).TotalSeconds)
if ($pys -eq $currentYear) { $pcf = "Copyright (C) $pys by $pa" } else { $pcf = "Copyright (C) $pys-$currentYear by $pa" }
$intName = "$pn-C++"
if ($pys -eq $currentYear) { $pcf = "Copyright (c) $pys $pa" } else { $pcf = "Copyright (c) $pys-$currentYear $pa" }
$intName = "$pn-$platformArch-C++"
$origName = "$pn.exe"
$verMajor = getValue $verMajor
$verMinor = getValue $verMinor
@@ -125,6 +148,8 @@ else {
$pnf = "$pn v$vs"
}
$pnf = "$pn v$vs ($platformArch)"
#region Save all variables to file
"// $pn" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode
"// VersionInfo.h" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
@@ -157,6 +182,7 @@ else {
# echo " verPatch: [$verPatch]"
# echo ""
# echo " aboutBuild: [$aboutBuild]"
# echo " platformArch: [$platformArch]"
# echo " productNameFull: [$pnf]"
# echo "productCopyrightFull: [$pcf]"
# echo " internalName: [$intName]"

Binary file not shown.

View File

@@ -1,16 +1,43 @@
@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)"
:: Then in "Resource Includes..." add '#include "VersionInfo.rc"' into 'Compile-time Directives'
REM In VisualStudio add to Pre-Build events:
REM "$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)"
REM "$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"
REM Then in "Resource Includes..." add '#include "VersionInfo.rc"' into 'Compile-time Directives'
IF "%~1" == "" GOTO :no_args
IF "%~2" == "" GOTO :no_args
IF "%~3" == "" GOTO :no_args
SET solutionDir=%1
SET projectDir=%2
SET platformArch=%3
CD /D %solutionDir%
powershell -ExecutionPolicy RemoteSigned -File Update_Version.ps1
powershell -ExecutionPolicy RemoteSigned -File Update_Version.ps1 %platformArch%
MOVE /Y %solutionDir%VersionInfo.h %projectDir%VersionInfo.h
EXIT

View File

@@ -1,37 +1,67 @@
// 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
// CLogger.cpp
#include "CLogger.h"
#include <filesystem>
inline wchar_t* CLogger::GetTimeStamp() {
#include "CLogger.h"
#include <string>
#include <filesystem>
#include <strsafe.h>
inline wchar_t* CLogger::GetTimeStamp()
{
GetLocalTime(&lt);
swprintf_s(logTimeBuffer, L"%d-%02d-%02d %02d:%02d:%02d.%03d | ", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds);
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::Out(const wchar_t* fmt, ...) {
if (fsLogFile.is_open()) {
void CLogger::Out(const wchar_t* fmt, ...)
{
if (fsLogFile.is_open())
{
va_list args;
va_start(args, fmt);
EnterCriticalSection(&cs);
_vsnwprintf_s(logBuffer, _countof(logBuffer), _TRUNCATE, fmt, args);
StringCchVPrintfW(logBuffer, _countof(logBuffer), fmt, args);
va_end(args);
fsLogFile << GetTimeStamp() << logBuffer << std::endl;
LeaveCriticalSection(&cs);
}
}
void CLogger::Init() {
InitializeCriticalSection(&cs);
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);
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);
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;
}
@@ -45,32 +75,31 @@ void CLogger::Init() {
log_path = L"D:\\test.log";
#endif
fsLogFile.open(log_path, std::ios::trunc);
if (fsLogFile.is_open()) {
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);
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) {
CLogger::CLogger(const wchar_t* _appTitle)
{
szAppTitle = _appTitle;
szAppTitleVer = _appTitle;
Init();
}
CLogger::CLogger(const wchar_t* _appTitle, const wchar_t* _appVersion) {
szAppTitle = _appTitle; szAppVersion = _appVersion;
szAppTitleVer = _appTitle;
szAppTitleVer.append(L", v").append(_appVersion);
Init();
}
CLogger::~CLogger() {
if (fsLogFile) {
CLogger::~CLogger()
{
if (fsLogFile)
{
fsLogFile << GetTimeStamp() << "Stop log." << std::endl;
fsLogFile.close();
DeleteCriticalSection(&cs);

View File

@@ -1,5 +1,28 @@
// 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
// CLogger.h
#pragma once
#include <Windows.h>
#include <fstream>
@@ -11,19 +34,17 @@ class CLogger
public:
void Out(const wchar_t*, ...);
CLogger(const wchar_t*);
CLogger(const wchar_t*, const wchar_t*);
~CLogger();
private:
SYSTEMTIME lt;
CRITICAL_SECTION cs;
HANDLE hLoggerThread = NULL;
HANDLE hLoggerEvent = NULL;
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 };
inline wchar_t* GetTimeStamp();

View File

@@ -1,6 +1,28 @@
// 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

View File

@@ -9,9 +9,10 @@
#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_ABOUT 112
#define IDS_HELP 112
#define IDS_ERR_MAIN 113
#define IDS_ERR_CLASS 114
#define IDS_ERR_WND 115
@@ -20,9 +21,11 @@
#define IDS_ERR_POPUP 118
#define IDS_ERR_HOOK 119
#define IDS_ERR_TIMER 120
#define IDS_ERR_MAXMIN 121
#define IDS_RUNNING 122
#define IDT_TIMER 123
#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
@@ -32,14 +35,15 @@
#define IDC_EDIT_TITLE 1004
#define IDC_EDIT_CLASS 1005
#define IDC_BUTTON_SET 1006
#define IDC_BUTTON_CLOSE 1007
#define IDC_ABOUTHELP 1008
#define IDC_DONATIONLINK 1009
#define IDC_DONATIONTEXT 1010
#define IDC_ABOUT_PROGNAME 1011
#define IDC_ABOUT_COPYRIGHT 1012
#define IDC_ABOUT_BUILDTIME 1013
#define IDC_ABOUTEDIT 1014
#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 IDC_STATIC -1
// Next default values for new objects
@@ -49,7 +53,7 @@
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1015
#define _APS_NEXT_SYMED_VALUE 124
#define _APS_NEXT_CONTROL_VALUE 1016
#define _APS_NEXT_SYMED_VALUE 126
#endif
#endif

View File

@@ -1,6 +1,32 @@
// 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.
#pragma once
// // Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <winsdkver.h>
#define WINVER 0x0601
#define _WIN32_WINNT 0x0601
#define _WIN32_IE 0x0601
#include <SDKDDKVer.h>

View File

@@ -1,6 +1,28 @@
// 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
//
#include "wCenterWindow.h"
#include "updater.h"
#include "picojson.h"
@@ -24,17 +46,20 @@ 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(LPVOID)
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
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);
_endthreadex(101);
return 101;
_endthreadex(101);
}
std::wstring j_tag_name, j_file_name, j_file_ext, j_file_url, j_page_url;
@@ -52,8 +77,8 @@ UINT WINAPI Updater(LPVOID)
{
std::string u = (*it).second.get<std::string>();
logger.Out(L"[UPDT] %s(%d): Error! The url is %s", TEXT(__FUNCTION__), __LINE__, u);
_endthreadex(102);
return 102;
_endthreadex(102);
}
for (it = obj.begin(); it != obj.end(); it++)
@@ -76,8 +101,8 @@ UINT WINAPI Updater(LPVOID)
else
{
logger.Out(L"[UPDT] %s(%d): Error! Cannot recognize JSON object!", TEXT(__FUNCTION__), __LINE__);
_endthreadex(103);
return 103;
_endthreadex(103);
}
size_t pos = 0;
@@ -116,8 +141,8 @@ UINT WINAPI Updater(LPVOID)
logger.Out(L"[UPDT] Exit from the %s() function", TEXT(__FUNCTION__));
_endthreadex(0);
return 0;
_endthreadex(0);
}
bool GetLatestRelease(const std::wstring& urn)
@@ -155,7 +180,9 @@ bool GetLatestRelease(const std::wstring& urn)
std::string jerr = picojson::get_last_error();
if (!jerr.empty())
{
std::cout << jerr << std::endl;
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;
}

View File

@@ -1,5 +1,27 @@
// 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
//
#pragma once
UINT WINAPI Updater(void*);

View File

@@ -1,10 +1,35 @@
// 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.cpp
//
// TODO: Licensing.
// TODO: Change keyboard low-level hook to RegisterHotKey function.
// TODO: Make x64 version.
//
// TODO: Change the formatting of source files.
// TODO: Add the name of app's icon author to the About dialog.
// TODO: Move the InitCommonControlsEx() function to the WinMain().
// TODO: Split main cpp-file to separate files.
// TODO: Make the automatic updater (download, unzip and replace executable).
// TODO: Change keyboard low-level hook to RegisterHotKey function. (Is it really needed?)
#include "framework.h"
#include "wCenterWindow.h"
#include "updater.h"
@@ -18,40 +43,33 @@
#define WM_WCW (WM_APP + 0x0F00)
// Global variables:
HINSTANCE hInst; // Instance
WCHAR szTitle[MAX_LOADSTRING]{ 0 }; // wCenterWindow's title
WCHAR szClass[MAX_LOADSTRING]{ 0 }; // Window's class
WCHAR szWinTitle[256]{ 0 };
WCHAR szWinClass[256]{ 0 };
HANDLE hHeap = NULL, hUpdater = NULL;
UINT dwUpdaterID = 0;
HHOOK hMouseHook = NULL, hKbdHook = NULL; // Hook's handles
HICON hIcon = NULL;
HMENU hMenu = NULL, hPopup = NULL;
HWND hWnd = NULL, hFgWnd = NULL;
HICON hIconSmall = NULL, hIconLarge = NULL;
HMENU hPopup = NULL;
HWND hFgWnd = NULL;
BOOL bKPressed = FALSE, bMPressed = FALSE, fShowIcon = TRUE, fCheckUpdates = TRUE, bWorkArea = TRUE;
BOOL bLCTRL = FALSE, bLWIN = FALSE, bKEYV = FALSE;
CLogger logger(TEXT(PRODUCT_NAME), TEXT(VERSION_STR));
UINT uMsgRestore = 0;
CLogger logger(TEXT(PRODUCT_NAME_FULL));
NOTIFYICONDATAW nid = { 0 };
MENUITEMINFO mii = { 0 };
MENUITEMINFOW mii = { 0 };
LPVOID szBuffer;
// {2D7B7F30-4B5F-4380-9807-57D7A2E37F6C}
// static const GUID guid = { 0x2d7b7f30, 0x4b5f, 0x4380, { 0x98, 0x7, 0x57, 0xd7, 0xa2, 0xe3, 0x7f, 0x6c } };
LPVOID szWinTitleBuffer = nullptr;
LPVOID szWinClassBuffer = nullptr;
// Forward declarations of functions included in this code module:
VOID HandlingTrayIcon();
VOID ShowError(UINT);
VOID ShowError(UINT, LPCWSTR);
VOID ShowPopupMenu(HWND, POINT);
BOOL IsWindowApprooved(HWND);
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK KeyboardHookProc(int, WPARAM, LPARAM);
LRESULT CALLBACK MouseHookProc(int, WPARAM, LPARAM);
INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
VOID MoveWindowToMonitorCenter(HWND hwnd, BOOL bWorkArea, BOOL bResize)
static VOID MoveWindowToMonitorCenter(HWND hwnd, BOOL bWorkArea, BOOL bResize)
{
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
@@ -101,15 +119,15 @@ VOID MoveWindowToMonitorCenter(HWND hwnd, BOOL bWorkArea, BOOL bResize)
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
hInst = hInstance;
WCHAR szClass[MAX_LOADSTRING]{ 0 }; // Window's class
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, _countof(szTitle));
LoadStringW(hInstance, IDS_CLASSNAME, szClass, _countof(szClass));
if (FindWindowW(szClass, NULL))
{
ShowError(IDS_RUNNING);
return FALSE;
ShowError(IDS_RUNNING, szTitle);
return -10;
}
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
@@ -131,33 +149,92 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd
}
LocalFree(szArglist);
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
LoadIconMetric(hInstance, MAKEINTRESOURCEW(IDI_TRAYICON), LIM_LARGE, &hIconLarge);
LoadIconMetric(hInstance, MAKEINTRESOURCEW(IDI_TRAYICON), LIM_SMALL, &hIconSmall);
WNDCLASSEXW wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEXW);
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDI_TRAYICON));
LoadIconMetric(hInst, MAKEINTRESOURCE(IDI_TRAYICON), LIM_LARGE, &(wcex.hIcon));
wcex.hIcon = hIconLarge;
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.lpszClassName = szClass;
wcex.hIconSm = wcex.hIcon;
hIcon = wcex.hIcon;
wcex.hIconSm = hIconSmall;
if (!RegisterClassExW(&wcex))
{
ShowError(IDS_ERR_CLASS);
return FALSE;
ShowError(IDS_ERR_CLASS, szTitle);
return -9;
}
hWnd = CreateWindowExW(0, szClass, szTitle, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
HWND hMainWnd = CreateWindowExW(0, szClass, szTitle, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if (!hMainWnd)
{
ShowError(IDS_ERR_WND);
return FALSE;
ShowError(IDS_ERR_WND, szTitle);
return -8;
}
#ifndef _DEBUG
HHOOK hMouseHook = SetWindowsHookExW(WH_MOUSE_LL, MouseHookProc, GetModuleHandleW(NULL), NULL);
if (!hMouseHook)
{
logger.Out(L"%s(%d): Mouse hook creation failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_HOOK, szTitle);
return -7;
}
logger.Out(L"%s(%d): The mouse hook was successfully installed", TEXT(__FUNCTION__), __LINE__);
#endif // !_DEBUG
HHOOK hKbdHook = SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardHookProc, GetModuleHandleW(NULL), NULL);
if (!hKbdHook)
{
logger.Out(L"%s(%d): Keyboard hook creation failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_HOOK, szTitle);
return -6;
}
logger.Out(L"%s(%d): The keyboard hook was successfully installed", TEXT(__FUNCTION__), __LINE__);
HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCE(IDR_MENU));
if (!hMenu)
{
logger.Out(L"%s(%d): Loading context menu failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_MENU, szTitle);
return -5;
}
logger.Out(L"%s(%d): Context menu successfully loaded", TEXT(__FUNCTION__), __LINE__);
hPopup = GetSubMenu(hMenu, 0);
if (!hPopup)
{
logger.Out(L"%s(%d): Creating popup menu failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_POPUP, szTitle);
return -4;
}
logger.Out(L"%s(%d): Popup menu successfully created", TEXT(__FUNCTION__), __LINE__);
mii.cbSize = sizeof(MENUITEMINFOW);
mii.fMask = MIIM_STATE;
bWorkArea ? mii.fState = MFS_CHECKED : mii.fState = MFS_UNCHECKED;
SetMenuItemInfoW(hPopup, ID_POPUPMENU_AREA, FALSE, &mii);
HandlingTrayIcon();
hHeap = GetProcessHeap();
szBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_WINTITLE_BUFFER_LENGTH);
HANDLE hHeap = GetProcessHeap();
szWinTitleBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_WINTITLE_BUFFER_LENGTH);
if (nullptr == szWinTitleBuffer)
{
ShowError(IDS_ERR_HEAP, szTitle);
return -3;
}
szWinClassBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_WINTITLE_BUFFER_LENGTH);
if (nullptr == szWinClassBuffer)
{
ShowError(IDS_ERR_HEAP, szTitle);
return -2;
}
MSG msg;
BOOL bRet;
@@ -166,7 +243,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd
{
if (bRet == -1)
{
ShowError(IDS_ERR_MAIN);
ShowError(IDS_ERR_MAIN, szTitle);
return -1;
}
else
@@ -176,21 +253,24 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd
}
}
#ifndef _DEBUG
if (hMouseHook) UnhookWindowsHookEx(hMouseHook);
#endif // !_DEBUG
if (hKbdHook) UnhookWindowsHookEx(hKbdHook);
if (hMenu) DestroyMenu(hMenu);
Shell_NotifyIconW(NIM_DELETE, &nid);
DestroyIcon(hIcon);
KillTimer(hMainWnd, IDT_TIMER);
DestroyIcon(hIconSmall);
DestroyIcon(hIconLarge);
HeapFree(hHeap, NULL, szWinClassBuffer);
HeapFree(hHeap, NULL, szWinTitleBuffer);
logger.Out(L"Exit from the %s() function, msg.wParam = %d", TEXT(__FUNCTION__), (int)msg.wParam);
logger.Out(L"Exit from the %s() function, msg.wParam = 0x%0*tX", TEXT(__FUNCTION__), (sizeof(int) * 2), static_cast<int>(msg.wParam));
HeapFree(hHeap, NULL, szBuffer);
CloseHandle(hUpdater);
return (int)msg.wParam;
return static_cast<int>(msg.wParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK WndProc(HWND hMainWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
@@ -198,70 +278,32 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
logger.Out(L"%s(%d): Recived WM_CREATE message", TEXT(__FUNCTION__), __LINE__);
hMenu = LoadMenuW(hInst, MAKEINTRESOURCE(IDR_MENU));
if (!hMenu)
{
logger.Out(L"%s(%d): Loading context menu failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_MENU);
PostQuitMessage(0);
}
logger.Out(L"%s(%d): Context menu successfully loaded", TEXT(__FUNCTION__), __LINE__);
hPopup = GetSubMenu(hMenu, 0);
if (!hPopup)
{
logger.Out(L"%s(%d): Creating popup menu failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_POPUP);
PostQuitMessage(0);
}
logger.Out(L"%s(%d): Popup menu successfully created", TEXT(__FUNCTION__), __LINE__);
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STATE;
bWorkArea ? mii.fState = MFS_CHECKED : mii.fState = MFS_UNCHECKED;
SetMenuItemInfoW(hPopup, ID_POPUPMENU_AREA, FALSE, &mii);
nid.cbSize = sizeof(NOTIFYICONDATAW);
nid.hWnd = hWnd;
nid.uVersion = NOTIFYICON_VERSION;
nid.hWnd = hMainWnd;
nid.uVersion = NOTIFYICON_VERSION_4;
nid.uCallbackMessage = WM_WCW;
nid.hIcon = hIcon;
nid.hIcon = hIconSmall;
nid.uID = IDI_TRAYICON;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_SHOWTIP;
StringCchCopyW(nid.szTip, _countof(nid.szTip), szTitle);
uMsgRestore = RegisterWindowMessageW(L"TaskbarCreated");
if (!uMsgRestore)
{
logger.Out(L"%s(%d): Registering 'TaskbarCreated' message failed!", TEXT(__FUNCTION__), __LINE__);
}
logger.Out(L"%s(%d): The 'TaskbarCreated' message successfully registered", TEXT(__FUNCTION__), __LINE__);
if (fCheckUpdates)
{
if (!SetTimer(hWnd, IDT_TIMER, 30000, NULL)) // 30 seconds
if (!SetTimer(hMainWnd, IDT_TIMER, (T1 * 1000 - T0 * 1000), NULL)) // 50 seconds
{
logger.Out(L"%s(%d): Creating timer failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_TIMER);
ShowError(IDS_ERR_TIMER, szTitle);
fCheckUpdates = FALSE;
}
logger.Out(L"%s(%d): Timer successfully created", TEXT(__FUNCTION__), __LINE__);
logger.Out(L"%s(%d): Timer successfully created (%d sec)", TEXT(__FUNCTION__), __LINE__, (T1 - T0));
}
#ifndef _DEBUG
hMouseHook = SetWindowsHookExW(WH_MOUSE_LL, MouseHookProc, hInst, NULL);
if (!hMouseHook)
{
logger.Out(L"%s(%d): Mouse hook creation failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_HOOK);
PostQuitMessage(0);
}
logger.Out(L"%s(%d): The mouse hook was successfully installed", TEXT(__FUNCTION__), __LINE__);
#endif // !_DEBUG
hKbdHook = SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardHookProc, hInst, NULL);
if (!hKbdHook)
{
logger.Out(L"%s(%d): Keyboard hook creation failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_HOOK);
PostQuitMessage(0);
}
logger.Out(L"%s(%d): The keyboard hook was successfully installed", TEXT(__FUNCTION__), __LINE__);
break;
}
@@ -269,9 +311,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (fCheckUpdates)
{
logger.Out(L"%s(%d): Checking for updates is enabled, fCheckUpdates = %s", TEXT(__FUNCTION__), __LINE__, fCheckUpdates ? L"True" : L"False");
logger.Out(L"%s(%d): Checking for updates is enabled", TEXT(__FUNCTION__), __LINE__);
hUpdater = (HANDLE)_beginthreadex(NULL, 0, &Updater, NULL, 0, &dwUpdaterID);
HANDLE hUpdater = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &Updater, NULL, 0, NULL));
if (NULL == hUpdater)
{
DWORD dwLastError = GetLastError();
@@ -279,40 +321,50 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
}
else
{
if (!SetTimer(hWnd, IDT_TIMER, 86400000, NULL)) // 1 day
if (!SetTimer(hMainWnd, IDT_TIMER, (T2 * 1000), NULL)) // 1 day
{
logger.Out(L"%s(%d): Creating timer failed!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_TIMER);
ShowError(IDS_ERR_TIMER, szTitle);
fCheckUpdates = FALSE;
}
logger.Out(L"%s(%d): Timer successfully created", TEXT(__FUNCTION__), __LINE__);
logger.Out(L"%s(%d): Timer successfully created (%d sec)", TEXT(__FUNCTION__), __LINE__, T2);
CloseHandle(hUpdater);
}
}
else
{
logger.Out(L"%s(%d): Checking for updates is disabled, fCheckUpdates = %s", TEXT(__FUNCTION__), __LINE__, fCheckUpdates ? L"True" : L"False");
logger.Out(L"%s(%d): Checking for updates is disabled", TEXT(__FUNCTION__), __LINE__);
}
break;
}
case WM_WCW: // Popup menu handler
{
if (IDI_TRAYICON == wParam && (WM_RBUTTONDOWN == lParam || WM_LBUTTONDOWN == lParam))
if (WM_CONTEXTMENU == LOWORD(lParam))
{
logger.Out(L"%s(%d): Entering the WM_WCW message handler", TEXT(__FUNCTION__), __LINE__);
logger.Out(L"%s(%d): Recived WM_CONTEXTMENU message", TEXT(__FUNCTION__), __LINE__);
SetForegroundWindow(hWnd);
POINT pt;
GetCursorPos(&pt);
int idMenu = TrackPopupMenu(hPopup, TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, NULL);
if (ID_POPUPMENU_ICON == idMenu)
POINT pt{ GET_X_LPARAM(wParam), GET_Y_LPARAM(wParam) };
ShowPopupMenu(hMainWnd, pt);
}
break;
}
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case ID_POPUPMENU_ICON:
{
logger.Out(L"%s(%d): Pressed the 'Hide icon' menuitem", TEXT(__FUNCTION__), __LINE__);
fShowIcon = FALSE;
HandlingTrayIcon();
break;
}
if (ID_POPUPMENU_AREA == idMenu)
case ID_POPUPMENU_AREA:
{
logger.Out(L"%s(%d): Pressed the 'Use workarea' menuitem", TEXT(__FUNCTION__), __LINE__);
@@ -320,30 +372,48 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
bWorkArea ? mii.fState = MFS_CHECKED : mii.fState = MFS_UNCHECKED;
SetMenuItemInfoW(hPopup, ID_POPUPMENU_AREA, FALSE, &mii);
logger.Out(L"%s(%d): Changed 'Use workarea' option to %s", TEXT(__FUNCTION__), __LINE__, bWorkArea ? L"True" : L"False");
break;
}
if (ID_POPUPMENU_ABOUT == idMenu && !bKPressed)
case ID_POPUPMENU_HELP:
{
logger.Out(L"%s(%d): Pressed the 'About' menuitem", TEXT(__FUNCTION__), __LINE__);
if (!bKPressed)
{
logger.Out(L"%s(%d): Pressed the 'Help' menuitem", TEXT(__FUNCTION__), __LINE__);
bKPressed = TRUE;
DialogBoxW(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, (DLGPROC)About);
bKPressed = FALSE;
bKPressed = TRUE;
WCHAR szHelp[MAX_LOADSTRING * 15];
LoadStringW(GetModuleHandleW(NULL), IDS_HELP, szHelp, _countof(szHelp));
MessageBoxW(hMainWnd, szHelp, szTitle, MB_OK | MB_ICONINFORMATION);
bKPressed = FALSE;
}
break;
}
if (ID_POPUPMENU_EXIT == idMenu)
case ID_POPUPMENU_ABOUT:
{
if (!bKPressed)
{
logger.Out(L"%s(%d): Pressed the 'About' menuitem", TEXT(__FUNCTION__), __LINE__);
bKPressed = TRUE;
DialogBoxParamW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_ABOUTBOX), hMainWnd, static_cast<DLGPROC>(About), 0L);
bKPressed = FALSE;
}
break;
}
case ID_POPUPMENU_EXIT:
{
logger.Out(L"%s(%d): Pressed the 'Exit' menuitem", TEXT(__FUNCTION__), __LINE__);
PostQuitMessage(0);
DestroyWindow(hMainWnd);
break;
}
logger.Out(L"%s(%d): Exit from the WM_WCW message handler", TEXT(__FUNCTION__), __LINE__);
}
break;
}
case WM_QUERYENDSESSION:
{
logger.Out(L"%s(%d): Recieved the WM_QUERYENDSESSION message, lParam = 0x%08X", TEXT(__FUNCTION__), __LINE__, (long)lParam);
logger.Out(L"%s(%d): Recieved the WM_QUERYENDSESSION message, lParam = 0x%p", TEXT(__FUNCTION__), __LINE__, lParam);
PostQuitMessage(0);
return TRUE;
@@ -358,7 +428,16 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
}
default: return DefWindowProcW(hWnd, message, wParam, lParam);
default:
{
if (message == uMsgRestore)
{
Shell_NotifyIconW(NIM_DELETE, &nid);
Shell_NotifyIconW(NIM_ADD, &nid);
break;
}
return DefWindowProcW(hMainWnd, message, wParam, lParam);
}
}
return 0;
}
@@ -381,7 +460,7 @@ LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPKBDLLHOOKSTRUCT pkhs = { 0 };
pkhs = (LPKBDLLHOOKSTRUCT)lParam;
pkhs = reinterpret_cast<LPKBDLLHOOKSTRUCT>(lParam);
if (WM_KEYUP == wParam)
{
if (VK_LCONTROL == pkhs->vkCode) bLCTRL = FALSE;
@@ -425,7 +504,7 @@ LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
logger.Out(L"%s(%d): Opening the 'Manual editing' dialog", TEXT(__FUNCTION__), __LINE__);
DialogBoxW(hInst, MAKEINTRESOURCE(IDD_MANUAL_EDITING), hFgWnd, (DLGPROC)DlgProc);
DialogBoxParamW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_MANUAL_EDITING), hFgWnd, static_cast<DLGPROC>(DlgProc), 0L);
SetForegroundWindow(hFgWnd);
}
else hFgWnd = NULL;
@@ -436,7 +515,7 @@ LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
BOOL CALLBACK DlgProc(HWND hDlg, UINT dlgmsg, WPARAM wParam, LPARAM lParam)
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT dlgmsg, WPARAM wParam, LPARAM lParam)
{
RECT rcFW = { 0 };
int x, y, w, h;
@@ -447,8 +526,7 @@ BOOL CALLBACK DlgProc(HWND hDlg, UINT dlgmsg, WPARAM wParam, LPARAM lParam)
logger.Out(L"%s(%d): Initializing the 'Manual editing' dialog", TEXT(__FUNCTION__), __LINE__);
SetWindowTextW(hDlg, szTitle);
GetWindowTextW(hFgWnd, szWinTitle, _countof(szWinTitle));
GetClassNameW(hFgWnd, szWinClass, _countof(szWinClass));
GetClassNameW(hFgWnd, static_cast<LPWSTR>(szWinClassBuffer), MAX_WINTITLE_BUFFER_LENGTH);
GetWindowRect(hFgWnd, &rcFW);
x = rcFW.left;
y = rcFW.top;
@@ -458,8 +536,8 @@ BOOL CALLBACK DlgProc(HWND hDlg, UINT dlgmsg, WPARAM wParam, LPARAM lParam)
SetDlgItemInt(hDlg, IDC_EDIT_Y, y, TRUE);
SetDlgItemInt(hDlg, IDC_EDIT_WIDTH, w, FALSE);
SetDlgItemInt(hDlg, IDC_EDIT_HEIGHT, h, FALSE);
SetDlgItemTextW(hDlg, IDC_EDIT_TITLE, szWinTitle);
SetDlgItemTextW(hDlg, IDC_EDIT_CLASS, szWinClass);
SetDlgItemTextW(hDlg, IDC_EDIT_TITLE, static_cast<LPCWSTR>(szWinTitleBuffer));
SetDlgItemTextW(hDlg, IDC_EDIT_CLASS, static_cast<LPCWSTR>(szWinClassBuffer));
UpdateWindow(hDlg);
break;
}
@@ -480,9 +558,19 @@ BOOL CALLBACK DlgProc(HWND hDlg, UINT dlgmsg, WPARAM wParam, LPARAM lParam)
MoveWindow(hFgWnd, x, y, w, h, TRUE);
SendMessageW(hFgWnd, WM_EXITSIZEMOVE, NULL, NULL);
logger.Out(L"%s(%d): Window with handle 0x%08X was moved to %d, %d", TEXT(__FUNCTION__), __LINE__, hFgWnd, x, y);
logger.Out(L"%s(%d): Window with handle 0x%p was moved to %d, %d", TEXT(__FUNCTION__), __LINE__, hFgWnd, x, y);
return TRUE;
return static_cast<INT_PTR>(TRUE);
break;
}
case IDC_BUTTON_CENTER:
{
logger.Out(L"%s(%d): Pressed the 'Center' button", TEXT(__FUNCTION__), __LINE__);
bKPressed = TRUE;
if (IsWindowApprooved(hFgWnd)) MoveWindowToMonitorCenter(hFgWnd, bWorkArea, FALSE);
else hFgWnd = NULL;
return static_cast<INT_PTR>(TRUE);
break;
}
case IDCANCEL:
@@ -497,19 +585,19 @@ BOOL CALLBACK DlgProc(HWND hDlg, UINT dlgmsg, WPARAM wParam, LPARAM lParam)
break;
}
}
return FALSE;
return static_cast<INT_PTR>(FALSE);
}
BOOL IsWindowApprooved(HWND hFW)
{
logger.Out(L"Entering the %s() function, handle = 0x%08X", TEXT(__FUNCTION__), hFW);
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
bool bApprooved = FALSE;
BOOL bApprooved = FALSE;
if (hFW)
{
if (GetWindowTextW(hFW, (LPWSTR)szBuffer, MAX_WINTITLE_BUFFER_LENGTH))
if (GetWindowTextW(hFW, reinterpret_cast<LPWSTR>(szWinTitleBuffer), MAX_WINTITLE_BUFFER_LENGTH))
{
logger.Out(L"%s(%d): Window title: '%s'", TEXT(__FUNCTION__), __LINE__, (LPWSTR)szBuffer);
logger.Out(L"%s(%d): Window handle: 0x%p. Title: '%s'", TEXT(__FUNCTION__), __LINE__, hFW, reinterpret_cast<LPWSTR>(szWinTitleBuffer));
}
if (IsIconic(hFW))
@@ -531,7 +619,7 @@ BOOL IsWindowApprooved(HWND hFW)
bApprooved = TRUE;
}
else ShowError(IDS_ERR_MAXMIN);
else ShowError(IDS_ERR_MAXMIN, szTitle);
}
else
{
@@ -555,24 +643,20 @@ VOID HandlingTrayIcon()
if (fShowIcon)
{
bool bResult1 = Shell_NotifyIconW(NIM_ADD, &nid);
logger.Out(L"%s(%d): Shell_NotifyIconW(NIM_ADD): %s", TEXT(__FUNCTION__), __LINE__, bResult1 ? L"True" : L"False");
BOOL bResult1 = Shell_NotifyIconW(NIM_ADD, &nid);
logger.Out(L"%s(%d): Shell_NotifyIconW(NIM_ADD) returned %s", TEXT(__FUNCTION__), __LINE__, bResult1 ? L"True" : L"False");
bool bResult2 = Shell_NotifyIconW(NIM_SETVERSION, &nid);
logger.Out(L"%s(%d): Shell_NotifyIconW(NIM_SETVERSION): %s", TEXT(__FUNCTION__), __LINE__, bResult2 ? L"True" : L"False");
BOOL bResult2 = Shell_NotifyIconW(NIM_SETVERSION, &nid);
logger.Out(L"%s(%d): Shell_NotifyIconW(NIM_SETVERSION) returned %s", TEXT(__FUNCTION__), __LINE__, bResult2 ? L"True" : L"False");
if (!bResult1 || !bResult2)
{
logger.Out(L"%s(%d): Error creating trayicon!", TEXT(__FUNCTION__), __LINE__);
ShowError(IDS_ERR_ICON);
ShowError(IDS_ERR_ICON, szTitle);
Shell_NotifyIconW(NIM_DELETE, &nid);
fShowIcon = FALSE;
}
else
{
Shell_NotifyIconW(NIM_MODIFY, &nid);
}
}
else
{
@@ -582,11 +666,20 @@ VOID HandlingTrayIcon()
logger.Out(L"Exit from the %s() function", TEXT(__FUNCTION__));
}
VOID ShowError(UINT uID)
VOID ShowError(UINT uID, LPCWSTR szAppTitle)
{
WCHAR szErrorText[MAX_LOADSTRING]; // Error's text
LoadStringW(hInst, uID, szErrorText, _countof(szErrorText));
MessageBoxW(NULL, szErrorText, szTitle, MB_OK | MB_ICONERROR | MB_TOPMOST);
LoadStringW(GetModuleHandleW(NULL), uID, szErrorText, _countof(szErrorText));
MessageBoxW(hFgWnd, szErrorText, szAppTitle, MB_OK | MB_ICONERROR | MB_TOPMOST);
}
VOID ShowPopupMenu(HWND hMainWnd, POINT pt)
{
SetForegroundWindow(hMainWnd);
UINT uFlags = TPM_RIGHTBUTTON;
GetSystemMetrics(SM_MENUDROPALIGNMENT) != 0 ? uFlags |= TPM_RIGHTALIGN : uFlags |= TPM_LEFTALIGN;
TrackPopupMenuEx(hPopup, uFlags, pt.x, pt.y, hMainWnd, NULL);
PostMessageW(hMainWnd, WM_NULL, 0, 0);
}
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
@@ -605,15 +698,15 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
WCHAR szAboutProgName[MAX_LOADSTRING];
WCHAR szAboutCopyright[MAX_LOADSTRING];
WCHAR szAboutBuildTime[MAX_LOADSTRING];
WCHAR szAboutHelp[MAX_LOADSTRING * 12];
WCHAR szAboutLicense[MAX_LOADSTRING * 22];
LoadStringW(GetModuleHandleW(NULL), IDS_LICENSE, szAboutLicense, _countof(szAboutLicense));
MultiByteToWideChar(1251, 0, PRODUCT_NAME_FULL, _countof(PRODUCT_NAME_FULL), szAboutProgName, MAX_LOADSTRING);
MultiByteToWideChar(1251, 0, PRODUCT_COPYRIGHT, _countof(PRODUCT_COPYRIGHT), szAboutCopyright, MAX_LOADSTRING);
MultiByteToWideChar(1251, 0, ABOUT_BUILD, _countof(ABOUT_BUILD), szAboutBuildTime, MAX_LOADSTRING);
LoadStringW(hInst, IDS_ABOUT, szAboutHelp, _countof(szAboutHelp));
SetDlgItemTextW(hDlg, IDC_ABOUT_PROGNAME, szAboutProgName);
SetDlgItemTextW(hDlg, IDC_ABOUT_COPYRIGHT, szAboutCopyright);
SetDlgItemTextW(hDlg, IDC_ABOUT_BUILDTIME, szAboutBuildTime);
SetDlgItemTextW(hDlg, IDC_ABOUTEDIT, szAboutHelp);
SetDlgItemTextW(hDlg, IDC_ABOUTEDIT, szAboutLicense);
#ifdef NO_DONATION
HWND hLink = GetDlgItem(hDlg, IDC_DONATIONLINK);
if (hLink) DestroyWindow(hLink);
@@ -623,7 +716,7 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
logger.Out(L"%s(%d): End of initializing the 'About' dialog", TEXT(__FUNCTION__), __LINE__);
return (INT_PTR)TRUE;
return static_cast<INT_PTR>(TRUE);
break;
}
@@ -638,7 +731,7 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
logger.Out(L"%s(%d): Pressed the donation link! :-)", TEXT(__FUNCTION__), __LINE__);
return (INT_PTR)TRUE;
return static_cast<INT_PTR>(TRUE);
}
break;
}
@@ -651,10 +744,10 @@ INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
logger.Out(L"%s(%d): Closing the 'About' dialog", TEXT(__FUNCTION__), __LINE__);
return (INT_PTR)TRUE;
return static_cast<INT_PTR>(TRUE);
}
break;
}
}
return (INT_PTR)FALSE;
return static_cast<INT_PTR>(FALSE);
}

View File

@@ -1,9 +1,41 @@
// 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
//
#pragma once
#include "resource.h"
#define T0 10
#define T1 60
#define T2 86400
#ifdef _WIN64
#define ARCH 64
#else
#define ARCH 86
#endif
#define MAX_LOADSTRING 50
// Windows Header Files
@@ -14,6 +46,7 @@
#include <vector>
#include <strsafe.h>
#include <windows.h>
#include <windowsx.h>
#include <wininet.h>
#include <shellapi.h>
#include <CommCtrl.h>

Binary file not shown.

View File

@@ -112,7 +112,7 @@
</ManifestFromManagedAssembly>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)"</Command>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -137,7 +137,7 @@
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)"</Command>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -151,13 +151,14 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>powershell -File "$(SolutionDir)Update_Version.ps1" move /y "$(SolutionDir)VersionInfo.h" "$(ProjectDir)"</Command>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -176,13 +177,14 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>powershell -File "$(SolutionDir)Update_Version.ps1" move /y "$(SolutionDir)VersionInfo.h" "$(ProjectDir)"</Command>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>

View File

@@ -27,27 +27,24 @@
<ClInclude Include="wCenterWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="logger.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="globals.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="picojson.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="updater.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CLogger.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="wCenterWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="logger.cpp">
<ClCompile Include="updater.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="updater.cpp">
<ClCompile Include="CLogger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>

View File

@@ -7,5 +7,17 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>