1
- using System . Collections . Generic ;
2
- using System ;
1
+ using System ;
2
+ using System . Collections . Generic ;
3
3
using System . Runtime . InteropServices ;
4
4
using System . Windows ;
5
5
using Windows . Win32 ;
@@ -11,9 +11,12 @@ namespace Flow.Launcher.Infrastructure;
11
11
12
12
/// <summary>
13
13
/// Contains full information about a display monitor.
14
- /// Codes are edited from: <see href=" https://github.com/Jack251970/DesktopWidgets3"> .
14
+ /// Inspired from: https://github.com/Jack251970/DesktopWidgets3.
15
15
/// </summary>
16
- internal class MonitorInfo
16
+ /// <remarks>
17
+ /// Use this class to replace the System.Windows.Forms.Screen class which can cause possible System.PlatformNotSupportedException.
18
+ /// </remarks>
19
+ public class MonitorInfo
17
20
{
18
21
/// <summary>
19
22
/// Gets the display monitors (including invisible pseudo-monitors associated with the mirroring drivers).
@@ -23,14 +26,14 @@ public static unsafe IList<MonitorInfo> GetDisplayMonitors()
23
26
{
24
27
var monitorCount = PInvoke . GetSystemMetrics ( SYSTEM_METRICS_INDEX . SM_CMONITORS ) ;
25
28
var list = new List < MonitorInfo > ( monitorCount ) ;
26
- var callback = new MONITORENUMPROC ( ( HMONITOR monitor , HDC deviceContext , RECT * rect , LPARAM data ) =>
29
+ var callback = new MONITORENUMPROC ( ( monitor , deviceContext , rect , data ) =>
27
30
{
28
31
list . Add ( new MonitorInfo ( monitor , rect ) ) ;
29
32
return true ;
30
33
} ) ;
31
34
var dwData = new LPARAM ( ) ;
32
35
var hdc = new HDC ( ) ;
33
- bool ok = PInvoke . EnumDisplayMonitors ( hdc , ( RECT ? ) null , callback , dwData ) ;
36
+ bool ok = PInvoke . EnumDisplayMonitors ( hdc , null , callback , dwData ) ;
34
37
if ( ! ok )
35
38
{
36
39
Marshal . ThrowExceptionForHR ( Marshal . GetLastWin32Error ( ) ) ;
@@ -43,11 +46,11 @@ public static unsafe IList<MonitorInfo> GetDisplayMonitors()
43
46
/// </summary>
44
47
/// <param name="hwnd">Window handle</param>
45
48
/// <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 )
49
+ public static unsafe MonitorInfo GetNearestDisplayMonitor ( nint hwnd )
47
50
{
48
- var nearestMonitor = PInvoke . MonitorFromWindow ( hwnd , MONITOR_FROM_FLAGS . MONITOR_DEFAULTTONEAREST ) ;
51
+ var nearestMonitor = PInvoke . MonitorFromWindow ( new ( hwnd ) , MONITOR_FROM_FLAGS . MONITOR_DEFAULTTONEAREST ) ;
49
52
MonitorInfo nearestMonitorInfo = null ;
50
- var callback = new MONITORENUMPROC ( ( HMONITOR monitor , HDC deviceContext , RECT * rect , LPARAM data ) =>
53
+ var callback = new MONITORENUMPROC ( ( monitor , deviceContext , rect , data ) =>
51
54
{
52
55
if ( monitor == nearestMonitor )
53
56
{
@@ -58,25 +61,83 @@ public static unsafe MonitorInfo GetNearestDisplayMonitor(HWND hwnd)
58
61
} ) ;
59
62
var dwData = new LPARAM ( ) ;
60
63
var hdc = new HDC ( ) ;
61
- bool ok = PInvoke . EnumDisplayMonitors ( hdc , ( RECT ? ) null , callback , dwData ) ;
64
+ bool ok = PInvoke . EnumDisplayMonitors ( hdc , null , callback , dwData ) ;
62
65
if ( ! ok )
63
66
{
64
67
Marshal . ThrowExceptionForHR ( Marshal . GetLastWin32Error ( ) ) ;
65
68
}
66
69
return nearestMonitorInfo ;
67
70
}
68
71
72
+ /// <summary>
73
+ /// Gets the primary display monitor (the one that contains the taskbar).
74
+ /// </summary>
75
+ /// <returns>The primary display monitor, or null if no monitor is found.</returns>
76
+ public static unsafe MonitorInfo GetPrimaryDisplayMonitor ( )
77
+ {
78
+ var primaryMonitor = PInvoke . MonitorFromWindow ( new HWND ( IntPtr . Zero ) , MONITOR_FROM_FLAGS . MONITOR_DEFAULTTOPRIMARY ) ;
79
+ MonitorInfo primaryMonitorInfo = null ;
80
+ var callback = new MONITORENUMPROC ( ( monitor , deviceContext , rect , data ) =>
81
+ {
82
+ if ( monitor == primaryMonitor )
83
+ {
84
+ primaryMonitorInfo = new MonitorInfo ( monitor , rect ) ;
85
+ return false ;
86
+ }
87
+ return true ;
88
+ } ) ;
89
+ var dwData = new LPARAM ( ) ;
90
+ var hdc = new HDC ( ) ;
91
+ bool ok = PInvoke . EnumDisplayMonitors ( hdc , null , callback , dwData ) ;
92
+ if ( ! ok )
93
+ {
94
+ Marshal . ThrowExceptionForHR ( Marshal . GetLastWin32Error ( ) ) ;
95
+ }
96
+ return primaryMonitorInfo ;
97
+ }
98
+
99
+ /// <summary>
100
+ /// Gets the display monitor that contains the cursor.
101
+ /// </summary>
102
+ /// <returns>The display monitor that contains the cursor, or null if no monitor is found.</returns>
103
+ public static unsafe MonitorInfo GetCursorDisplayMonitor ( )
104
+ {
105
+ if ( ! PInvoke . GetCursorPos ( out var pt ) )
106
+ {
107
+ Marshal . ThrowExceptionForHR ( Marshal . GetLastWin32Error ( ) ) ;
108
+ }
109
+ var cursorMonitor = PInvoke . MonitorFromPoint ( pt , MONITOR_FROM_FLAGS . MONITOR_DEFAULTTONEAREST ) ;
110
+ MonitorInfo cursorMonitorInfo = null ;
111
+ var callback = new MONITORENUMPROC ( ( monitor , deviceContext , rect , data ) =>
112
+ {
113
+ if ( monitor == cursorMonitor )
114
+ {
115
+ cursorMonitorInfo = new MonitorInfo ( monitor , rect ) ;
116
+ return false ;
117
+ }
118
+ return true ;
119
+ } ) ;
120
+ var dwData = new LPARAM ( ) ;
121
+ var hdc = new HDC ( ) ;
122
+ bool ok = PInvoke . EnumDisplayMonitors ( hdc , null , callback , dwData ) ;
123
+ if ( ! ok )
124
+ {
125
+ Marshal . ThrowExceptionForHR ( Marshal . GetLastWin32Error ( ) ) ;
126
+ }
127
+ return cursorMonitorInfo ;
128
+ }
129
+
69
130
private readonly HMONITOR _monitor ;
70
131
71
132
internal unsafe MonitorInfo ( HMONITOR monitor , RECT * rect )
72
133
{
73
- RectMonitor =
134
+ Bounds =
74
135
new Rect ( new Point ( rect ->left , rect ->top ) ,
75
136
new Point ( rect ->right , rect ->bottom ) ) ;
76
137
_monitor = monitor ;
77
138
var info = new MONITORINFOEXW ( ) { monitorInfo = new MONITORINFO ( ) { cbSize = ( uint ) sizeof ( MONITORINFOEXW ) } } ;
78
139
GetMonitorInfo ( monitor , ref info ) ;
79
- RectWork =
140
+ WorkingArea =
80
141
new Rect ( new Point ( info . monitorInfo . rcWork . left , info . monitorInfo . rcWork . top ) ,
81
142
new Point ( info . monitorInfo . rcWork . right , info . monitorInfo . rcWork . bottom ) ) ;
82
143
Name = new string ( info . szDevice . AsSpan ( ) ) . Replace ( "\0 " , "" ) . Trim ( ) ;
@@ -93,23 +154,23 @@ internal unsafe MonitorInfo(HMONITOR monitor, RECT* rect)
93
154
/// <remarks>
94
155
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
95
156
/// </remarks>
96
- public Rect RectMonitor { get ; }
157
+ public Rect Bounds { get ; }
97
158
98
159
/// <summary>
99
160
/// Gets the work area rectangle of the display monitor, expressed in virtual-screen coordinates.
100
161
/// </summary>
101
162
/// <remarks>
102
163
/// <note>If the monitor is not the primary display monitor, some of the rectangle's coordinates may be negative values.</note>
103
164
/// </remarks>
104
- public Rect RectWork { get ; }
165
+ public Rect WorkingArea { get ; }
105
166
106
167
/// <summary>
107
168
/// Gets if the monitor is the the primary display monitor.
108
169
/// </summary>
109
170
public bool IsPrimary => _monitor == PInvoke . MonitorFromWindow ( new ( IntPtr . Zero ) , MONITOR_FROM_FLAGS . MONITOR_DEFAULTTOPRIMARY ) ;
110
171
111
172
/// <inheritdoc />
112
- public override string ToString ( ) => $ "{ Name } { RectMonitor . Width } x{ RectMonitor . Height } ";
173
+ public override string ToString ( ) => $ "{ Name } { Bounds . Width } x{ Bounds . Height } ";
113
174
114
175
private static unsafe bool GetMonitorInfo ( HMONITOR hMonitor , ref MONITORINFOEXW lpmi )
115
176
{
0 commit comments