Skip to content

Instantly share code, notes, and snippets.

@emoacht
Created March 19, 2021 06:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emoacht/b56aa494692536c37f038580fa1792e7 to your computer and use it in GitHub Desktop.
Save emoacht/b56aa494692536c37f038580fa1792e7 to your computer and use it in GitHub Desktop.
Get screen Rect from a FrameworkElement
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Media;
public static class ScreenHelper
{
public static Rect ToScreenRect(this FrameworkElement element) => GetMonitorRect(GetElementRect(element));
private static Rect GetElementRect(FrameworkElement element)
{
var point = element.PointToScreen(new Point(0, 0));
var dpi = VisualTreeHelper.GetDpi(element);
return new Rect(point, new Size(element.ActualWidth * dpi.DpiScaleX, element.ActualHeight * dpi.DpiScaleY));
}
private static Rect GetMonitorRect(Rect elementRect)
{
RECT rect = elementRect;
var monitorHandle = MonitorFromRect(ref rect, MONITOR_DEFAULTTONULL);
if (monitorHandle != IntPtr.Zero)
{
var monitorInfo = new MONITORINFO { cbSize = (uint)Marshal.SizeOf<MONITORINFO>() };
if (GetMonitorInfo(monitorHandle, ref monitorInfo))
{
return monitorInfo.rcMonitor;
}
}
return Rect.Empty;
}
[DllImport("User32.dll")]
private static extern IntPtr MonitorFromRect(ref RECT lprc, uint dwFlags);
private const uint MONITOR_DEFAULTTONULL = 0x00000000;
[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
[StructLayout(LayoutKind.Sequential)]
private struct MONITORINFO
{
public uint cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public static implicit operator Rect(RECT rect)
{
return new Rect(
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top);
}
public static implicit operator RECT(Rect rect)
{
return new RECT
{
left = (int)rect.X,
top = (int)rect.Y,
right = (int)rect.Right,
bottom = (int)rect.Bottom
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment