C# 如何获得打开用户控件的屏幕的分辨率?
我想知道屏幕的分辨率,我读过这个问题: 然而,这似乎给出了主屏幕的分辨率,但我想知道是否有办法获得显示窗口的屏幕的分辨率 例如,我必须安装屏幕、笔记本电脑屏幕和显示器。笔记本电脑的分辨率为1366x768,显示器的分辨率为1920x1080。主屏幕是显示器,笔记本电脑的屏幕是辅助屏幕 我希望有一个简单的应用程序,它有一个按钮,我希望当我点击按钮时,它给出我看到窗口的监视器的分辨率。如果我把窗口拖到另一个显示器上,那么它会给出另一个显示器的分辨率C# 如何获得打开用户控件的屏幕的分辨率?,c#,wpf,C#,Wpf,我想知道屏幕的分辨率,我读过这个问题: 然而,这似乎给出了主屏幕的分辨率,但我想知道是否有办法获得显示窗口的屏幕的分辨率 例如,我必须安装屏幕、笔记本电脑屏幕和显示器。笔记本电脑的分辨率为1366x768,显示器的分辨率为1920x1080。主屏幕是显示器,笔记本电脑的屏幕是辅助屏幕 我希望有一个简单的应用程序,它有一个按钮,我希望当我点击按钮时,它给出我看到窗口的监视器的分辨率。如果我把窗口拖到另一个显示器上,那么它会给出另一个显示器的分辨率 谢谢。您可以通过各种方式来完成,但我喜欢使用Mon
谢谢。您可以通过各种方式来完成,但我喜欢使用MonitorFromRect和GetMonitorInfo函数的简单方式。假设您为每个监视器DPI设置了正确的app.manifest,下面的扩展方法将用于从FrameworkElement获取screen Rect
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
};
}
}
}
关于jwdonahue提出的点,此方法将返回与指定框架元素具有最大交集的屏幕矩形
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
};
}
}
}
使用系统;
使用System.Runtime.InteropServices;
使用System.Windows;
使用System.Windows.Media;
公共静态类ScreenHelper
{
publicstaticrect-ToScreenRect(这个FrameworkElement元素)=>getmonitorect(GetElementRect(元素));
私有静态Rect GetElementRect(FrameworkElement元素)
{
var point=element.PointToScreen(新点(0,0));
var dpi=visualtreeheloper.GetDpi(元素);
返回新的Rect(点,新大小(element.ActualWidth*dpi.DpiScaleX,element.ActualHeight*dpi.DpiScaleY));
}
私有静态Rect getmonitorect(Rect elementRect)
{
RECT RECT=elementRect;
var monitorHandle=MonitorFromRect(ref rect,MONITOR\u DEFAULTTONULL);
如果(监视器句柄!=IntPtr.Zero)
{
var monitorInfo=new monitorInfo{cbSize=(uint)Marshal.SizeOf()};
if(GetMonitorInfo(monitorHandle,ref monitorInfo))
{
返回monitorInfo.rcMonitor;
}
}
返回Rect.Empty;
}
[DllImport(“User32.dll”)]
私有静态外部IntPtr监视器fromrect(ref RECT lprc,uint dwFlags);
专用consuint监视器\u DEFAULTTONULL=0x00000000;
[DllImport(“User32.dll”)]
[返回:Marshallas(UnmanagedType.Bool)]
私有静态外部bool GetMonitorInfo(IntPtr hMonitor,ref MONITORINFO lpmi);
[StructLayout(LayoutKind.Sequential)]
私有结构监视器信息
{
公共单位cbSize;
公共RECT-rcMonitor;
公共关系工作;
公共旗帜;
}
[StructLayout(LayoutKind.Sequential)]
私有结构矩形
{
公共int左;
公共int top;
公共权利;
公共int底部;
公共静态隐式运算符Rect(Rect Rect)
{
返回新Rect(
右,左,
右上角,
右,右,左,
矩形底部-矩形顶部);
}
公共静态隐式运算符RECT(RECT RECT)
{
返回新RECT
{
左=(int)rect.X,
top=(int)rect.Y,
右=(int)rect.right,
bottom=(int)rect.bottom
};
}
}
}
我认为您需要System.Windows.Forms.Screen[]AllScreens{get;}
来查找特定屏幕的分辨率,但这对于您似乎想要使用它的目的通常没有用处。如果窗口跨越两个或多个屏幕怎么办?是的,我不知道一个窗口是否拆分为两个窗口,但在我的情况下,我不会这样做,但这是一个很好的想法。这个分辨率信息将用于什么?如果只是提供信息,您可以在固定的屏幕相对位置放置一个对话框,显示屏幕分辨率。不需要拖动窗口。