171 Commits
v1.3 ... master

Author SHA1 Message Date
4d3db130a1 Merge branch 'dev' 2025-05-09 16:53:46 +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
739e363e67 Release v1.3.9 2025-05-03 17:04:18 +03:00
6b0a7265a7 Release 1.3.9 2025-05-03 16:59:52 +03:00
72a048875d Release v2.3.9 2024-03-03 16:33:46 +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
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
1a3e3ef4b1 Release v2.3.7 2023-11-28 18:16:36 +03:00
b0a14f731a Update check timers have been fixed. 2023-11-28 18:03:12 +03:00
b12bfe08be The Updater thread has been enabled back. 2023-11-28 17:48:23 +03:00
febb3bda2f Some fixes. 2023-11-28 17:34:55 +03:00
2d90c60a1c Replaced PostMessage() function.
The PostMessageW(WM_QUIT) function has been replaced by the PostQuitMessage() function.
2023-11-28 17:18:11 +03:00
382428e6fa Temporarily disabled Updater thread creation. 2023-11-28 17:10:07 +03:00
1f8fb92dbe Replaced macro calling.
The macro call has been replaced with a call to the Out() method of an instance of the CLogger class.
2023-11-28 17:02:14 +03:00
14ee12cb85 Added CLogger class into solution tree, and removed other unnecessary files. 2023-11-28 16:46:33 +03:00
56e6a5b6b2 Added CLogger class. 2023-11-28 16:41:39 +03:00
251b965073 Fixed missing break statement. 2023-11-08 23:37:30 +03:00
b855b0d624 Changed calling updater thread. 2023-11-07 17:55:47 +03:00
0403415607 Fix the git tagname parsing. 2023-11-07 17:48:53 +03:00
18959b1ef0 Fix updates timer. 2023-11-07 17:46:09 +03:00
4299d9b89f Fix updater.cpp. 2023-11-07 17:41:25 +03:00
049375a2d7 Update README.md. 2023-11-07 17:39:58 +03:00
5bf973347f Added a timer to periodically check for updates. 2023-11-07 17:38:24 +03:00
b71793cfed Added option to disable checking for updates.
Added commandline option '/noupdate' to disable check for updates.
2023-11-04 23:36:29 +03:00
0150121c02 Some optimizations.
Moved RECT and KBDLLHOOKSTRUCT structures from global scope to local.
2023-11-04 23:24:09 +03:00
W0LF
8303665159 Update README.md 2023-11-04 22:52:24 +03:00
f2ef0f9bb4 Update .gitignore file. 2023-11-03 15:12:51 +03:00
10db7316fa Release v2.3.6 2023-06-04 15:10:01 +03:00
5e9a553b67 Removed completed TODO. 2023-06-04 15:07:31 +03:00
e74c775f90 Added check for a new version of the application. 2023-06-04 14:23:35 +03:00
aadba59546 Changed the case in the file name. 2023-06-04 13:48:45 +03:00
b58039b4ab Added version information to the beginning of the log file. 2023-05-20 14:25:35 +03:00
9dd557311e Splitted single logger.h file to .h and .cpp files. 2023-05-20 13:52:40 +03:00
8df89dc8e1 Changed logger macros. 2023-05-20 13:08:17 +03:00
cf16651ae2 Moved headers from framework.h to wCenterWindow.h. 2023-05-20 13:00:48 +03:00
9fe46f867c Added globals.h header file for global variables. 2023-05-20 12:51:45 +03:00
bb904723fa Hided 'Donation:' string. 2023-05-20 12:33:51 +03:00
eaed0ae8dc Changed size and positioning of icon's control into About dialog according to new icons. 2023-05-20 12:27:01 +03:00
854a9a473b New program icon. Created by Kirill Topov. 2023-05-20 12:17:43 +03:00
W0LF
61b5f1d39c Merge pull request #3 from dreamforceinc/dev
Release v2.3.5
2023-04-12 09:19:22 +03:00
1dd9883f42 Release v2.3.5 2023-04-12 09:13:46 +03:00
90b281d3a5 Changed control for help text from static to EditText. 2023-04-12 08:54:30 +03:00
bf609d3c08 Added DestroyIcon() function. 2023-04-12 07:35:29 +03:00
582cce5b20 Changed Logger. 2023-04-11 19:02:53 +03:00
710d9d9d3e Added LoadIconMetric() function to drawing better quality icon on HiDPI displays. 2023-04-11 11:56:46 +03:00
b6a6ec685d Simplified the "IsWindowApprooved()" function. 2023-04-08 14:29:33 +03:00
28ea979492 Hid the donation link. 2023-04-08 11:55:56 +03:00
8cd54374ab Update versioning script. 2023-04-08 11:00:40 +03:00
9b3b505ec6 Update pre-build scripts. 2023-04-02 16:50:15 +03:00
d81f43b4a3 Move global szAboutHelp variable to local. 2023-03-26 23:16:05 +03:00
a1db2f16e9 Update versioning script. 2023-03-26 23:05:36 +03:00
117c4f780f Update About dialog. 2023-03-26 22:50:52 +03:00
266afddfe5 Update About dialog. 2023-03-26 22:50:18 +03:00
6b3a90d682 Update versioning scripts. 2023-03-26 21:29:55 +03:00
0f8304ef23 Update versioning scripts. 2023-03-26 21:28:59 +03:00
c035b8a980 Added TODOs. 2022-03-25 12:56:34 +03:00
cc2e5b5654 Released new version. 2022-03-16 17:42:44 +03:00
1929e3dc4f Update versioning. 2022-03-16 17:22:51 +03:00
93ea96bca0 Update .gitignore. 2022-03-16 09:39:43 +03:00
6fb8d35643 Update versioning. 2022-03-16 09:33:54 +03:00
7d0e5ee0a7 Moved Version.h to outside the project folder. 2022-03-15 17:36:49 +03:00
146208bd03 Update versioning. 2022-03-15 17:31:09 +03:00
342c6e3009 Fixed path in pre-build event. 2022-03-14 20:26:13 +03:00
bcf45417d8 Update Update_Rev.bat.
File Update_Rev.bat moved outside the project folder.
2022-03-14 20:23:25 +03:00
2763bbd12d Update .gitignore file. 2022-03-14 18:32:29 +03:00
a256184737 Fixed Update_Rev.bat 2022-03-14 18:24:48 +03:00
2510b74aa1 Added "autoversioning" when compiling. 2022-03-13 11:45:21 +03:00
96940111aa Improoved versioning.
Changed some literals to predefined constants in VERSIONINFO resource.
2022-03-02 15:19:59 +03:00
bad4d37e7a Some improovements. 2022-02-28 20:37:18 +03:00
fe10e4ec72 Reduced buffer length. 2022-02-28 19:56:37 +03:00
6edbf1f9c6 Changed PATH_LEN constant to internal MAX_PATH. 2022-02-28 19:52:56 +03:00
79acd5d110 Moved RegisterClass function into WinMain. 2022-02-28 19:32:46 +03:00
4d503f6421 Changed manifest. 2022-02-28 19:30:14 +03:00
dcf844ddd3 Changed function prototype. 2022-02-28 19:13:36 +03:00
517cfdcc82 Improoved logging. 2022-02-28 19:07:18 +03:00
5c3e15b949 Increased revision. 2022-02-25 19:20:06 +03:00
790ae9ab67 More logging. 2022-02-25 19:14:57 +03:00
52364a228a Replced some SendMessageW to PostMessageW. 2022-02-25 18:15:10 +03:00
W0LF
73b91259c8 Update README.md 2022-02-25 17:45:11 +03:00
cb01a4b815 Update README.md. 2022-02-25 17:21:28 +03:00
e15f08d521 Clean up code. 2022-02-25 16:28:14 +03:00
28de2585a8 Added handler.
Added WM_QUERYENDSESSION message handler for correct closing log-file.
2022-02-25 14:45:08 +03:00
3cd3faea01 Fixed list of arguments in log-file. 2022-02-25 14:41:35 +03:00
19660bb346 Fixed donation link. 2022-02-25 14:37:14 +03:00
b332c7476f Fix.
Fixed mistake not getting focus when calling manual edit window.
2022-02-25 14:34:51 +03:00
d5b3ef1040 Added missing initialization of some structures 2022-02-19 23:10:48 +03:00
76099356cd Fixed return of focus to the window after closing the manual editing dialog. 2022-02-19 23:03:53 +03:00
750ac44696 Added application guid for future use 2022-02-13 14:28:05 +03:00
0a0fe05555 Fix manifest 2022-02-13 12:36:22 +03:00
b6a0f9a3c5 Changed manifest 2022-02-13 12:31:56 +03:00
e7c06ec4b6 Changed size of NOTIFYICONDATA structure 2022-02-12 19:40:27 +03:00
f58e6a99cb Slightly cleaned up code 2022-02-12 18:13:19 +03:00
b5e040f3d5 Merge branch 'dev' of https://github.com/dreamforceinc/wCenterWindow into dev 2022-02-12 18:01:28 +03:00
fee7025323 Preparation for autoversioning 2022-02-12 18:01:07 +03:00
W0LF
6c9855ab38 Merge pull request #2 from dreamforceinc/master
Merge pull request #1 from dreamforceinc/dev
2022-02-12 17:32:23 +03:00
W0LF
3f438f6038 Merge pull request #1 from dreamforceinc/dev
v2.3.2
2022-02-12 17:31:42 +03:00
7491ed2ca7 Fixed (I hope) error creating trayicon 2022-02-12 04:37:44 +03:00
166cdd0d88 v2.3.1
Some improovements
2022-01-14 17:32:17 +03:00
d1ab2b86e2 Added more logging 2021-12-29 20:15:15 +03:00
690f621f5b Added some TODOs 2021-12-26 05:56:44 +03:00
01eb9075b4 Fixed a bug when the log file was not created in the program's folder when launched from the scheduler. 2021-12-19 06:23:32 +03:00
5137eed759 Added backing up previous logfile 2021-12-10 03:24:43 +03:00
b8d3db9289 Added simple logging 2021-12-10 02:20:42 +03:00
a4af63ed34 Version 2.2
Added manual editing of size and position of the widow.
Added centering the window by middle mouse button.
Updated project from Visual Studio 2017 to 2019.
2021-04-30 23:07:44 +03:00
W0LF
f394d436cf Update README.md 2020-05-03 18:57:37 +03:00
W0LF
bdb2ebd295 Delete wCenterWindow.h 2020-05-03 18:50:05 +03:00
W0LF
bd5d845ec1 Delete targetver.h 2020-05-03 18:49:07 +03:00
W0LF
a6c866d1dd Delete framework.h 2020-05-03 18:48:50 +03:00
W0LF
38a570310f Delete Resource.h 2020-05-03 18:48:32 +03:00
W0LF
4a96fef1c7 new version 2020-05-03 18:47:31 +03:00
W0LF
0f47ebae9e new version 2020-05-03 18:45:44 +03:00
f8b925d0f8 Update Readme.md 2020-01-24 15:06:19 +03:00
35f791d7a0 Added 'Hide Icon' option to menu. 2020-01-24 15:03:52 +03:00
W0LF
4586599d2c Update README.md 2020-01-23 17:32:57 +03:00
dfdbd6a94b Merge branch 'master' of https://github.com/dreamforceinc/wCenterWindow 2020-01-23 17:21:33 +03:00
5ef184bee3 change version number 2020-01-23 17:18:24 +03:00
ce31a7d6e0 Added commandline option '/hide' for hide trayicon at startup. 2020-01-23 17:15:30 +03:00
W0LF
00a949f502 Update README.md 2020-01-22 13:46:50 +03:00
W0LF
703fccaa15 Update README.md 2020-01-22 13:46:25 +03:00
25 changed files with 2763 additions and 539 deletions

7
.gitignore vendored
View File

@@ -6,6 +6,7 @@
*.user
*.userosscache
*.sln.docstates
[Vv]ersion.h
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@@ -326,7 +327,7 @@ var/
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
#*.manifest
*.spec
# Installer logs
@@ -436,3 +437,7 @@ lightgbm.Rcheck/
# GraphViz artifacts
*.gv
*.gv.*
/wCenterWindow/VersionInfo.h
[Pp]atches/
*.patch

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
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
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,2 +1,34 @@
# wCenterWindow
This program centers the current active window by a 'LCTRL + LWIN + C' hotkey.
## wCenterWindow
Copyright (c) 2020-2024 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.
`LCTRL + LWIN + I` hotkey is used to hide/show trayicon.
You can also use commandline option `/hide` to hide trayicon at startup.
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 (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.
## 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`).<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.<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
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.

177
Update_Version.ps1 Normal file
View File

@@ -0,0 +1,177 @@
# Update Version v2.1
# Required module: PSIni
# Installation: Install-Module -Name PsIni
$date = Get-Date
function addLeadingZero([int]$nvar) {
[string]$svar = $null
if ($nvar -lt 10) { $svar = '0' + $nvar.ToString() }
else { $svar = $nvar.ToString() }
return $svar
}
function getValue([string]$var) {
switch -CaseSensitive ($var) {
"%y" { $var = $currentYear; break }
"%m" { $var = $currentMonth; break }
"%d" { $var = $currentDay; break }
"%t" { $var = -join ((addLeadingZero($currentHour)), (addLeadingZero($currentMinute)), (addLeadingZero($currentSecond))); break }
"%D" { $var = $spanDays; break }
"%S" { $var = $spanSecs; break }
"%C" { $var = $gitCommitCount; break }
"%c" { $var = $gitRevCount; break }
}
return $var
}
function makeVersionString([string]$vmaj, [string]$vmin, [string]$vbld, [string]$vrev) {
[string]$vstr = $null
if ($vmin -eq "") { $vmin = $vbld = $vrev = 0; $vstr = ($vmaj) -join '.' }
else {
if ($vbld -eq "") { $vbld = $vrev = 0; $vstr = ($vmaj, $vmin) -join '.' }
else {
if ($vrev -eq "") { $vrev = 0; $vstr = ($vmaj, $vmin, $vbld) -join '.' }
else { $vstr = ($vmaj, $vmin, $vbld, $vrev) -join '.' }
}
}
[string]$nstr = ($vmaj, $vmin, $vbld, $vrev) -join ','
return @($vstr, $nstr)
}
#region Initializing variables
[string]$verMajor = [string]$verMinor = [string]$verBuild = [string]$verPatch = $null
[string]$pn = [string]$pa = [string]$aboutBuild = [string]$pnf = [string]$pcf = $null
[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
if (-not (Test-Path $iniFile)) {
Write-Error "Can't find file '$iniFile'"
# Start-Sleep -Seconds 3
exit 1
}
[bool]$isGit = $false
if (Test-Path ".\.git") {
$isGit = $true
[int]$gitCommitCount = [int]$gitRevCount = $null
[string]$gitRevDate = [string]$gitVerStr = [string]$gitAHash = $null
$gitCommitCount = $(git rev-list --count HEAD)
$gitRevDate = $(git log -1 HEAD --date=rfc --pretty=format:%ad%n)
$gitVerStr = $(git describe HEAD --long)
if ($LastExitCode -eq 0) {
$gitVerStr = $gitVerStr.Replace('-g', '-')
$gitRevCount = $gitVerStr.Split('-')[-2]
$gitAHash = $gitVerStr.Split('-')[-1]
}
else {
$gitVerStr = ""
$gitRevCount = 0
$gitAHash = $(git describe HEAD --always)
}
}
#region Reading values from INI file
$config = $null
$config = (Get-IniContent -FilePath $iniFile)["Config"]
$verMajor = $config.Major
$verMinor = $config.Minor
$verBuild = $config.Build
$verPatch = $config.Patch
$pys = $config.ProductYearStart
$pn = $config.ProductName
$pa = $config.ProductAutors
$pd = $config.ProductDescription
#endregion
if ($verMajor -eq "") {
Write-Error "Major version cannot be empty!"
# Start-Sleep -Seconds 3
exit 2
}
#region Variables preparation
$currentYear = $date.Year
$currentMonth = $date.Month
$currentDay = $date.Day
$currentHour = $date.Hour
$currentMinute = $date.Minute
$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 $pa" } else { $pcf = "Copyright (c) $pys-$currentYear $pa" }
$intName = "$pn-$platformArch-C++"
$origName = "$pn.exe"
$verMajor = getValue $verMajor
$verMinor = getValue $verMinor
$verBuild = getValue $verBuild
$verPatch = getValue $verPatch
#endregion
$vs = (makeVersionString $verMajor $verMinor $verBuild $verPatch)[0]
$vn = (makeVersionString $verMajor $verMinor $verBuild $verPatch)[1]
# if ([string]::IsNullOrEmpty($gitVerStr)) { $pnf = "$pn v$vs" } else { $pnf = "$pn $gitVerStr" }
if ($isGit) {
$aboutBuild = "Git date: $gitRevDate"
$pnf = "$pn v$vs ($gitAHash)"
}
else {
$aboutBuild = $buildDateTime
$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
"#pragma once" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define PRODUCT_NAME `"$pn`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define PRODUCT_NAME_FULL `"$pnf`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define PRODUCT_AUTHORS `"$pa`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define PRODUCT_DESCRIPTION `"$pd`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define ABOUT_BUILD `"$aboutBuild`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define INTERNAL_NAME `"$intName`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define ORIG_FILE_NAME `"$origName`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define PRODUCT_COPYRIGHT `"$pcf`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define VERSION_STR `"$vs`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
"#define VERSION_NUM $vn" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
# "#define SPAN_DAYS $spanDays" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
# "#define SPAN_SECS $spanSecs" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
# if ($isGit) {
# # "#define GIT_VERSION_STR `"$gitVerStr`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
# # "#define GIT_REV_DATE `"Git date: $gitRevDate`"" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
# # "#define GIT_REV_COUNT $gitRevCount" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
# # "#define GIT_COMMIT_COUNT $gitCommitCount" | Out-File -FilePath ".\VersionInfo.h" -Encoding unicode -Append
# }
#endregion
#region Print out all variables
# echo " verMajor: [$verMajor]"
# echo " verMinor: [$verMinor]"
# echo " verBuild: [$verBuild]"
# echo " verPatch: [$verPatch]"
# echo ""
# echo " aboutBuild: [$aboutBuild]"
# echo " platformArch: [$platformArch]"
# echo " productNameFull: [$pnf]"
# echo "productCopyrightFull: [$pcf]"
# echo " internalName: [$intName]"
# echo " originalName: [$origName]"
# echo " versionStr: [$vs]"
# echo " versionNum: [$vn]"
# echo " spanDays: [$spanDays]"
# echo " spanSecs: [$spanSecs]"
# echo ""
# echo " gitCommitCount: [$gitCommitCount]"
# echo " gitRevCount: [$gitRevCount]"
# echo " gitRevDate: [$gitRevDate]"
# echo " gitVerStr: [$gitVerStr]"
#endregion

21
Version.ini Normal file
View File

@@ -0,0 +1,21 @@
; wCenterWindow
; Version.ini
[Config]
; %y - current year
; %m - current month
; %d - current day
; %t - current time in HHMMSS form
; %D - span days from 01.01.2000
; %S - span seconds from midnight
; %C - total count git commits
; %c - count git commits from last tag
; Major version cannot be empty!
Major = 1
Minor = 3
Build = 10
Patch = %C
ProductYearStart = 2020
ProductName = wCenterWindow
ProductAutors = Vladislav Salikov aka W0LF
ProductDescription = Centers current active window on desktop by hotkey

25
pre-build.cmd Normal file
View File

@@ -0,0 +1,25 @@
@ECHO OFF
:: 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)" "$(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 %platformArch%
MOVE /Y %solutionDir%VersionInfo.h %projectDir%VersionInfo.h
EXIT
:no_args
ECHO Not enough arguments!
EXIT 1

View File

@@ -1,9 +1,14 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.1000
# Visual Studio Version 17
VisualStudioVersion = 17.5.33516.290
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wCenterWindow", "wCenterWindow\wCenterWindow.vcxproj", "{6A775901-6C34-4E96-B359-C11C76A520BB}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wCenterWindow", "wCenterWindow\wCenterWindow.vcxproj", "{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C7B4FD1E-DC1B-46A4-842C-5130F09EFCB5}"
ProjectSection(SolutionItems) = preProject
Version.ini = Version.ini
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,19 +18,19 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6A775901-6C34-4E96-B359-C11C76A520BB}.Debug|x64.ActiveCfg = Debug|x64
{6A775901-6C34-4E96-B359-C11C76A520BB}.Debug|x64.Build.0 = Debug|x64
{6A775901-6C34-4E96-B359-C11C76A520BB}.Debug|x86.ActiveCfg = Debug|Win32
{6A775901-6C34-4E96-B359-C11C76A520BB}.Debug|x86.Build.0 = Debug|Win32
{6A775901-6C34-4E96-B359-C11C76A520BB}.Release|x64.ActiveCfg = Release|x64
{6A775901-6C34-4E96-B359-C11C76A520BB}.Release|x64.Build.0 = Release|x64
{6A775901-6C34-4E96-B359-C11C76A520BB}.Release|x86.ActiveCfg = Release|Win32
{6A775901-6C34-4E96-B359-C11C76A520BB}.Release|x86.Build.0 = Release|Win32
{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}.Debug|x64.ActiveCfg = Debug|x64
{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}.Debug|x64.Build.0 = Debug|x64
{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}.Debug|x86.ActiveCfg = Debug|Win32
{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}.Debug|x86.Build.0 = Debug|Win32
{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}.Release|x64.ActiveCfg = Release|x64
{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}.Release|x64.Build.0 = Release|x64
{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}.Release|x86.ActiveCfg = Release|Win32
{F1A1603A-F5D0-47B8-8E4B-CF17747BCFBA}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CAD0B026-63B6-4645-9B26-22CD0E1049B7}
SolutionGuid = {83F3F9B6-B00E-4705-9C92-19308AAC038B}
EndGlobalSection
EndGlobal

83
wCenterWindow/CLogger.cpp Normal file
View File

@@ -0,0 +1,83 @@
// wCenterWindow
// CLogger.cpp
#include "CLogger.h"
#include <string>
#include <filesystem>
#include <strsafe.h>
// 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;
}
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::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);
}
}
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;
}
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"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(".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() {
if (fsLogFile) {
fsLogFile << ConvU16U8(GetTimeStamp()) << "Stop log." << std::endl;
fsLogFile.close();
DeleteCriticalSection(&cs);
}
}

30
wCenterWindow/CLogger.h Normal file
View File

@@ -0,0 +1,30 @@
// wCenterWindow
// CLogger.h
#pragma once
#include <Windows.h>
#include <fstream>
#define MAX_LOGBUFFER_LENGTH 512
class CLogger {
public:
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::ofstream fsLogFile;
std::wstring szAppTitle { 0 };
std::wstring szAppVersion { 0 };
std::wstring szAppPlatform { 0 };
std::wstring szAppTitleVer { 0 };
std::string ConvU16U8(const std::wstring&);
inline wchar_t* GetTimeStamp();
void Init();
};

View File

@@ -1,27 +0,0 @@
// resource.h
#define IDS_APP_TITLE 100
#define IDS_CLASSNAME 101
#define IDS_HELPTEXT 102
#define IDI_TRAYICON 103
#define IDR_MENU 104
#define ID_POPUPMENU_HELP 105
#define ID_POPUPMENU_EXIT 106
#define IDS_ERR_MAIN 107
#define IDS_ERR_WND 108
#define IDS_ERR_ICON 109
#define IDS_ERR_MENU 110
#define IDS_ERR_POPUP 111
#define IDS_ERR_HOOK 112
#define IDS_RUNNING 113
#define IDC_STATIC -1
// Next default values for new objects
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

Binary file not shown.

View File

@@ -1,15 +1,6 @@
// header.h: включаемый файл для стандартных системных включаемых файлов
// или включаемые файлы для конкретного проекта
#pragma once
// wCenterWindow
// framework.h
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Исключите редко используемые компоненты из заголовков Windows
// Файлы заголовков Windows
#include <windows.h>
#include <strsafe.h>
#include <shellapi.h>
// Файлы заголовков среды выполнения C
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

1010
wCenterWindow/picojson.h Normal file

File diff suppressed because it is too large Load Diff

49
wCenterWindow/resource.h Normal file
View File

@@ -0,0 +1,49 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by wCenterWindow.rc
//
#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
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 200
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1010
#define _APS_NEXT_SYMED_VALUE 122
#endif
#endif

View File

@@ -1,2 +1,12 @@
#pragma once
// wCenterWindow
// targetver.h
#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>

204
wCenterWindow/updater.cpp Normal file
View File

@@ -0,0 +1,204 @@
// wCenterWindow
// updater.h
#include "wCenterWindow.h"
#include "updater.h"
#include "picojson.h"
#include <cwctype>
#define GITHUB_URL TEXT("api.github.com")
#define GITHUB_URI TEXT("/repos/dreamforceinc/wCenterWindow/releases/latest")
picojson::value json;
struct Version {
UINT Major = 0;
UINT Minor = 0;
UINT Build = 0;
UINT Patch = 0;
} verApp, verGh;
bool GetLatestRelease(const std::wstring& urn);
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);
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);
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;
if (json.is<picojson::object>()) {
logger.Out(L"[UPDT] %s(%d): Parsing JSON object", TEXT(__FUNCTION__), __LINE__);
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 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);
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);
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__);
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__));
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;
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);
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 {
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;
}
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;
}

5
wCenterWindow/updater.h Normal file
View File

@@ -0,0 +1,5 @@
// wCenterWindow
// updater.h
#pragma once
UINT WINAPI Updater(void*);

View File

@@ -1,247 +1,647 @@
// wCenterWindow.cpp : Определяет точку входа для приложения.
// wCenterWindow
// wCenterWindow.cpp
// TODO: Split main cpp-file to separate files.
// TODO: Make Updater's errors as Windows notifications.
// TODO: Make the automatic updater (download, unzip and replace executable).
// TODO: Change keyboard low-level hook to RegisterHotKey function. (Is it really needed?)
#pragma warning( disable : 28251 )
#include "framework.h"
#include "wCenterWindow.h"
#include "updater.h"
#define MAX_LOADSTRING 80
#define WM_WCW WM_USER + 0x7F00
//#define NO_DONATION
#define KEY_I 0x49
#define KEY_C 0x43
#define KEY_V 0x56
// Глобальные переменные:
HINSTANCE hInst; // Текущий экземпляр
WCHAR szTitle[MAX_LOADSTRING]; // Текст строки заголовка
WCHAR szClass[MAX_LOADSTRING]; // Имя класса главного окна
WCHAR szHelp[MAX_LOADSTRING]; // Текст описания
HHOOK KeyboardHook;
HICON hIcon;
HMENU hMenu, hPopup;
HWND hWnd;
NOTIFYICONDATA nid = { 0 };
KBDLLHOOKSTRUCT *pkhs;
BOOL pressed = FALSE, showIcon = TRUE;
BOOL bLCTRL = FALSE, bLWIN = FALSE, bKEYI = FALSE, bKEYC = FALSE;
int dtCenterX, dtCenterY;
#define MAX_WINTITLE_BUFFER_LENGTH 1024
#define WM_WCW (WM_APP + 0x0F00)
// Прототипы функций
ATOM MyRegisterClass(HINSTANCE);
VOID ShowError(HINSTANCE, UINT);
// Global variables:
WCHAR szTitle[MAX_LOADSTRING]{ 0 }; // wCenterWindow's title
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;
UINT uMsgRestore = 0;
CLogger logger(TEXT(PRODUCT_NAME_FULL));
NOTIFYICONDATAW nid = { 0 };
MENUITEMINFOW mii = { 0 };
LPVOID szWinTitleBuffer = nullptr;
LPVOID szWinClassBuffer = nullptr;
// Forward declarations of functions included in this code module:
VOID HandlingTrayIcon();
VOID ShowError(UINT, LPCWSTR);
VOID ShowPopupMenu(HWND, POINT);
BOOL IsWindowApprooved(HWND);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK KeyboardHookProc(int, WPARAM, LPARAM);
BOOL CreateTrayIcon();
LRESULT CALLBACK MouseHookProc(int, WPARAM, LPARAM);
INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
HRESULT CALLBACK AboutCallback(HWND, UINT, WPARAM, LPARAM, LONG_PTR);
// Точка входа
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
static VOID MoveWindowToMonitorCenter(HWND hwnd, BOOL bWorkArea, BOOL bResize) {
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDS_CLASSNAME, szClass, MAX_LOADSTRING);
if (FindWindow(szClass, NULL))
{
ShowError(hInstance, IDS_RUNNING);
return FALSE;
RECT fgwrc = { 0 };
GetWindowRect(hwnd, &fgwrc);
LONG nWidth = fgwrc.right - fgwrc.left;
LONG nHeight = fgwrc.bottom - fgwrc.top;
logger.Out(L"%s(%d): Moving the window from %d, %d", TEXT(__FUNCTION__), __LINE__, fgwrc.left, fgwrc.top);
MONITORINFO mi = { 0 };
mi.cbSize = sizeof(MONITORINFO);
GetMonitorInfoW(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &mi);
RECT area = { 0 };
if (bWorkArea) {
area.bottom = mi.rcWork.bottom;
area.left = mi.rcWork.left;
area.right = mi.rcWork.right;
area.top = mi.rcWork.top;
}
MyRegisterClass(hInstance);
hWnd = CreateWindowExW(0, szClass, szTitle, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
ShowError(hInstance, IDS_ERR_WND);
return FALSE;
else {
area.bottom = mi.rcMonitor.bottom;
area.left = mi.rcMonitor.left;
area.right = mi.rcMonitor.right;
area.top = mi.rcMonitor.top;
}
if (showIcon)
{
if (!CreateTrayIcon())
{
ShowError(hInstance, IDS_ERR_ICON);
SendMessage(hWnd, WM_CLOSE, NULL, NULL);
LONG aw = area.right - area.left;
LONG ah = area.bottom - area.top;
if ((nWidth > aw) && bResize) nWidth = aw;
if ((nHeight > ah) && bResize) nHeight = ah;
if (area.left < 0) {
aw = -aw;
area.left = 0;
}
if (area.top < 0) {
ah = -ah;
area.top = 0;
}
int x = area.left + (aw - nWidth) / 2;
int y = area.top + (ah - nHeight) / 2;
logger.Out(L"%s(%d): Moving the window to %d, %d", TEXT(__FUNCTION__), __LINE__, x, y);
SendMessageW(hwnd, WM_ENTERSIZEMOVE, NULL, NULL);
MoveWindow(hwnd, x, y, nWidth, nHeight, TRUE);
SendMessageW(hwnd, WM_EXITSIZEMOVE, NULL, NULL);
logger.Out(L"Exit from the %s() function", TEXT(__FUNCTION__));
}
hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU));
if (!hMenu)
{
ShowError(hInstance, IDS_ERR_MENU);
SendMessage(hWnd, WM_CLOSE, NULL, NULL);
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
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, szTitle);
return -10;
}
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
int nArgs = 0;
LPWSTR* szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
logger.Out(L"Arguments count: %d", nArgs - 1);
if (nArgs > 1) {
for (int i = 1; i < nArgs; i++) {
logger.Out(L"Argument %d: %s", i, szArglist[i]);
if (0 == lstrcmpiW(szArglist[i], L"/hide")) fShowIcon = FALSE;
if (0 == lstrcmpiW(szArglist[i], L"/noupdate")) fCheckUpdates = FALSE;
}
}
LocalFree(szArglist);
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 = hIconLarge;
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.lpszClassName = szClass;
wcex.hIconSm = hIconSmall;
if (!RegisterClassExW(&wcex)) {
ShowError(IDS_ERR_CLASS, szTitle);
return -9;
}
HWND hMainWnd = CreateWindowExW(0, szClass, szTitle, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if (!hMainWnd) {
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)
{
ShowError(hInstance, IDS_ERR_POPUP);
SendMessage(hWnd, WM_CLOSE, NULL, NULL);
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();
HANDLE hHeap = GetProcessHeap();
szWinTitleBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_WINTITLE_BUFFER_LENGTH);
if (nullptr == szWinTitleBuffer) {
ShowError(IDS_ERR_HEAP, szTitle);
return -3;
}
KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, hInstance, NULL);
if (!KeyboardHook)
{
ShowError(hInstance, IDS_ERR_HOOK);
SendMessage(hWnd, WM_CLOSE, NULL, NULL);
szWinClassBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, MAX_WINTITLE_BUFFER_LENGTH);
if (nullptr == szWinClassBuffer) {
ShowError(IDS_ERR_HEAP, szTitle);
return -2;
}
LoadStringW(hInstance, IDS_HELPTEXT, szHelp, MAX_LOADSTRING);
RECT dtrc = { 0 };
SystemParametersInfo(SPI_GETWORKAREA, NULL, &dtrc, FALSE);
dtCenterX = dtrc.right / 2, dtCenterY = dtrc.bottom / 2;
MSG msg;
BOOL bRet;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
ShowError(hInstance, IDS_ERR_MAIN);
while ((bRet = GetMessageW(&msg, NULL, 0, 0)) != 0) {
if (bRet == -1) {
ShowError(IDS_ERR_MAIN, szTitle);
return -1;
}
else
{
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
DispatchMessageW(&msg);
}
}
return (int)msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TRAYICON));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.lpszClassName = szClass;
wcex.hIconSm = wcex.hIcon;
hIcon = wcex.hIcon;
return RegisterClassEx(&wcex);
#ifndef _DEBUG
if (hMouseHook) UnhookWindowsHookEx(hMouseHook);
#endif // !_DEBUG
if (hKbdHook) UnhookWindowsHookEx(hKbdHook);
if (hMenu) DestroyMenu(hMenu);
Shell_NotifyIconW(NIM_DELETE, &nid);
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 = 0x%p", TEXT(__FUNCTION__), msg.wParam);
return static_cast<UINT_PTR>(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) {
case WM_CREATE:
{
switch (message)
{
case WM_WCW:
if (lParam == WM_RBUTTONDOWN && wParam == IDI_TRAYICON)
{
SetForegroundWindow(hWnd);
POINT pt;
GetCursorPos(&pt);
int idMenu = TrackPopupMenu(hPopup, TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, NULL);
if (idMenu == ID_POPUPMENU_HELP && !pressed)
{
pressed = TRUE;
if (MessageBox(hWnd, szHelp, szTitle, MB_OK | MB_TOPMOST) == IDOK) pressed = FALSE;
logger.Out(L"%s(%d): Recived WM_CREATE message", TEXT(__FUNCTION__), __LINE__);
nid.cbSize = sizeof(NOTIFYICONDATAW);
nid.hWnd = hMainWnd;
nid.uVersion = NOTIFYICON_VERSION_4;
nid.uCallbackMessage = WM_WCW;
nid.hIcon = hIconSmall;
nid.uID = IDI_TRAYICON;
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__);
}
if (idMenu == ID_POPUPMENU_EXIT) SendMessage(hWnd, WM_CLOSE, NULL, NULL);
logger.Out(L"%s(%d): The 'TaskbarCreated' message successfully registered", TEXT(__FUNCTION__), __LINE__);
if (fCheckUpdates) {
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, szTitle);
fCheckUpdates = FALSE;
}
logger.Out(L"%s(%d): Timer successfully created (%d sec)", TEXT(__FUNCTION__), __LINE__, (T1 - T0));
}
break;
}
case WM_TIMER:
{
if (fCheckUpdates) {
logger.Out(L"%s(%d): Checking for updates is enabled", TEXT(__FUNCTION__), __LINE__);
HANDLE hUpdater = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, &Updater, NULL, 0, NULL));
if (NULL == hUpdater) {
DWORD dwLastError = GetLastError();
logger.Out(L"%s(%d): Creating Updater thread failed! Error: %d", TEXT(__FUNCTION__), __LINE__, dwLastError);
}
else {
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, szTitle);
fCheckUpdates = FALSE;
}
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", TEXT(__FUNCTION__), __LINE__);
}
break;
}
// Popup menu handler
case WM_WCW:
{
if (WM_CONTEXTMENU == LOWORD(lParam)) {
logger.Out(L"%s(%d): Recived WM_CONTEXTMENU message", TEXT(__FUNCTION__), __LINE__);
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;
}
case ID_POPUPMENU_AREA:
{
logger.Out(L"%s(%d): Pressed the 'Use workarea' menuitem", TEXT(__FUNCTION__), __LINE__);
bWorkArea = !bWorkArea;
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;
}
case ID_POPUPMENU_HELP:
{
if (!bKPressed) {
logger.Out(L"%s(%d): Pressed the 'Help' menuitem", TEXT(__FUNCTION__), __LINE__);
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;
}
case ID_POPUPMENU_ABOUT:
{
if (!bKPressed) {
logger.Out(L"%s(%d): Pressed the 'About' menuitem", TEXT(__FUNCTION__), __LINE__);
bKPressed = TRUE;
WCHAR szContent[MAX_LOADSTRING * 6] = { 0 };
StringCchPrintfW(szContent, ARRAYSIZE(szContent),
L"%s\n%s\n\n%s\n%s\n%s",
TEXT(PRODUCT_COPYRIGHT),
L"Program icon made by Kirill Topov.",
L"This software is licensed under a <A HREF=\"https://mit-license.org\">MIT License</A>.",
L"This software uses the <A HREF=\"https://github.com/kazuho/picojson\">PicoJSON</A> - a C++ JSON parser/serializer by Kazuho Oku.",
#ifndef NO_DONATION
L"\n<A HREF=\"https://www.paypal.com/paypalme/VladislavSalikov\">Donate via PayPal</A>"
#else
L""
#endif // !NO_DONATION
);
TASKDIALOGCONFIG tdc = { 0 };
tdc.cbSize = sizeof(tdc);
tdc.hInstance = GetModuleHandleW(NULL);
tdc.dwFlags = TDF_ENABLE_HYPERLINKS | TDF_ALLOW_DIALOG_CANCELLATION | TDF_USE_HICON_MAIN | TDF_SIZE_TO_CONTENT;
tdc.dwCommonButtons = TDCBF_OK_BUTTON;
tdc.pszWindowTitle = L"About";
tdc.hMainIcon = hIconLarge;
tdc.pszMainInstruction = TEXT(PRODUCT_NAME_FULL);
tdc.pszContent = szContent;
tdc.pfCallback = AboutCallback;
TaskDialogIndirect(&tdc, NULL, NULL, NULL);
bKPressed = FALSE;
}
break;
}
case ID_POPUPMENU_EXIT:
{
logger.Out(L"%s(%d): Pressed the 'Exit' menuitem", TEXT(__FUNCTION__), __LINE__);
DestroyWindow(hMainWnd);
break;
}
}
break;
}
case WM_QUERYENDSESSION:
{
logger.Out(L"%s(%d): Recieved the WM_QUERYENDSESSION message, lParam = 0x%p", TEXT(__FUNCTION__), __LINE__, lParam);
PostQuitMessage(0);
return TRUE;
break;
}
case WM_DESTROY:
if (KeyboardHook) UnhookWindowsHookEx(KeyboardHook);
if (hMenu) DestroyMenu(hMenu);
Shell_NotifyIcon(NIM_DELETE, &nid);
{
logger.Out(L"%s(%d): Recieved the WM_DESTROY message", TEXT(__FUNCTION__), __LINE__);
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
{
if (message == uMsgRestore) {
logger.Out(L"%s(%d): Recieved the 'TaskbarCreated' message", TEXT(__FUNCTION__), __LINE__);
HandlingTrayIcon();
break;
}
return DefWindowProcW(hMainWnd, message, wParam, lParam);
}
}
return 0;
}
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
pkhs = (KBDLLHOOKSTRUCT*)lParam;
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (WM_MBUTTONUP == wParam) bMPressed = FALSE;
if (WM_MBUTTONDOWN == wParam && bLCTRL && bLWIN && !bMPressed) {
logger.Out(L"%s(%d): Pressed LCTRL + LWIN + MMB", TEXT(__FUNCTION__), __LINE__);
if (wParam == WM_KEYUP)
{
if (pkhs->vkCode == VK_LCONTROL) bLCTRL = FALSE;
if (pkhs->vkCode == VK_LWIN) bLWIN = FALSE;
pressed = FALSE;
bMPressed = TRUE;
hFgWnd = GetForegroundWindow();
if (IsWindowApprooved(hFgWnd)) MoveWindowToMonitorCenter(hFgWnd, bWorkArea, FALSE);
else hFgWnd = NULL;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
if (wParam == WM_KEYDOWN)
{
if (pkhs->vkCode == VK_LCONTROL) bLCTRL = TRUE;
if (pkhs->vkCode == VK_LWIN) bLWIN = TRUE;
if (bLCTRL && bLWIN && pkhs->vkCode == 0x49 && !pressed) // 'I' key
{
pressed = TRUE;
showIcon = !showIcon;
if (showIcon)
{
if (!CreateTrayIcon())
{
ShowError(GetModuleHandle(NULL), IDS_ERR_ICON);
showIcon = FALSE;
}
}
else
{
Shell_NotifyIcon(NIM_DELETE, &nid);
}
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
LPKBDLLHOOKSTRUCT pkhs = { 0 };
pkhs = reinterpret_cast<LPKBDLLHOOKSTRUCT>(lParam);
if (WM_KEYUP == wParam) {
if (VK_LCONTROL == pkhs->vkCode) bLCTRL = FALSE;
if (VK_LWIN == pkhs->vkCode) bLWIN = FALSE;
bKPressed = FALSE;
}
if (bLCTRL && bLWIN && pkhs->vkCode == 0x43 && !pressed) // 'C' key
{
pressed = TRUE;
HWND fgWindow = GetForegroundWindow();
if (fgWindow)
{
HWND parentWindow = fgWindow;
while (TRUE)
{
parentWindow = GetParent(fgWindow);
if (parentWindow) fgWindow = parentWindow;
else break;
if (WM_KEYDOWN == wParam) {
if (VK_LCONTROL == pkhs->vkCode) bLCTRL = TRUE;
if (VK_LWIN == pkhs->vkCode) bLWIN = TRUE;
// 'I' key
if (KEY_I == pkhs->vkCode && bLCTRL && bLWIN && !bKPressed) {
logger.Out(L"%s(%d): Pressed LCTRL + LWIN + I", TEXT(__FUNCTION__), __LINE__);
bKPressed = TRUE;
fShowIcon = !fShowIcon;
HandlingTrayIcon();
return TRUE;
}
WINDOWPLACEMENT wp = { 0 };
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(fgWindow, &wp);
if (wp.showCmd == SW_SHOWNORMAL)
{
int fgW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
int fgH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
int fgX = dtCenterX - (fgW / 2);
int fgY = dtCenterY - (fgH / 2);
wp.rcNormalPosition.left = fgX;
wp.rcNormalPosition.top = fgY;
wp.rcNormalPosition.right = fgX + fgW;
wp.rcNormalPosition.bottom = fgY + fgH;
SendMessage(fgWindow, WM_ENTERSIZEMOVE, NULL, NULL);
SetWindowPlacement(fgWindow, &wp);
SendMessage(fgWindow, WM_EXITSIZEMOVE, NULL, NULL);
// 'C' key
if (KEY_C == pkhs->vkCode && bLCTRL && bLWIN && !bKPressed && !bKEYV) {
logger.Out(L"%s(%d): Pressed LCTRL + LWIN + C", TEXT(__FUNCTION__), __LINE__);
bKPressed = TRUE;
hFgWnd = GetForegroundWindow();
if (IsWindowApprooved(hFgWnd)) MoveWindowToMonitorCenter(hFgWnd, bWorkArea, FALSE);
else hFgWnd = NULL;
return TRUE;
}
// 'V' key
if (KEY_V == pkhs->vkCode && bLCTRL && bLWIN && !bKPressed && !bKEYV) {
logger.Out(L"%s(%d): Pressed LCTRL + LWIN + V", TEXT(__FUNCTION__), __LINE__);
bKPressed = TRUE; bKEYV = TRUE;
hFgWnd = GetForegroundWindow();
if (IsWindowApprooved(hFgWnd)) {
logger.Out(L"%s(%d): Opening the 'Manual editing' dialog", TEXT(__FUNCTION__), __LINE__);
DialogBoxParamW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_MANUAL_EDITING), hFgWnd, static_cast<DLGPROC>(DlgProc), 0L);
SetForegroundWindow(hFgWnd);
}
else hFgWnd = NULL;
bKEYV = FALSE;
return TRUE;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
BOOL CreateTrayIcon()
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT dlgmsg, WPARAM wParam, LPARAM lParam) {
RECT rcFW = { 0 };
int x, y, w, h;
switch (dlgmsg) {
case WM_INITDIALOG:
{
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uVersion = NOTIFYICON_VERSION;
nid.uCallbackMessage = WM_WCW;
nid.hIcon = hIcon;
nid.uID = IDI_TRAYICON;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.dwInfoFlags = NIIF_INFO;
StringCchCopy(nid.szTip, sizeof(nid.szTip), szTitle);
return Shell_NotifyIcon(NIM_ADD, &nid);
logger.Out(L"%s(%d): Initializing the 'Manual editing' dialog", TEXT(__FUNCTION__), __LINE__);
SetWindowTextW(hDlg, szTitle);
GetClassNameW(hFgWnd, static_cast<LPWSTR>(szWinClassBuffer), MAX_WINTITLE_BUFFER_LENGTH);
GetWindowRect(hFgWnd, &rcFW);
x = rcFW.left;
y = rcFW.top;
w = rcFW.right - rcFW.left;
h = rcFW.bottom - rcFW.top;
SetDlgItemInt(hDlg, IDC_EDIT_X, x, TRUE);
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, static_cast<LPCWSTR>(szWinTitleBuffer));
SetDlgItemTextW(hDlg, IDC_EDIT_CLASS, static_cast<LPCWSTR>(szWinClassBuffer));
UpdateWindow(hDlg);
break;
}
VOID ShowError(HINSTANCE hInstance, UINT uID)
case WM_COMMAND:
{
WCHAR szErrorText[MAX_LOADSTRING]; // Текст ошибки
LoadStringW(hInstance, uID, szErrorText, MAX_LOADSTRING);
MessageBox(hWnd, szErrorText, szTitle, MB_OK | MB_ICONERROR);
switch (LOWORD(wParam)) {
case IDC_BUTTON_SET:
{
logger.Out(L"%s(%d): Pressed the 'Set' button", TEXT(__FUNCTION__), __LINE__);
x = GetDlgItemInt(hDlg, IDC_EDIT_X, NULL, TRUE);
y = GetDlgItemInt(hDlg, IDC_EDIT_Y, NULL, TRUE);
w = GetDlgItemInt(hDlg, IDC_EDIT_WIDTH, NULL, FALSE);
h = GetDlgItemInt(hDlg, IDC_EDIT_HEIGHT, NULL, FALSE);
SendMessageW(hFgWnd, WM_ENTERSIZEMOVE, NULL, NULL);
MoveWindow(hFgWnd, x, y, w, h, TRUE);
SendMessageW(hFgWnd, WM_EXITSIZEMOVE, NULL, NULL);
logger.Out(L"%s(%d): Window with handle 0x%p was moved to %d, %d", TEXT(__FUNCTION__), __LINE__, hFgWnd, x, y);
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:
case IDC_BUTTON_CLOSE:
{
logger.Out(L"%s(%d): Closing the 'Manual editing' dialog", TEXT(__FUNCTION__), __LINE__);
EndDialog(hDlg, LOWORD(wParam));
break;
}
}
break;
}
}
return static_cast<INT_PTR>(FALSE);
}
BOOL IsWindowApprooved(HWND hFW) {
logger.Out(L"Entering the %s() function", TEXT(__FUNCTION__));
BOOL bApprooved = FALSE;
if (hFW) {
if (GetWindowTextW(hFW, reinterpret_cast<LPWSTR>(szWinTitleBuffer), MAX_WINTITLE_BUFFER_LENGTH)) {
logger.Out(L"%s(%d): Window handle: 0x%p. Title: '%s'", TEXT(__FUNCTION__), __LINE__, hFW, reinterpret_cast<LPWSTR>(szWinTitleBuffer));
}
if (IsIconic(hFW)) {
logger.Out(L"%s(%d): The window is iconified", TEXT(__FUNCTION__), __LINE__);
}
if (IsZoomed(hFW)) {
logger.Out(L"%s(%d): The window is maximized", TEXT(__FUNCTION__), __LINE__);
}
LONG_PTR wlp = GetWindowLongPtrW(hFW, GWL_STYLE);
if (wlp & WS_CAPTION) {
if (!IsIconic(hFW) && !IsZoomed(hFW)) {
logger.Out(L"%s(%d): The window is approved!", TEXT(__FUNCTION__), __LINE__);
bApprooved = TRUE;
}
else ShowError(IDS_ERR_MAXMIN, szTitle);
}
else {
logger.Out(L"%s(%d): The window has no caption!", TEXT(__FUNCTION__), __LINE__);
}
}
if (!bApprooved) {
logger.Out(L"%s(%d): The window is not approved!", TEXT(__FUNCTION__), __LINE__);
}
logger.Out(L"Exit from the %s() function", TEXT(__FUNCTION__));
return bApprooved;
}
VOID HandlingTrayIcon() {
logger.Out(L"Entering the %s() function, fShowIcon = %s", TEXT(__FUNCTION__), fShowIcon ? L"True" : L"False");
if (fShowIcon) {
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) 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, szTitle);
Shell_NotifyIconW(NIM_DELETE, &nid);
fShowIcon = FALSE;
}
}
else {
Shell_NotifyIconW(NIM_DELETE, &nid);
}
logger.Out(L"Exit from the %s() function", TEXT(__FUNCTION__));
}
VOID ShowError(UINT uID, LPCWSTR szAppTitle) {
WCHAR szErrorText[MAX_LOADSTRING]; // Error's text
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);
}
HRESULT CALLBACK AboutCallback(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData) {
if (TDN_HYPERLINK_CLICKED == uMsg) {
ShellExecuteW(hDlg, L"open", reinterpret_cast<LPCWSTR>(lParam), NULL, NULL, SW_SHOW);
}
return S_OK;
}

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<description>Centers windows by hotkey (C++)</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="Win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
publicKeyToken="6595b64144ccf1df"
language="*"
processorArchitecture="*"/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--ID Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--ID Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--ID Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--ID Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!--ID Windows 10/11 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware> </windowsSettings>
<windowsSettings> <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness> </windowsSettings>
<windowsSettings> <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware> </windowsSettings>
<windowsSettings> <heapType xmlns="http://schemas.microsoft.com/SMI/2020/WindowsSettings">SegmentHeap</heapType> </windowsSettings>
</application>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

View File

@@ -1,2 +1,43 @@
// 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 64
// Windows Header Files
#include <fstream>
#include <sstream>
#include <filesystem>
#include <string>
#include <vector>
#include <strsafe.h>
#include <windows.h>
#include <windowsx.h>
#include <wininet.h>
#include <shellapi.h>
#include <CommCtrl.h>
#include <process.h>
// Logger header file
#include "CLogger.h"
// VerionInfo header file
#include "VersionInfo.h"
// wCenterWindow's title
extern WCHAR szTitle[MAX_LOADSTRING];
// An instance of the "CLogger" class
extern CLogger logger;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -19,36 +19,37 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{6A775901-6C34-4E96-B359-C11C76A520BB}</ProjectGuid>
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{f1a1603a-f5d0-47b8-8e4b-cf17747bcfba}</ProjectGuid>
<RootNamespace>wCenterWindow</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<XPDeprecationWarning>false</XPDeprecationWarning>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</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>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@@ -72,93 +73,134 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<EnableMicrosoftCodeAnalysis>false</EnableMicrosoftCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<CopyCppRuntimeToOutputDir>false</CopyCppRuntimeToOutputDir>
<CopyLocalDeploymentContent>false</CopyLocalDeploymentContent>
<CopyLocalProjectReference>false</CopyLocalProjectReference>
<CopyLocalDebugSymbols>false</CopyLocalDebugSymbols>
<EnableMicrosoftCodeAnalysis>false</EnableMicrosoftCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<CopyLocalDeploymentContent>false</CopyLocalDeploymentContent>
<CopyLocalProjectReference>false</CopyLocalProjectReference>
<CopyLocalDebugSymbols>false</CopyLocalDebugSymbols>
<CopyCppRuntimeToOutputDir>false</CopyCppRuntimeToOutputDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<ConformanceMode>false</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
<ManifestFromManagedAssembly>
</ManifestFromManagedAssembly>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<DebugInformationFormat>None</DebugInformationFormat>
<ConformanceMode>false</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AssemblyDebug>false</AssemblyDebug>
<AdditionalDependencies>comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>comctl32.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)pre-build.cmd" "$(SolutionDir)" "$(ProjectDir)" "$(PlatformTarget)"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="CLogger.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="picojson.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="updater.h" />
<ClInclude Include="wCenterWindow.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CLogger.cpp" />
<ClCompile Include="updater.cpp" />
<ClCompile Include="wCenterWindow.cpp" />
</ItemGroup>
<ItemGroup>
@@ -167,6 +209,12 @@
<ItemGroup>
<Image Include="wCenterWindow.ico" />
</ItemGroup>
<ItemGroup>
<Manifest Include="wCenterWindow.exe.manifest" />
</ItemGroup>
<ItemGroup>
<None Include="..\README.md" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@@ -1,46 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Исходные файлы">
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Файлы заголовков">
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Файлы ресурсов">
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="framework.h">
<Filter>Файлы заголовков</Filter>
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Файлы заголовков</Filter>
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wCenterWindow.h">
<Filter>Файлы заголовков</Filter>
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Файлы заголовков</Filter>
<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>Исходные файлы</Filter>
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="updater.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CLogger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="wCenterWindow.rc">
<Filter>Файлы ресурсов</Filter>
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Image Include="wCenterWindow.ico">
<Filter>Файлы ресурсов</Filter>
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Manifest Include="wCenterWindow.exe.manifest">
<Filter>Resource Files</Filter>
</Manifest>
</ItemGroup>
<ItemGroup>
<None Include="..\README.md" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</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>