0

I wanted to know the resolution of the screen and I have read this question:Get and Set Screen Resolution

However, it seems this give the resolution of the primary screen, but I would like to know if there is some way to get the resolution of the screen in which is shown the window.

For example, I have to screens, the laptop screen and a monitor. The laptop has a resolution of 1366x768 and the monitor has a resolution of 1920x1080. The main screen is the monitor, and the screen of the laptop is the secondary screen.

I would like to have a simple application that it has a button, and I would like than when I click the button, it gives the resolution of the monitor in which I am seeing the window. If I drag the window to the other monitor, then it should give me the resolution of the other monitor.

Thanks.

Álvaro García
  • 18,114
  • 30
  • 102
  • 193
  • 1
    I think you want `System.Windows.Forms.Screen[] AllScreens { get; }` to find the resolution of a specific screen, but that's generally not useful for what you seem to want to use it for. What if the window spans two or more screens? – jwdonahue Mar 18 '21 at 20:14
  • Yes, I didn't realize about if a windows is split in 2 windows, but in my case it iwill not happen, but it is a good point to have in mind. – Álvaro García Mar 19 '21 at 09:02
  • What will this resolution information be used for? If it's just informational, you could put a dialog at fixed, screen relative location, that shows that screens resolution. No need to drag the window around. – jwdonahue Mar 19 '21 at 16:35

1 Answers1

1

You can accomplish it by various ways but I like straightforward way using MonitorFromRect and GetMonitorInfo functions. Assuming you set proper app.manifest for Per-Monitor DPI, the following extension method will work to get screen Rect from a FrameworkElement.

Regarding the point jwdonahue raised, this method will return the Rect of screen which has the largest intersection with the specified 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
            };
        }
    }
}
emoacht
  • 2,764
  • 1
  • 13
  • 24