-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWindowTracker.cs
More file actions
136 lines (108 loc) · 4.96 KB
/
Copy pathWindowTracker.cs
File metadata and controls
136 lines (108 loc) · 4.96 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System.Runtime.InteropServices;
using System.Text;
namespace SpatialAudio
{
struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public override string ToString()
{
return $"[L: {Left}, T: {Top}, R: {Right}, B: {Bottom}]";
}
}
struct MONITORINFO
{
public uint cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
}
internal static class WindowTracker
{
private static RECT _virtualDesktop;
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
public delegate bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdc, ref RECT lprcMonitor, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumWindows(EnumWindowsProc callback, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
[DllImport("user32.dll")]
static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport ("user32.dll", CharSet= CharSet.Unicode)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxCount);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint pid);
[DllImport("user32.dll")]
static extern bool SetProcessDpiAwarenessContext(IntPtr value);
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProc lpfnEnum, IntPtr dwData);
[DllImport("user32.dll")]
static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
public static void EnablePerMonitorDpiAwareness()
{
SetProcessDpiAwarenessContext(-4);
}
private static bool WindowCallback(IntPtr hWnd, IntPtr lParam)
{
if (!IsWindowVisible(hWnd)) return true;
GetWindowRect(hWnd, out RECT rect);
StringBuilder title = new StringBuilder(256);
int chars = GetWindowText(hWnd, title, 256);
if (chars == 0) {
Console.WriteLine("(no title)");
}
GetWindowThreadProcessId(hWnd, out uint pid);
Console.WriteLine($"hwnd: {hWnd}, pid: {pid}, title: {title}, {rect.Left}, {rect.Top}, {rect.Right}, {rect.Bottom}");
return true;
}
public static void ListWindows()
{
EnumWindows(WindowCallback, IntPtr.Zero);
}
private static bool MonitorCallback(IntPtr hMonitor, IntPtr hdc, ref RECT lprcMonitor, IntPtr lParam)
{
MONITORINFO monitor = new MONITORINFO();
monitor.cbSize = (uint)Marshal.SizeOf<MONITORINFO>();
if (GetMonitorInfo(hMonitor, ref monitor))
{
_virtualDesktop.Left = Math.Min(_virtualDesktop.Left, monitor.rcMonitor.Left);
_virtualDesktop.Top = Math.Min(_virtualDesktop.Top, monitor.rcMonitor.Top);
_virtualDesktop.Right = Math.Max(_virtualDesktop.Right, monitor.rcMonitor.Right);
_virtualDesktop.Bottom = Math.Max(_virtualDesktop.Bottom, monitor.rcMonitor.Bottom);
}
return true;
}
public static void ListMonitors()
{
_virtualDesktop = new RECT { Left = int.MaxValue, Top = int.MaxValue, Right = int.MinValue, Bottom = int.MinValue };
EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorCallback, IntPtr.Zero);
}
public static (float azimuth, float distance, string title) GetFocusedInfo()
{
IntPtr fWindow = GetForegroundWindow();
if (IsWindowVisible(fWindow))
{
GetWindowRect(fWindow, out RECT rect);
StringBuilder title = new StringBuilder(256);
int chars = GetWindowText(fWindow, title, 256);
string t = chars == 0 ? "(no title)" : title.ToString();
float cx = rect.Left + MathF.Abs(rect.Right - rect.Left) / 2;
float cy = rect.Top + MathF.Abs(rect.Bottom - rect.Top) / 2;
float lx = _virtualDesktop.Left + MathF.Abs(_virtualDesktop.Right - _virtualDesktop.Left) / 2;
float ly = _virtualDesktop.Top + MathF.Abs(_virtualDesktop.Bottom - _virtualDesktop.Top) / 2;
float dx = cx - lx;
float dy = cy - ly;
float halfWidth = (_virtualDesktop.Right - _virtualDesktop.Left) / 2f;
float eyeDistance = halfWidth / MathF.Tan(70f * MathF.PI / 180f);
float azimuth = MathF.Atan2(dx, eyeDistance) * 180.0f / MathF.PI;
float distance = MathF.Sqrt(dx * dx + dy * dy);
return (azimuth, distance, title.ToString());
}else { return (0, 0, "Not visible"); }
}
}
}