63 Commits
v1.3 ... v2.3.4

Author SHA1 Message Date
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
18 changed files with 1221 additions and 537 deletions

3
.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

View File

@@ -1,2 +1,22 @@
# wCenterWindow
This program centers the current active window by a 'LCTRL + LWIN + C' hotkey.
## wCenterWindow
This program centers the current active window by a `LCTRL + LWIN + C` hotkey,
or pressing `LCTRL + LWIN + MMB` (Middle Mouse Button).
`LCTRL + LWIN + V` - manual editing of size and position of the window.
You can use `LCTRL + LWIN + I` hotkey for hide/show trayicon.
You can also use commandline option `/hide` for hide trayicon at startup.
`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.
## 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').\
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.\
**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".

81
Update_version.bat Normal file
View File

@@ -0,0 +1,81 @@
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET CURRENT_TIME=%TIME%
SET CURRENT_DATE=%DATE%
SET BUILDTIME=%CURRENT_TIME:~0,8%
SET BUILDDATE=%CURRENT_DATE%
SET BUILD_DATETIME=Build time: %BUILDDATE% %BUILDTIME%
SET CURRENT_YEAR=%CURRENT_DATE:~6,4%
SET BUILDSECS=0
SET GIT_COUNT=0
SET GIT_TIME=0
SET GIT_DATE=0
SET GIT_DATETIME=0
SET VerMajor=0
SET VerMinor=0
SET VerPatch=0
SET INT_NAME=0
SET PN=0
SET VS=0
SET VSF=0
SET PCF=0
SET PYS=0
SET PA=0
CD /D %~dp0
IF NOT EXIST "VersionInfo.h" (
ECHO Can't find file 'VersionInfo.h'
TIMEOUT /T 3
EXIT /B 1
)
COPY /Y "VersionInfo.h" "version.h" >nul
FOR /F "tokens=3" %%A IN ('FINDSTR /I /L /C:"define V_MAJOR" "version.h"') DO (SET "VerMajor=%%A")
FOR /F "tokens=3" %%A IN ('FINDSTR /I /L /C:"define V_MINOR" "version.h"') DO (SET "VerMinor=%%A")
FOR /F "tokens=3" %%A IN ('FINDSTR /I /L /C:"define V_PATCH" "version.h"') DO (SET "VerPatch=%%A")
FOR /F "tokens=3" %%A IN ('FINDSTR /I /L /C:"define PRODUCT_NAME" "version.h"') DO (SET "PN=%%~A")
FOR /F "tokens=3" %%A IN ('FINDSTR /I /L /C:"define PRODUCT_YEAR_START" "version.h"') DO (SET "PYS=%%A")
FOR /F "tokens=2*" %%A IN ('FINDSTR /I /L /C:"define PRODUCT_AUTHORS" "version.h"') DO (SET "PA=%%~B")
FOR /F "tokens=1-4 delims=:., " %%A IN ("%BUILDTIME%") DO (SET /A "BUILDSECS=%%A * 3600 + %%B * 60 + %%C")
FOR /F "delims=" %%A IN ('git rev-list --count HEAD') DO (SET /A GIT_COUNT=%%A)
FOR /F "tokens=1,2 delims= " %%A IN ('git log -1 --date=format:%%d.%%m.%%Y ^| find /I "Date:"') DO (SET "GIT_DATE=%%B")
FOR /F "tokens=2-4 delims=, " %%A IN ('git log -1 --date=format:"%%a,%%d-%%h-%%Y,%%T" ^| find /I "Date:"') DO (
SET "GIT_DATETIME=Git time: %%A, %%B %%C"
SET "GIT_TIME=%%C"
)
SET VSF=%VerMajor%.%VerMinor%.%VerPatch%.%GIT_COUNT%
SET VS=%VerMajor%.%VerMinor%.%VerPatch%
SET VNF=%VerMajor%,%VerMinor%,%VerPatch%,%GIT_COUNT%
SET VN=%VerMajor%,%VerMinor%,%VerPatch%
SET PNF=%PN% v%VS% (C++)
SET PCF=Copyright (C) %PYS%-%CURRENT_YEAR% by %PA%
SET INT_NAME=%PN%C++
SET ORIG_NAME=%PN%.exe
ECHO #define BUILD_DATE "%BUILDDATE%">> version.h
ECHO #define BUILD_TIME "%BUILDTIME%">> version.h
ECHO #define BUILD_DATETIME "%BUILD_DATETIME%">> version.h
ECHO #define GIT_DATE "%GIT_DATE%">> version.h
ECHO #define GIT_TIME "%GIT_TIME%">> version.h
ECHO #define GIT_DATETIME "%GIT_DATETIME%">> version.h
ECHO #define GIT_COUNT %GIT_COUNT% >> version.h
ECHO #define V_SECS %BUILDSECS% >> version.h
ECHO #define INTERNAL_NAME "%INT_NAME%">> version.h
ECHO #define ORIG_FILE_NAME "%ORIG_NAME%">> version.h
ECHO #define PRODUCT_NAME_FULL "%PNF%">> version.h
ECHO #define PRODUCT_COPYRIGHT "%PCF%">> version.h
ECHO #define VERSION_NUM %VN% >> version.h
ECHO #define VERSION_STR "%VS%">> version.h
ECHO #define VERSION_NUM_FULL %VNF% >> version.h
ECHO #define VERSION_STR_FULL "%VSF%">> version.h
ENDLOCAL
EXIT

12
VersionInfo.h Normal file
View File

@@ -0,0 +1,12 @@
// wCenterWindow
// version.h
//
#pragma once
#define V_MAJOR 2
#define V_MINOR 3
#define V_PATCH 4
#define PRODUCT_NAME "wCenterWindow"
#define PRODUCT_AUTHORS "W0LF aka 'dreamforce'"
#define PRODUCT_YEAR_START 2020
#define PRODUCT_DESCRIPTION "Centers windows by hotkey"

View File

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

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.1000
# Visual Studio Version 16
VisualStudioVersion = 16.0.31112.23
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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -13,19 +13,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

70
wCenterWindow/Logger.cpp Normal file
View File

@@ -0,0 +1,70 @@
// wCenterWindow
// Logger.cpp
//
#include "framework.h"
#define TS_LEN 30
std::ofstream logfile;
extern WCHAR szTitle[];
extern LPVOID szBuffer;
std::string GetTimeStamp()
{
SYSTEMTIME lt;
GetLocalTime(&lt);
CHAR ts[TS_LEN];
StringCchPrintfA(ts, TS_LEN, "%d-%02d-%02d %02d:%02d:%02d.%03d - ", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond, lt.wMilliseconds);
return ts;
}
void OpenLogFile()
{
WCHAR lpszPath[MAX_PATH + 1] = { 0 };
DWORD dwPathLength = GetModuleFileNameW(NULL, lpszPath, MAX_PATH);
DWORD dwError = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == dwError)
{
MessageBoxW(NULL, L"Path to logfile is too long! Working without logging", (LPCWSTR)szTitle, MB_OK | MB_ICONWARNING);
return;
}
if (NULL == dwPathLength)
{
MessageBoxW(NULL, L"Can't get module filename! Working without logging", (LPCWSTR)szTitle, MB_OK | MB_ICONWARNING);
return;
}
std::filesystem::path log_path = lpszPath;
log_path.replace_extension(L".log");
std::filesystem::path bak_path = log_path;
bak_path.replace_extension(L".bak");
if (std::filesystem::exists(log_path)) std::filesystem::rename(log_path, bak_path);
#ifdef _DEBUG
log_path = L"d:\\test.log";
#endif
logfile.open(log_path);
if (logfile.is_open())
{
logfile << std::boolalpha;
diag_log("Start logging");
diag_log("Logfile: ", log_path);
diag_log("Logfile was successfully opened");
}
else
{
MessageBoxW(NULL, L"Can't open logfile! Working without logging", (LPCWSTR)szTitle, MB_OK | MB_ICONWARNING);
}
return;
}
void CloseLogFile()
{
if (logfile)
{
diag_log("End logging");
logfile.close();
}
}

59
wCenterWindow/Logger.h Normal file
View File

@@ -0,0 +1,59 @@
// wCenterWindow
// Logger.h
//
#pragma once
#include "framework.h"
extern std::ofstream logfile;
std::string GetTimeStamp();
template <typename T1>
void diag_log(T1 arg1)
{
logfile << GetTimeStamp() << arg1 << std::endl;
}
template <typename T1, typename T2>
void diag_log(T1 arg1, T2 arg2)
{
logfile << GetTimeStamp() << arg1 << arg2 << std::endl;
}
template <typename T1, typename T2, typename T3>
void diag_log(T1 arg1, T2 arg2, T3 arg3)
{
logfile << GetTimeStamp() << arg1 << arg2 << arg3 << std::endl;
}
template <typename T1, typename T2, typename T3, typename T4>
void diag_log(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
logfile << GetTimeStamp() << arg1 << arg2 << arg3 << arg4 << std::endl;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void diag_log(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5)
{
logfile << GetTimeStamp() << arg1 << arg2 << arg3 << arg4 << arg5 << std::endl;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
void diag_log(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
{
logfile << GetTimeStamp() << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << std::endl;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
void diag_log(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7)
{
logfile << GetTimeStamp() << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << std::endl;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
void diag_log(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
{
logfile << GetTimeStamp() << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << std::endl;
}
void OpenLogFile();
void CloseLogFile();

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

View File

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

48
wCenterWindow/resource.h Normal file
View File

@@ -0,0 +1,48 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by wCenterWindow.rc
//
#define IDS_CLASSNAME 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 104
#define IDI_TRAYICON 105
#define IDR_MENU 106
#define ID_POPUPMENU_ICON 107
#define ID_POPUPMENU_AREA 108
#define ID_POPUPMENU_ABOUT 110
#define ID_POPUPMENU_EXIT 111
#define IDS_ABOUT 112
#define IDS_ERR_MAIN 113
#define IDS_ERR_CLASS 114
#define IDS_ERR_WND 115
#define IDS_ERR_ICON 116
#define IDS_ERR_MENU 117
#define IDS_ERR_POPUP 118
#define IDS_ERR_HOOK 119
#define IDS_ERR_MAXMIN 120
#define IDS_RUNNING 121
#define IDR_MAINFRAME 128
#define IDD_MANUAL_EDITING 129
#define IDC_EDIT_X 1000
#define IDC_EDIT_Y 1001
#define IDC_EDIT_WIDTH 1002
#define IDC_EDIT_HEIGHT 1003
#define IDC_EDIT_TITLE 1004
#define IDC_EDIT_CLASS 1005
#define IDC_BUTTON_SET 1006
#define IDC_BUTTON_CLOSE 1007
#define IDC_ABOUTHELP 1008
#define IDC_DONATIONLINK 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 130
#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,6 @@
#pragma once
#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 <SDKDDKVer.h>

View File

@@ -1,247 +1,552 @@
// wCenterWindow.cpp : Определяет точку входа для приложения.
// wCenterWindow
// wCenterWindow.cpp
//
#include "framework.h"
#include "wCenterWindow.h"
#define MAX_LOADSTRING 80
#define WM_WCW WM_USER + 0x7F00
#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 BUF_LEN 1024
#define MAX_LOADSTRING 50
#define WM_WCW 0x8F00
// Прототипы функций
ATOM MyRegisterClass(HINSTANCE);
VOID ShowError(HINSTANCE, UINT);
// Global variables:
HINSTANCE hInst; // Instance
WCHAR szTitle[MAX_LOADSTRING]; // Window's title
WCHAR szClass[MAX_LOADSTRING]; // Window's class
WCHAR szAbout[MAX_LOADSTRING * 12]; // Description text
WCHAR szWinTitle[256];
WCHAR szWinClass[256];
WCHAR szWinCore[] = L"Windows.UI.Core.CoreWindow";
WCHAR szWorkerW[] = L"WorkerW";
HANDLE hHeap = NULL;
HHOOK hMouseHook = NULL, hKbdHook = NULL; // Hook's handles
HICON hIcon = NULL;
HMENU hMenu = NULL, hPopup = NULL;
HWND hWnd = NULL, hFgWnd = NULL, hTaskBar = NULL, hDesktop = NULL, hProgman = NULL;
bool bKPressed = FALSE, bMPressed = FALSE, bShowIcon = TRUE, bWorkArea = TRUE;
bool bLCTRL = FALSE, bLWIN = FALSE, bKEYV = FALSE;
RECT rcFW = { 0 };
NOTIFYICONDATAW nid = { 0 };
LPKBDLLHOOKSTRUCT pkhs = { 0 };
MENUITEMINFO mii = { 0 };
LPVOID szBuffer;
// {2D7B7F30-4B5F-4380-9807-57D7A2E37F6C}
static const GUID guid = { 0x2d7b7f30, 0x4b5f, 0x4380, { 0x98, 0x7, 0x57, 0xd7, 0xa2, 0xe3, 0x7f, 0x6c } };
// Forward declarations of functions included in this code module:
VOID HandlingTrayIcon();
VOID ShowError(UINT);
bool IsWindowApprooved(HWND);
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK KeyboardHookProc(int, WPARAM, LPARAM);
BOOL CreateTrayIcon();
LRESULT CALLBACK MouseHookProc(int, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
std::string ConvertWideToUtf8(const std::wstring&);
// Точка входа
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
VOID MoveWindowToMonitorCenter(HWND hwnd, BOOL bWorkArea, BOOL bResize)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
diag_log("Entering MoveWindowToMonitorCenter(), handle = 0x", hwnd);
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDS_CLASSNAME, szClass, MAX_LOADSTRING);
if (FindWindow(szClass, NULL))
RECT fgwrc = { 0 };
GetWindowRect(hwnd, &fgwrc);
LONG nWidth = fgwrc.right - fgwrc.left;
LONG nHeight = fgwrc.bottom - fgwrc.top;
diag_log("Moving window from x = ", fgwrc.left, ", y = ", fgwrc.top);
MONITORINFO mi = { 0 };
mi.cbSize = sizeof(MONITORINFO);
GetMonitorInfoW(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &mi);
RECT area = { 0 };
if (bWorkArea)
{
ShowError(hInstance, IDS_RUNNING);
area.bottom = mi.rcWork.bottom;
area.left = mi.rcWork.left;
area.right = mi.rcWork.right;
area.top = mi.rcWork.top;
}
else
{
area.bottom = mi.rcMonitor.bottom;
area.left = mi.rcMonitor.left;
area.right = mi.rcMonitor.right;
area.top = mi.rcMonitor.top;
}
int aw = area.right - area.left;
int ah = area.bottom - area.top;
if (nWidth > aw && bResize) nWidth = aw;
if (nHeight > ah && bResize) nHeight = ah;
if (area.left < 0) aw = -aw;
if (area.top < 0) ah = -ah;
int x = (aw - nWidth) / 2;
int y = (ah - nHeight) / 2;
SendMessageW(hwnd, WM_ENTERSIZEMOVE, NULL, NULL);
MoveWindow(hwnd, x, y, nWidth, nHeight, TRUE);
SendMessageW(hwnd, WM_EXITSIZEMOVE, NULL, NULL);
diag_log("Moving window to x = ", x, ", y = ", y);
diag_log("Quiting MoveWindowToMonitorCenter()");
}
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
hInst = hInstance;
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, _countof(szTitle));
LoadStringW(hInstance, IDS_CLASSNAME, szClass, _countof(szClass));
if (FindWindowW(szClass, NULL))
{
ShowError(IDS_RUNNING);
return FALSE;
}
OpenLogFile();
diag_log("Entering WinMain()");
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDI_TRAYICON));
wcex.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wcex.lpszClassName = szClass;
wcex.hIconSm = wcex.hIcon;
hIcon = wcex.hIcon;
if (!RegisterClassExW(&wcex))
{
ShowError(IDS_ERR_CLASS);
return FALSE;
}
MyRegisterClass(hInstance);
hWnd = CreateWindowExW(0, szClass, szTitle, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
ShowError(hInstance, IDS_ERR_WND);
ShowError(IDS_ERR_WND);
return FALSE;
}
if (showIcon)
int nArgs = 0;
LPWSTR* szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
std::string arg;
diag_log("Arguments: ", nArgs - 1);
for (int i = 1; i < nArgs; i++)
{
if (!CreateTrayIcon())
{
ShowError(hInstance, IDS_ERR_ICON);
SendMessage(hWnd, WM_CLOSE, NULL, NULL);
}
arg = ConvertWideToUtf8(szArglist[i]);
diag_log("Argument #", i, ": ", arg);
}
hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU));
if (!hMenu)
{
ShowError(hInstance, IDS_ERR_MENU);
SendMessage(hWnd, WM_CLOSE, NULL, NULL);
}
(nArgs >= 2 && 0 == lstrcmpiW(szArglist[1], L"/hide")) ? bShowIcon = FALSE : bShowIcon = TRUE;
LocalFree(szArglist);
HandlingTrayIcon();
hPopup = GetSubMenu(hMenu, 0);
if (!hPopup)
{
ShowError(hInstance, IDS_ERR_POPUP);
SendMessage(hWnd, WM_CLOSE, NULL, NULL);
}
hHeap = GetProcessHeap();
szBuffer = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, BUF_LEN);
KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, hInstance, NULL);
if (!KeyboardHook)
{
ShowError(hInstance, IDS_ERR_HOOK);
SendMessage(hWnd, WM_CLOSE, NULL, NULL);
}
LoadStringW(hInstance, IDS_HELPTEXT, szHelp, MAX_LOADSTRING);
RECT dtrc = { 0 };
SystemParametersInfo(SPI_GETWORKAREA, NULL, &dtrc, FALSE);
dtCenterX = dtrc.right / 2, dtCenterY = dtrc.bottom / 2;
hTaskBar = FindWindowW(L"Shell_TrayWnd", NULL);
hProgman = FindWindowW(L"Progman", NULL);
hDesktop = GetDesktopWindow();
MSG msg;
BOOL bRet;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
while ((bRet = GetMessageW(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
ShowError(hInstance, IDS_ERR_MAIN);
ShowError(IDS_ERR_MAIN);
return -1;
}
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);
if (hMouseHook) UnhookWindowsHookEx(hMouseHook);
if (hKbdHook) UnhookWindowsHookEx(hKbdHook);
if (hMenu) DestroyMenu(hMenu);
Shell_NotifyIconW(NIM_DELETE, &nid);
diag_log("Quiting WinMain(), msg.wParam = ", (int)msg.wParam);
CloseLogFile();
HeapFree(hHeap, NULL, szBuffer);
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_WCW:
if (lParam == WM_RBUTTONDOWN && wParam == IDI_TRAYICON)
case WM_CREATE:
{
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)
diag_log("Recived WM_CREATE message");
hMenu = LoadMenuW(hInst, MAKEINTRESOURCE(IDR_MENU));
if (!hMenu)
{
pressed = TRUE;
if (MessageBox(hWnd, szHelp, szTitle, MB_OK | MB_TOPMOST) == IDOK) pressed = FALSE;
diag_log("Loading context menu failed!");
ShowError(IDS_ERR_MENU);
PostMessageW(hWnd, WM_CLOSE, NULL, NULL);
}
if (idMenu == ID_POPUPMENU_EXIT) SendMessage(hWnd, WM_CLOSE, NULL, NULL);
diag_log("Context menu successfully loaded");
hPopup = GetSubMenu(hMenu, 0);
if (!hPopup)
{
diag_log("Creating popup menu failed!");
ShowError(IDS_ERR_POPUP);
PostMessageW(hWnd, WM_CLOSE, NULL, NULL);
}
diag_log("Popup menu successfully created");
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.uCallbackMessage = WM_WCW;
nid.hIcon = hIcon;
nid.uID = IDI_TRAYICON;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.dwInfoFlags = NIIF_NONE;
nid.dwState = NIS_HIDDEN;
nid.dwStateMask = NIS_HIDDEN;
StringCchCopyW(nid.szTip, _countof(nid.szTip), szTitle);
#ifndef _DEBUG
hMouseHook = SetWindowsHookExW(WH_MOUSE_LL, MouseHookProc, hInst, NULL);
if (!hMouseHook)
{
diag_log("Creating mouse hook failed!");
ShowError(IDS_ERR_HOOK);
PostMessageW(hWnd, WM_CLOSE, NULL, NULL);
}
diag_log("Mouse hook was successfully set");
#endif // !_DEBUG
hKbdHook = SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardHookProc, hInst, NULL);
if (!hKbdHook)
{
diag_log("Creating keyboard hook failed!");
ShowError(IDS_ERR_HOOK);
PostMessageW(hWnd, WM_CLOSE, NULL, NULL);
}
diag_log("Keyboard hook was successfully set");
LoadStringW(hInst, IDS_ABOUT, szAbout, _countof(szAbout));
break;
}
break;
case WM_DESTROY:
if (KeyboardHook) UnhookWindowsHookEx(KeyboardHook);
if (hMenu) DestroyMenu(hMenu);
Shell_NotifyIcon(NIM_DELETE, &nid);
PostQuitMessage(0);
break;
case WM_WCW:
{
if (IDI_TRAYICON == wParam && (WM_RBUTTONDOWN == lParam || WM_LBUTTONDOWN == lParam))
{
diag_log("Entering menu handler");
SetForegroundWindow(hWnd);
POINT pt;
GetCursorPos(&pt);
int idMenu = TrackPopupMenu(hPopup, TPM_RETURNCMD, pt.x, pt.y, 0, hWnd, NULL);
if (ID_POPUPMENU_ICON == idMenu)
{
diag_log("Pressed 'Hide icon' menuitem");
bShowIcon = FALSE;
HandlingTrayIcon();
}
if (ID_POPUPMENU_AREA == idMenu)
{
diag_log("Pressed 'Use workarea' menuitem");
bWorkArea = !bWorkArea;
bWorkArea ? mii.fState = MFS_CHECKED : mii.fState = MFS_UNCHECKED;
SetMenuItemInfoW(hPopup, ID_POPUPMENU_AREA, FALSE, &mii);
diag_log("Changed 'Use workarea' option to ", bWorkArea);
}
if (ID_POPUPMENU_ABOUT == idMenu && !bKPressed)
{
diag_log("Pressed 'About' menuitem");
bKPressed = TRUE;
DialogBoxW(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, (DLGPROC)About);
bKPressed = FALSE;
}
if (ID_POPUPMENU_EXIT == idMenu)
{
diag_log("Pressed 'Exit' menuitem");
PostMessageW(hWnd, WM_CLOSE, NULL, NULL);
}
diag_log("Quiting menu handler");
}
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_QUERYENDSESSION:
{
diag_log("Recieved WM_QUERYENDSESSION message, lParam = ", lParam);
CloseLogFile();
return TRUE;
break;
}
case WM_DESTROY:
{
diag_log("Recived WM_DESTROY message");
PostQuitMessage(0);
break;
}
default:
return DefWindowProcW(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (WM_MBUTTONUP == wParam) bMPressed = FALSE;
if (WM_MBUTTONDOWN == wParam && bLCTRL && bLWIN && !bMPressed)
{
diag_log("Pressed LCTRL + LWIN + MMB");
bMPressed = TRUE;
hFgWnd = GetForegroundWindow();
if (IsWindowApprooved(hFgWnd)) MoveWindowToMonitorCenter(hFgWnd, bWorkArea, FALSE);
else hFgWnd = NULL;
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
pkhs = (KBDLLHOOKSTRUCT*)lParam;
if (wParam == WM_KEYUP)
if (WM_KEYUP == wParam)
{
if (pkhs->vkCode == VK_LCONTROL) bLCTRL = FALSE;
if (pkhs->vkCode == VK_LWIN) bLWIN = FALSE;
pressed = FALSE;
if (VK_LCONTROL == pkhs->vkCode) bLCTRL = FALSE;
if (VK_LWIN == pkhs->vkCode) bLWIN = FALSE;
bKPressed = FALSE;
}
if (wParam == WM_KEYDOWN)
if (WM_KEYDOWN == wParam)
{
if (pkhs->vkCode == VK_LCONTROL) bLCTRL = TRUE;
if (pkhs->vkCode == VK_LWIN) bLWIN = TRUE;
if (VK_LCONTROL == pkhs->vkCode) bLCTRL = TRUE;
if (VK_LWIN == pkhs->vkCode) bLWIN = TRUE;
if (bLCTRL && bLWIN && pkhs->vkCode == 0x49 && !pressed) // 'I' key
if (KEY_I == pkhs->vkCode && bLCTRL && bLWIN && !bKPressed) // 'I' key
{
pressed = TRUE;
showIcon = !showIcon;
if (showIcon)
{
if (!CreateTrayIcon())
{
ShowError(GetModuleHandle(NULL), IDS_ERR_ICON);
showIcon = FALSE;
}
}
else
{
Shell_NotifyIcon(NIM_DELETE, &nid);
}
diag_log("Pressed LCTRL + LWIN + I");
bKPressed = TRUE;
bShowIcon = !bShowIcon;
HandlingTrayIcon();
return TRUE;
}
if (bLCTRL && bLWIN && pkhs->vkCode == 0x43 && !pressed) // 'C' key
if (KEY_C == pkhs->vkCode && bLCTRL && bLWIN && !bKPressed && !bKEYV) // 'C' key
{
pressed = TRUE;
HWND fgWindow = GetForegroundWindow();
if (fgWindow)
diag_log("Pressed LCTRL + LWIN + C");
bKPressed = TRUE;
hFgWnd = GetForegroundWindow();
if (IsWindowApprooved(hFgWnd)) MoveWindowToMonitorCenter(hFgWnd, bWorkArea, FALSE);
else hFgWnd = NULL;
return TRUE;
}
if (KEY_V == pkhs->vkCode && bLCTRL && bLWIN && !bKPressed && !bKEYV) // 'V' key
{
diag_log("Pressed LCTRL + LWIN + V");
bKPressed = TRUE; bKEYV = TRUE;
hFgWnd = GetForegroundWindow();
if (IsWindowApprooved(hFgWnd))
{
HWND parentWindow = fgWindow;
while (TRUE)
{
parentWindow = GetParent(fgWindow);
if (parentWindow) fgWindow = parentWindow;
else break;
}
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);
}
diag_log("Opening 'Manual editing' dialog");
DialogBoxW(hInst, MAKEINTRESOURCE(IDD_MANUAL_EDITING), hFgWnd, (DLGPROC)DlgProc);
SetForegroundWindow(hFgWnd);
}
else hFgWnd = NULL;
bKEYV = FALSE;
return TRUE;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
BOOL CreateTrayIcon()
BOOL CALLBACK DlgProc(HWND hDlg, UINT dlgmsg, WPARAM wParam, LPARAM lParam)
{
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);
int x, y, w, h;
switch (dlgmsg)
{
case WM_INITDIALOG:
{
diag_log("Initializing 'Manual editing' dialog");
SetWindowTextW(hDlg, szTitle);
GetWindowTextW(hFgWnd, szWinTitle, _countof(szWinTitle));
GetClassNameW(hFgWnd, szWinClass, _countof(szWinClass));
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, szWinTitle);
SetDlgItemTextW(hDlg, IDC_EDIT_CLASS, szWinClass);
UpdateWindow(hDlg);
break;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BUTTON_SET:
{
diag_log("Pressed 'Set' button");
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);
diag_log("Window with handle 0x", hFgWnd, " was moved to x = ", x, ", y = ", y);
return TRUE;
break;
}
case IDCANCEL:
case IDC_BUTTON_CLOSE:
{
diag_log("Closing 'Manual editing' dialog");
EndDialog(hDlg, LOWORD(wParam));
break;
}
}
}
return FALSE;
}
VOID ShowError(HINSTANCE hInstance, UINT uID)
bool IsWindowApprooved(HWND hFW)
{
WCHAR szErrorText[MAX_LOADSTRING]; // Текст ошибки
LoadStringW(hInstance, uID, szErrorText, MAX_LOADSTRING);
MessageBox(hWnd, szErrorText, szTitle, MB_OK | MB_ICONERROR);
diag_log("Entering IsWindowApprooved(), handle = 0x", hFW);
bool bApprooved = FALSE;
if (hFW)
{
GetClassNameW(hFW, szWinClass, _countof(szWinClass));
if (GetWindowTextW(hFW, (LPWSTR)szBuffer, BUF_LEN - sizeof(WCHAR))) diag_log("Title: '", ConvertWideToUtf8((LPWSTR)szBuffer), "'");
if (IsIconic(hFW)) diag_log("Window is iconic");
if (IsZoomed(hFW)) diag_log("Window is maximized");
if ((wcscmp(szWinClass, szWinCore) != 0) &&
(wcscmp(szWinClass, szWorkerW) != 0) &&
(hFW != hDesktop && hFW != hTaskBar && hFW != hProgman))
{
if (!IsIconic(hFW) && !IsZoomed(hFW))
{
diag_log("Window is approved");
bApprooved = TRUE;
}
else ShowError(IDS_ERR_MAXMIN);
}
else diag_log("The window belongs to the Windows environment");
}
if (!bApprooved) diag_log("Window is not approved!");
diag_log("Quiting IsWindowApprooved()");
return bApprooved;
}
VOID HandlingTrayIcon()
{
diag_log("Entering HandlingTrayIcon(), bShowIcon = ", bShowIcon);
if (bShowIcon)
{
bool bResult1 = Shell_NotifyIconW(NIM_ADD, &nid);
diag_log("Shell_NotifyIconW(NIM_ADD): ", bResult1);
bool bResult2 = Shell_NotifyIconW(NIM_SETVERSION, &nid);
diag_log("Shell_NotifyIconW(NIM_SETVERSION): ", bResult2);
if (!bResult1 || !bResult2)
{
diag_log("Error creating trayicon!");
ShowError(IDS_ERR_ICON);
bShowIcon = FALSE;
}
}
else
{
Shell_NotifyIconW(NIM_DELETE, &nid);
}
diag_log("Quiting HandlingTrayIcon()");
}
VOID ShowError(UINT uID)
{
WCHAR szErrorText[MAX_LOADSTRING]; // Error's text
LoadStringW(hInst, uID, szErrorText, _countof(szErrorText));
MessageBoxW(NULL, szErrorText, szTitle, MB_OK | MB_ICONERROR | MB_TOPMOST);
}
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
INITCOMMONCONTROLSEX icex = { 0 };
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_LINK_CLASS;
InitCommonControlsEx(&icex);
switch (message)
{
case WM_INITDIALOG:
{
diag_log("Initializing 'About' dialog");
SetDlgItemTextW(hDlg, IDC_ABOUTHELP, szAbout);
return (INT_PTR)TRUE;
break;
}
case WM_NOTIFY:
{
LPNMHDR pNMHdr = (LPNMHDR)lParam;
if ((NM_CLICK == pNMHdr->code || NM_RETURN == pNMHdr->code) && IDC_DONATIONLINK == pNMHdr->idFrom)
{
PNMLINK pNMLink = (PNMLINK)pNMHdr;
LITEM item = pNMLink->item;
ShellExecuteW(NULL, L"open", item.szUrl, NULL, NULL, SW_SHOW);
diag_log("Pressed donation link");
return (INT_PTR)TRUE;
}
break;
}
case WM_COMMAND:
{
if (IDOK == LOWORD(wParam) || IDCANCEL == LOWORD(wParam))
{
EndDialog(hDlg, LOWORD(wParam));
diag_log("Closing 'About' dialog");
return (INT_PTR)TRUE;
}
break;
}
}
return (INT_PTR)FALSE;
}
std::string ConvertWideToUtf8(const std::wstring& wstr)
{
int count = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
std::string str(count, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL);
return str;
}

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,4 @@
// wCenterWindow
// wCenterWindow.h
#pragma once
#include "resource.h"

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>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</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>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@@ -73,100 +74,132 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<CopyCppRuntimeToOutputDir>false</CopyCppRuntimeToOutputDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</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>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
<ManifestFromManagedAssembly>
</ManifestFromManagedAssembly>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)Update_version.bat"</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>
<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;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)Update_version.bat"</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>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)Update_version.bat"</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>
<AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<Manifest>
<AdditionalManifestFiles>%(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PreBuildEvent>
<Command>"$(SolutionDir)Update_version.bat"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="framework.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="Logger.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="wCenterWindow.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Logger.cpp" />
<ClCompile Include="wCenterWindow.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="wCenterWindow.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="small.ico" />
<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,63 @@
<?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="Logger.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="wCenterWindow.cpp">
<Filter>Исходные файлы</Filter>
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Logger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="wCenterWindow.rc">
<Filter>Файлы ресурсов</Filter>
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Image Include="small.ico">
<Filter>Resource Files</Filter>
</Image>
<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,7 @@
<?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>/test1 /test2</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>