c# - 如何获取打开用户控件的屏幕分辨率?
问题描述
我想知道屏幕的分辨率,我读过这个问题:获取和设置屏幕分辨率
但是,这似乎给出了主屏幕的分辨率,但我想知道是否有某种方法可以获得显示窗口的屏幕的分辨率。
例如,我要屏幕、笔记本电脑屏幕和显示器。笔记本电脑的分辨率为 1366x768,显示器的分辨率为 1920x1080。主屏幕是显示器,笔记本电脑的屏幕是副屏幕。
我想要一个简单的应用程序,它有一个按钮,我希望当我单击按钮时,它会给出我看到窗口的显示器的分辨率。如果我将窗口拖到另一台显示器,那么它应该给我另一台显示器的分辨率。
谢谢。
解决方案
您可以通过多种方式完成它,但我喜欢使用 MonitorFromRect 和 GetMonitorInfo 函数的直接方式。假设您为 Per-Monitor DPI 设置了正确的 app.manifest,以下扩展方法将用于从 FrameworkElement 获取屏幕 Rect。
关于 jwdonahue 提出的点,此方法将返回与指定 FrameworkElement 有最大交集的屏幕的 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
};
}
}
}
推荐阅读
- javascript - 我的 Javascript 动画无法正常工作。接收类型错误:r 未定义
- react-native - `run-android`时反应本机错误
- azure - 在 Azure HDInsight Blob 存储中读取 csv 文件时出错。
- c++ - 多线程 RayTracer 使用两种不同的算法生成工件
- ionic3 - Ionic 3:Android 模拟器引发运行时错误:无法读取未定义的属性“调整大小”
- macos - 用较新的 Brew 版本替换旧的 Xcode 命令行工具
- exception - 声明 CurPageChanged 时 Inno 脚本中的奇怪异常行为
- python - 在 matplotlib 中调整 xticklabel 的位置对 x 方向没有影响
- csv - 使用 sed 查找并替换特定 csv 列中的多个模式
- python - 如何使用整数变量作为函数的参数?