This repository was archived by the owner on Sep 19, 2026. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathWindowCenterer.cs
More file actions
85 lines (70 loc) · 3.21 KB
/
Copy pathWindowCenterer.cs
File metadata and controls
85 lines (70 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// WindowCenter — 快捷键居中 Windows 窗口
// Copyright (C) 2026 WindowCenter contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
using System.Runtime.InteropServices;
using static WindowCenter.NativeMethods;
namespace WindowCenter;
/// <summary>核心:将当前前台窗口居中到所在显示器</summary>
internal static class WindowCenterer
{
/// <summary>居中当前活动窗口。成功返回 true。</summary>
public static bool CenterActiveWindow()
{
nint hWnd = GetForegroundWindow();
if (hWnd == nint.Zero) return false;
// 跳过控制台窗口自身
if (hWnd == GetConsoleWindow()) return false;
// ── 1. 处理窗口状态 ──────────────────────
long style = GetWindowLongPtrW(hWnd, GWL_STYLE);
bool isMaximized = (style & WS_MAXIMIZE) != 0;
bool isMinimized = (style & WS_MINIMIZE) != 0;
// 最小化 → 先还原
if (isMinimized)
{
ShowWindow(hWnd, SW_RESTORE);
// 给窗口一点时间恢复,否则 GetWindowRect 可能拿到旧尺寸
Thread.Sleep(50);
}
// 最大化 → 先还原
if (isMaximized)
{
ShowWindow(hWnd, SW_RESTORE);
Thread.Sleep(50);
}
// ── 2. 获取窗口尺寸 ──────────────────────
if (!GetWindowRect(hWnd, out RECT windowRect))
return false;
int windowWidth = windowRect.Width;
int windowHeight = windowRect.Height;
// ── 3. 获取所在显示器工作区 ──────────────
nint hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
var monitorInfo = new MONITORINFO { cbSize = Marshal.SizeOf<MONITORINFO>() };
if (!GetMonitorInfoW(hMonitor, ref monitorInfo))
return false;
RECT work = monitorInfo.rcWork;
// ── 4. 计算居中坐标 ──────────────────────
int newX = work.Left + (work.Width - windowWidth) / 2;
int newY = work.Top + (work.Height - windowHeight) / 2;
// ── 5. 移动窗口(保持宽高不变,不改变 Z 序)─
bool result = SetWindowPos(hWnd, nint.Zero,
newX, newY, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
if (result)
Logger.Info($"窗口居中: {windowWidth}x{windowHeight} → ({newX}, {newY})");
else
Logger.Warn("SetWindowPos 失败");
return result;
}
}