C# 控制 Windows 中程式視窗大小與位置

Introduction

通常程式預設起始位置為視窗正中間,但有時因為手殘動到導致視窗歪了、不在正中間了,身為強迫症患者就會越看越賭爛。因此本篇將記錄一下,利用 C# 來控制 Windows 中其他應用程式的視窗大小與位置。

Supports

Windows 7sp1/8/8.1/10 with .NET Framework 4.6.1 (or higher)

Code

以下程式將示範透過應用程式標題名稱取得該視窗,並設定視窗位置為左右垂直置中。

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
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ConsoleApp1
{
class Program
{
// Define the FindWindow API function.
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

// Define the SetWindowPos API function.
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);

// Define the SetWindowPosFlags enumeration.
[Flags()]
private enum SetWindowPosFlags : uint
{
SynchronousWindowPosition = 0x4000,
DeferErase = 0x2000,
DrawFrame = 0x0020,
FrameChanged = 0x0020,
HideWindow = 0x0080,
DoNotActivate = 0x0010,
DoNotCopyBits = 0x0100,
IgnoreMove = 0x0002,
DoNotChangeOwnerZOrder = 0x0200,
DoNotRedraw = 0x0008,
DoNotReposition = 0x0200,
DoNotSendChangingEvent = 0x0400,
IgnoreResize = 0x0001,
IgnoreZOrder = 0x0004,
ShowWindow = 0x0040,
}

static void Main(string[] args)
{
// Get the target window's handle by caption.
IntPtr target_hwnd = FindWindowByCaption(IntPtr.Zero, "Visual Studio");

// If got the window.
if (target_hwnd != IntPtr.Zero)
{
int width = "<your window's width>";
int height = "<your window's height>";
int x = (Screen.PrimaryScreen.WorkingArea.Width - width) / 2;
int y = (Screen.PrimaryScreen.WorkingArea.Height - height) / 2;
SetWindowPos(target_hwnd, IntPtr.Zero, x, y, width, height, 0);
}
}
}
}

若不知道或不確定該視窗標題,可透過以下程式來列表出所有視窗標題來取得:

1
2
3
foreach (var process in System.Diagnostics.Process.GetProcesses())
if (!string.IsNullOrEmpty(process.MainWindowTitle))
Console.WriteLine($"Process: {process.ProcessName}\tID: {process.Id}\tWindow title: {process.MainWindowTitle}");

References