49 lines
1.9 KiB
C#
49 lines
1.9 KiB
C#
using System.Windows;
|
|
|
|
namespace DeskCore;
|
|
|
|
/// <summary>Bildschirm-Hilfen, damit Fenster nie außerhalb des sichtbaren Bereichs landen (z. B. nach Abstecken eines Monitors).</summary>
|
|
public static class Screens
|
|
{
|
|
/// <summary>Umrechnung Pixel → WPF-Einheiten (System-DPI).</summary>
|
|
public static double Scale
|
|
{
|
|
get
|
|
{
|
|
using var g = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
|
|
return g.DpiX / 96.0;
|
|
}
|
|
}
|
|
|
|
/// <summary>Arbeitsbereiche (ohne Taskleiste) aller angeschlossenen Bildschirme in WPF-Einheiten.</summary>
|
|
public static List<Rect> WorkAreas()
|
|
{
|
|
var s = Scale;
|
|
return System.Windows.Forms.Screen.AllScreens
|
|
.Select(m => new Rect(m.WorkingArea.X / s, m.WorkingArea.Y / s, m.WorkingArea.Width / s, m.WorkingArea.Height / s))
|
|
.ToList();
|
|
}
|
|
|
|
public static Rect PrimaryWorkArea => SystemParameters.WorkArea;
|
|
|
|
/// <summary>Arbeitsbereich des Bildschirms, auf dem der Punkt liegt (sonst der nächstgelegene).</summary>
|
|
public static Rect WorkAreaAt(Point p)
|
|
{
|
|
var areas = WorkAreas();
|
|
return areas.FirstOrDefault(a => a.Contains(p), areas.OrderBy(a =>
|
|
Math.Pow(Math.Clamp(p.X, a.Left, a.Right) - p.X, 2) + Math.Pow(Math.Clamp(p.Y, a.Top, a.Bottom) - p.Y, 2))
|
|
.FirstOrDefault(PrimaryWorkArea));
|
|
}
|
|
|
|
/// <summary>Ist genug vom Fenster (Titelleiste) auf irgendeinem Bildschirm sichtbar, um es greifen zu können?</summary>
|
|
public static bool IsReachable(Rect window)
|
|
{
|
|
var title = new Rect(window.X, window.Y, window.Width, Math.Min(40, window.Height));
|
|
return WorkAreas().Any(a =>
|
|
{
|
|
var i = Rect.Intersect(a, title);
|
|
return !i.IsEmpty && i.Width >= Math.Min(120, window.Width / 2) && i.Height >= 20;
|
|
});
|
|
}
|
|
}
|