2022-10-23 11:02:31 +13:00
|
|
|
|
// <copyright file="Screen.cs" company="PlaceholderCompany">
|
|
|
|
|
// Copyright (c) PlaceholderCompany. All rights reserved.
|
|
|
|
|
// </copyright>
|
|
|
|
|
//
|
|
|
|
|
// Copyright (c) 2022-2022 Peter Kirmeier
|
|
|
|
|
|
|
|
|
|
namespace SystemTrayMenu.DllImports
|
|
|
|
|
{
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Runtime.Versioning;
|
2022-11-14 07:58:54 +13:00
|
|
|
|
using System.Windows;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// wraps the methodcalls to native windows dll's.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static partial class NativeMethods
|
|
|
|
|
{
|
|
|
|
|
public static class Screen
|
|
|
|
|
{
|
|
|
|
|
private static Point LastCursorPosition = new Point(0, 0);
|
|
|
|
|
|
2022-11-14 07:58:54 +13:00
|
|
|
|
private static List<Rect>? screens;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
|
2022-11-14 07:58:54 +13:00
|
|
|
|
public static List<Rect> Screens
|
2022-10-23 11:02:31 +13:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if ((screens == null) || (screens.Count == 0))
|
|
|
|
|
{
|
|
|
|
|
FetchScreens();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((screens == null) || (screens.Count == 0))
|
|
|
|
|
{
|
|
|
|
|
return new()
|
|
|
|
|
{
|
2022-11-14 07:58:54 +13:00
|
|
|
|
new (0, 0, 800, 600),
|
2022-10-23 11:02:31 +13:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return screens;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 07:58:54 +13:00
|
|
|
|
public static Rect PrimaryScreen => Screens[0];
|
2022-10-23 11:02:31 +13:00
|
|
|
|
|
|
|
|
|
public static Point CursorPosition
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
NativeMethods.POINT lpPoint;
|
|
|
|
|
if (NativeMethods.GetCursorPos(out lpPoint))
|
|
|
|
|
{
|
|
|
|
|
LastCursorPosition = new(lpPoint.X, lpPoint.Y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return LastCursorPosition;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 07:58:54 +13:00
|
|
|
|
public static Rect FromPoint(Point pt)
|
2022-10-23 11:02:31 +13:00
|
|
|
|
{
|
2022-11-14 07:58:54 +13:00
|
|
|
|
foreach (Rect screen in Screens)
|
2022-10-23 11:02:31 +13:00
|
|
|
|
{
|
|
|
|
|
if (screen.Contains(pt))
|
|
|
|
|
{
|
|
|
|
|
return screen;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Use primary screen as fallback
|
|
|
|
|
return Screens[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static void FetchScreens()
|
|
|
|
|
{
|
|
|
|
|
var backup = screens;
|
|
|
|
|
screens = new();
|
|
|
|
|
if (!NativeMethods.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumCallback, IntPtr.Zero))
|
|
|
|
|
{
|
|
|
|
|
screens = backup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool MonitorEnumCallback(IntPtr hMonitor, IntPtr hdcMonitor, ref NativeMethods.RECT lprcMonitor, IntPtr dwData)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
screens!.Add(new()
|
|
|
|
|
{
|
|
|
|
|
X = lprcMonitor.left,
|
|
|
|
|
Y = lprcMonitor.top,
|
|
|
|
|
Width = lprcMonitor.right - lprcMonitor.left,
|
|
|
|
|
Height = lprcMonitor.bottom - lprcMonitor.top,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
// Catch everything as this callback runs within a native context
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class NativeMethods
|
|
|
|
|
{
|
|
|
|
|
public delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaymonitors .
|
|
|
|
|
/// </summary>
|
|
|
|
|
[SupportedOSPlatform("windows")]
|
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
|
|
|
|
public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, IntPtr dwData);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getcursorpos .
|
|
|
|
|
/// </summary>
|
|
|
|
|
[SupportedOSPlatform("windows")]
|
|
|
|
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
|
|
|
|
public static extern bool GetCursorPos(out POINT lpPoint);
|
|
|
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
|
|
|
internal struct RECT
|
|
|
|
|
{
|
|
|
|
|
public int left;
|
|
|
|
|
public int top;
|
|
|
|
|
public int right;
|
|
|
|
|
public int bottom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
|
|
|
internal struct POINT
|
|
|
|
|
{
|
|
|
|
|
public int X;
|
|
|
|
|
public int Y;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|