Skip to content

Commit 2cd1683

Browse files
committed
Improve code quality
1 parent 1ca17aa commit 2cd1683

File tree

12 files changed

+434
-378
lines changed

12 files changed

+434
-378
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System.Collections.Generic;
2+
using System;
3+
using System.Runtime.InteropServices;
4+
using System.Windows;
5+
using Windows.Win32;
6+
using Windows.Win32.Foundation;
7+
using Windows.Win32.Graphics.Gdi;
8+
using Windows.Win32.UI.WindowsAndMessaging;
9+
10+
namespace Flow.Launcher.Infrastructure;
11+
12+
/// <summary>
13+
/// Contains full information about a display monitor.
14+
/// Codes are edited from: <see href="https://github.com/Jack251970/DesktopWidgets3">.
15+
/// </summary>
16+
internal class MonitorInfo
17+
{
18+
/// <summary>
19+
/// Gets the display monitors (including invisible pseudo-monitors associated with the mirroring drivers).
20+
/// </summary>
21+
/// <returns>A list of display monitors</returns>
22+
public static unsafe IList<MonitorInfo> GetDisplayMonitors()
23+
{
24+
var monitorCount = PInvoke.GetSystemMetrics(SYSTEM_METRICS_INDEX.SM_CMONITORS);
25+
var list = new List<MonitorInfo>(monitorCount);
26+
var callback = new MONITORENUMPROC((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
27+
{
28+
list.Add(new MonitorInfo(monitor, rect));
29+
return true;
30+
});
31+
var dwData = new LPARAM();
32+
var hdc = new HDC();
33+
bool ok = PInvoke.EnumDisplayMonitors(hdc, (RECT?)null, callback, dwData);
34+
if (!ok)
35+
{
36+
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
37+
}
38+
return list;
39+
}
40+
41+
/// <summary>
42+
/// Gets the display monitor that is nearest to a given window.
43+
/// </summary>
44+
/// <param name="hwnd">Window handle</param>
45+
/// <returns>The display monitor that is nearest to a given window, or null if no monitor is found.</returns>
46+
public static unsafe MonitorInfo GetNearestDisplayMonitor(HWND hwnd)
47+
{
48+
var nearestMonitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
49+
MonitorInfo nearestMonitorInfo = null;
50+
var callback = new MONITORENUMPROC((HMONITOR monitor, HDC deviceContext, RECT* rect, LPARAM data) =>
51+
{
52+
if (monitor == nearestMonitor)
53+
{
54+
nearestMonitorInfo = new MonitorInfo(monitor, rect);
55+
return false;
56+
}
57+
return true;
58+
});
59+
var dwData = new LPARAM();
60+
var hdc = new HDC();
61+
bool ok = PInvoke.EnumDisplayMonitors(hdc, (RECT?)null, callback, dwData);
62+
if (!ok)
63+
{
64+
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
65+
}
66+
return nearestMonitorInfo;
67+
}
68+
69+
private readonly HMONITOR _monitor;
70+
71+
internal unsafe MonitorInfo(HMONITOR monitor, RECT* rect)
72+
{
73+
RectMonitor =
74+
new Rect(new Point(rect->left, rect->top),
75+
new Point(rect->right, rect->bottom));
76+
_monitor = monitor;
77+
var info = new MONITORINFOEXW() { monitorInfo = new MONITORINFO() { cbSize = (uint)sizeof(MONITORINFOEXW) } };
78+
GetMonitorInfo(monitor, ref info);
79+
RectWork =
80+
new Rect(new Point(info.monitorInfo.rcWork.left, info.monitorInfo.rcWork.top),
81+
new Point(info.monitorInfo.rcWork.right, info.monitorInfo.rcWork.bottom));
82+
Name = new string(info.szDevice.AsSpan()).Replace("\0", "").Trim();
83+
}
84+
85+
/// <summary>
86+
/// Gets the name of the display.
87+
/// </summary>
88+
public string Name { get; }
89+
90+
/// <summary>
91+
/// Gets the display monitor rectangle, expressed in virtual-screen coordinates.
92+
/// </summary>
93+
/// <remarks>
94+
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
95+
/// </remarks>
96+
public Rect RectMonitor { get; }
97+
98+
/// <summary>
99+
/// Gets the work area rectangle of the display monitor, expressed in virtual-screen coordinates.
100+
/// </summary>
101+
/// <remarks>
102+
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
103+
/// </remarks>
104+
public Rect RectWork { get; }
105+
106+
/// <summary>
107+
/// Gets if the monitor is the the primary display monitor.
108+
/// </summary>
109+
public bool IsPrimary => _monitor == PInvoke.MonitorFromWindow(new(IntPtr.Zero), MONITOR_FROM_FLAGS.MONITOR_DEFAULTTOPRIMARY);
110+
111+
/// <inheritdoc />
112+
public override string ToString() => $"{Name} {RectMonitor.Width}x{RectMonitor.Height}";
113+
114+
private static unsafe bool GetMonitorInfo(HMONITOR hMonitor, ref MONITORINFOEXW lpmi)
115+
{
116+
fixed (MONITORINFOEXW* lpmiLocal = &lpmi)
117+
{
118+
var lpmiBase = (MONITORINFO*)lpmiLocal;
119+
var __result = PInvoke.GetMonitorInfo(hMonitor, lpmiBase);
120+
return __result;
121+
}
122+
}
123+
}

Flow.Launcher.Infrastructure/NativeMethods.txt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,31 @@ EnumWindows
2020

2121
DwmSetWindowAttribute
2222
DWM_SYSTEMBACKDROP_TYPE
23-
DWM_WINDOW_CORNER_PREFERENCE
23+
DWM_WINDOW_CORNER_PREFERENCE
24+
25+
MAX_PATH
26+
SystemParametersInfo
27+
28+
SetForegroundWindow
29+
30+
GetWindowLong
31+
SetWindowLong
32+
GetForegroundWindow
33+
GetDesktopWindow
34+
GetShellWindow
35+
GetWindowRect
36+
GetClassName
37+
FindWindowEx
38+
WINDOW_STYLE
39+
40+
SetLastError
41+
WINDOW_EX_STYLE
42+
43+
GetSystemMetrics
44+
EnumDisplayMonitors
45+
MonitorFromWindow
46+
GetMonitorInfo
47+
MONITORINFOEXW
48+
49+
WM_ENTERSIZEMOVE
50+
WM_EXITSIZEMOVE

0 commit comments

Comments
 (0)