C# 실행중인 프로세스와 윈도우 사이즈 조사
C# 2021. 11. 26. 16:34 |반응형
실행중인 모든 프로세스와 현재 포커스를 갖고 있는 프로세스를 조사하고 각 프로세스의 윈도우 사이즈를 구해 보자.
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string className, string windowName);
// 이 예제에서는 쓰이지 않았지만 Findwindow()는 아래와 같이 사용하면 된다.
// IntPtr hwnd = FindWindow(className, windowName);
// windowName = proc.ProcessName;
// className = proc.MainWindowTitle;
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern int GetWindowRect(IntPtr hWnd, out Rectangle rect);
[DllImport("dwmapi.dll")]
private static extern int DwmGetWindowAttribute(IntPtr hWnd, int dwAttribute, out Rectangle pvAttribute, int cbAttribute);
public Form1()
{
InitializeComponent();
timer1.Interval = 5000; // 5초마다 갱신
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Process[] processes = Process.GetProcesses();
Rectangle rect;
// GetWindowRect(), DwmGetWindowAttribute()에 의해 rect에는 아래와 같은 값이 들어간다.
// rect.X = 좌상단 X 좌표
// rect.Y = 좌상단 T 좌표
// rect.Width = 우하단 X 좌표 (너비가 아니다)
// rect.Height = 우하단 Y 좌표 (높이가 아니다)
int rectangleSize = Marshal.SizeOf(typeof(Rectangle));
int index; // Process.GetProcesses()로 조사된 모든 프로세스 중 몇 번째 인지 나타낼 인덱스.
int row = 0; // 내용 표시 Y 위치
string str;
foreach (Process p in processes)
{
// A process has a main window associated with it only if the process has a graphical interface. If the associated process
// does not have a main window, the MainWindowHandle value is zero. The value is also zero for processes that have been hidden,
// that is, processes that are not visible in the taskbar. This can be the case for processes that appear as icons in the
// notification area, at the far right of the taskbar.
// 테스크 바에 표시되는(보이는) 프로세스만 조사. 윈도우 핸들이 0(IntPtr.Zero)이 아닌 윈도우인데 그렇다고 다 보이는 건 아니다.
if (p.MainWindowHandle != IntPtr.Zero)
{
index = Array.IndexOf(processes, p); // 비효율적인 배열의 인덱스 가져오기. foreach()말고 for(;;)를 쓰는게 낫다.
DwmGetWindowAttribute(p.MainWindowHandle, 9, out rect, rectangleSize);
// 9 = DWMWA_EXTENDED_FRAME_BOUNDS
str = string.Format("[{0}] {1}: ({2}, {3}, {4}, {5})", index, p.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
row += 15;
}
}
// 포커스를 갖고 있는 윈도우(Foreground window) 조사
uint foregroundProcessID = 0;
IntPtr foregroundHWnd = GetForegroundWindow(); // Get foreground window handle
uint threadID = GetWindowThreadProcessId(foregroundHWnd, out foregroundProcessID); // Get PID from window handle
Process foregroundProcess = Process.GetProcessById(Convert.ToInt32(foregroundProcessID)); // Get it as a C# obj.
// 윈도우 사이즈 조사
DwmGetWindowAttribute(foregroundHWnd, 9, out rect, rectangleSize);
// 9 = DWMWA_EXTENDED_FRAME_BOUNDS
str = string.Format("[Foreground] {0}: ({1}, {2}, {3}, {4})", foregroundProcess.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
row += 30;
// Windows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing.
// The borders might look like this: 7, 0, 7, 7(left, top, right, bottom)
// 윈도우 사이즈 조사 시 예전과 같이 GetWindowRect()를 사용하면 보통 7픽셀의 resizing을 위한 테두리가 포함된다.
e.Graphics.DrawString("[Foreground window with invisible border]", Font, Brushes.Red, 0, row);
row += 15;
GetWindowRect(foregroundHWnd, out rect);
str = string.Format("[Foreground] {0}: ({1}, {2}, {3}, {4})", foregroundProcess.ProcessName, rect.X, rect.Y, rect.Width, rect.Height);
e.Graphics.DrawString(str, Font, Brushes.Black, 0, row);
}
private void timer1_Tick(object sender, EventArgs e)
{
Invalidate();
}
}
}
|
소스를 입력하고 실행한다.
GetWindowRect()로 윈도우 사이즈를 구하면 resizing을 위한 보이지 않는 테두리가 포함 되므로 눈에 보이는 정확한 사이즈는 DwmGetWindowAttribute()로 구하자.
반응형
'C#' 카테고리의 다른 글
C# Icon Change - 아이콘 바꾸기 (0) | 2021.11.27 |
---|---|
C# Desktop Image Display Program - 바탕화면 이미지 출력 프로그램 (0) | 2021.11.27 |
C# Form Shortcut - 폼에 단축키 지정하기 (0) | 2021.11.25 |
C# Image, Bitmap Resolution - 이미지, 비트맵 파일 해상도 (0) | 2021.11.25 |
C# Desktop Moving Image Display - 바탕화면에 이미지 출력하고 움직이기 (0) | 2021.11.23 |