C# 如何获取活动屏幕尺寸?

C# 如何获取活动屏幕尺寸?,c#,wpf,C#,Wpf,我要寻找的是当前窗口所在监视器的System.Windows.SystemParameters.WorkArea 澄清:所讨论的窗口是WPF,而不是WinForm屏幕。FromControl、屏幕。FromPoint和屏幕。FromRectangle应该可以帮助您完成这项工作。例如,在WinForms中: class MyForm : Form { public Rectangle GetScreen() { return Screen.FromControl(this).Bou

我要寻找的是当前窗口所在监视器的
System.Windows.SystemParameters.WorkArea


澄清:所讨论的窗口是
WPF
,而不是
WinForm

屏幕。FromControl
屏幕。FromPoint
屏幕。FromRectangle
应该可以帮助您完成这项工作。例如,在WinForms中:

class MyForm : Form
{
  public Rectangle GetScreen()
  {
    return Screen.FromControl(this).Bounds;
  }
}
我不知道有没有类似的WPF调用。因此,您需要执行类似于此扩展方法的操作

static class ExtensionsForWPF
{
  public static System.Windows.Forms.Screen GetScreen(this Window window)
  {
    return System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(window).Handle);
  }
}
添加到ffpf

Screen.FromControl(this).Bounds

您可以使用此选项获取主屏幕的桌面工作区边界:

这对于获取主屏幕的大小也很有用:

您可能还需要:


要获得所有显示器的组合尺寸,而不是一个显示器。

我想在打开第一个窗口之前获得屏幕分辨率,因此这里有一个快速解决方案,在实际测量屏幕尺寸之前打开一个不可见的窗口(您需要使窗口参数适应您的窗口,以确保两者在同一屏幕上打开-主要是
WindowStartupLocation
很重要)


我需要设置窗口应用程序的最大大小。此应用程序可以相应更改。应用程序显示在主屏幕或辅助屏幕中。为了解决此问题,我创建了一个简单的方法,我将在下面向您展示:

/// <summary>
/// Set the max size of the application window taking into account the current monitor
/// </summary>
public static void SetMaxSizeWindow(ioConnect _receiver)
{
    Point absoluteScreenPos = _receiver.PointToScreen(Mouse.GetPosition(_receiver));

    if (System.Windows.SystemParameters.VirtualScreenLeft == System.Windows.SystemParameters.WorkArea.Left)
    {
        //Primary Monitor is on the Left
        if (absoluteScreenPos.X <= System.Windows.SystemParameters.PrimaryScreenWidth)
        {
            //Primary monitor
            _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.WorkArea.Width;
            _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
        }
        else
        {
            //Secondary monitor
            _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.VirtualScreenWidth - System.Windows.SystemParameters.WorkArea.Width;
            _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.VirtualScreenHeight;
        }
    }

    if (System.Windows.SystemParameters.VirtualScreenLeft < 0)
    {
        //Primary Monitor is on the Right
        if (absoluteScreenPos.X > 0)
        {
            //Primary monitor
            _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.WorkArea.Width;
            _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.WorkArea.Height;
        }
        else
        {
            //Secondary monitor
            _receiver.WindowApplication.MaxWidth = System.Windows.SystemParameters.VirtualScreenWidth - System.Windows.SystemParameters.WorkArea.Width;
            _receiver.WindowApplication.MaxHeight = System.Windows.SystemParameters.VirtualScreenHeight;
        }
    }
}
//
///根据当前监视器设置应用程序窗口的最大大小
/// 
公共静态无效设置MaxSizeWindow(ioConnect\u接收器)
{
点绝对屏幕位置=_receiver.PointToScreen(Mouse.GetPosition(_receiver));
if(System.Windows.SystemParameters.VirtualScreenLeft==System.Windows.SystemParameters.WorkArea.Left)
{
//主监视器在左边
如果(绝对屏幕位置X 0)
{
//主监视器
_receiver.WindowApplication.MaxWidth=System.Windows.SystemParameters.WorkArea.Width;
_receiver.WindowApplication.MaxHeight=System.Windows.SystemParameters.WorkArea.Height;
}
其他的
{
//辅助监视器
_receiver.WindowApplication.MaxWidth=System.Windows.SystemParameters.VirtualScreenWidth-System.Windows.SystemParameters.WorkArea.Width;
_receiver.WindowApplication.MaxHeight=System.Windows.SystemParameters.VirtualScreenHeight;
}
}
}
这是一个“中央屏幕”,使用代替或: 由于屏幕尺寸计算,对我来说唯一有效的方法是(包括任务栏计算):


小心你的窗口比例因子(100%/125%/150%/200%)。 您可以使用以下代码获得真实的屏幕大小:

SystemParameters.FullPrimaryScreenHeight
SystemParameters.FullPrimaryScreenWidth

添加不使用WinForms而是使用NativeMethods的解决方案。 首先,您需要定义所需的本机方法

public static class NativeMethods
{
    public const Int32 MONITOR_DEFAULTTOPRIMERTY = 0x00000001;
    public const Int32 MONITOR_DEFAULTTONEAREST = 0x00000002;


    [DllImport( "user32.dll" )]
    public static extern IntPtr MonitorFromWindow( IntPtr handle, Int32 flags );


    [DllImport( "user32.dll" )]
    public static extern Boolean GetMonitorInfo( IntPtr hMonitor, NativeMonitorInfo lpmi );


    [Serializable, StructLayout( LayoutKind.Sequential )]
    public struct NativeRectangle
    {
        public Int32 Left;
        public Int32 Top;
        public Int32 Right;
        public Int32 Bottom;


        public NativeRectangle( Int32 left, Int32 top, Int32 right, Int32 bottom )
        {
            this.Left = left;
            this.Top = top;
            this.Right = right;
            this.Bottom = bottom;
        }
    }


    [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Auto )]
    public sealed class NativeMonitorInfo
    {
        public Int32 Size = Marshal.SizeOf( typeof( NativeMonitorInfo ) );
        public NativeRectangle Monitor;
        public NativeRectangle Work;
        public Int32 Flags;
    }
}
然后像这样获取监视器句柄和监视器信息

        var hwnd = new WindowInteropHelper( this ).EnsureHandle();
        var monitor = NativeMethods.MonitorFromWindow( hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST );

        if ( monitor != IntPtr.Zero )
        {
            var monitorInfo = new NativeMonitorInfo();
            NativeMethods.GetMonitorInfo( monitor, monitorInfo );

            var left = monitorInfo.Monitor.Left;
            var top = monitorInfo.Monitor.Top;
            var width = ( monitorInfo.Monitor.Right - monitorInfo.Monitor.Left );
            var height = ( monitorInfo.Monitor.Bottom - monitorInfo.Monitor.Top );
        }
在C#winforms中,我通过以下方法获得了起点(例如,当我们有多个monitor/diplay,一个窗体调用另一个窗体时):

private Point get_start_point()
    {
        return
            new Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X,
                      Screen.GetBounds(parent_class_with_form.ActiveForm).Y
                      );
    }
桌面应用程序 对于多监视器设置,您还需要考虑X和Y位置:

Rectangle activeScreenDimensions = Screen.FromControl(this).Bounds;
this.Size = new Size(activeScreenDimensions.Width + activeScreenDimensions.X, activeScreenDimensions.Height + activeScreenDimensions.Y);
此调试代码应能很好地完成以下任务:

您可以探索

使用Screen.AllScreens将所有显示器放入一个数组或列表中,然后捕获当前显示器的索引及其属性

C#(由Telerik从VB转换而来-请仔细检查)


也许我的标签没有明确说明我使用的是WPF windows,而不是WinForms。我没有引用System.windows.Forms.dll,而且它也不会工作,因为WPF有自己的继承树。不客气。我为没有直接找到答案而道歉-我必须在更新我的文件之前调查WPF中有哪些可用内容这可以在右边边缘放置一个窗口:var bounds=This.GetScreen().WorkingArea;this.Left=bounds.Right-this.Width;但它需要引用System.Windows.Forms和System.Drawing,这并不理想。@设备注意,此调用不支持DPI;您需要进行计算。在我的VS 2015 WPF应用程序中,在Windows 10 Pro(v10.0.14393)上的4-monitor系统上以.NET 4.5为目标当显示器上的
窗口位于我的主显示器上方时(例如,它的
顶部<0
),
FromHandle
返回我的主显示器的
屏幕(即使
窗口
完全位于辅助显示器内)!?!叹气。看起来我必须搜索
屏幕。所有屏幕都是我自己排列的。为什么事情不能“正常工作”?!?arrrgh.更改了已接受的答案,以反映从WPF.System.Windows.SystemParameters执行此操作的最佳方式。*对我来说,不使用WinForms名称空间的困扰似乎很奇怪,它不会给您带来任何好处;相反,它让您没有适当解决问题所需的工具。对我来说,这不是WinForms vs.WPF的问题,而是学习新的东西。如果我不同时学习两种方法,我无法决定哪种方法更好。在这种情况下,没有“两种方法”因为只有一种方法可以做到这一点,那就是使用WinForms的东西。@Jeff Yates:你是对的。我找到了我问这个问题的原始项目,发现我使用了PrimaryScreen*属性。它们解决了我一天的需要,但不是我问的实际问题。很抱歉,我改变了公认的答案因此,我感到困惑…这似乎只是返回主屏幕尺寸。我想知道窗口当前所在屏幕的尺寸…这并不能回答问题,即使您只想获得主屏幕的大小,系统参数(WPF)不正确。它们返回与设备无关的单位,而不是像素。为了更好地实现
private Point get_start_point()
    {
        return
            new Point(Screen.GetBounds(parent_class_with_form.ActiveForm).X,
                      Screen.GetBounds(parent_class_with_form.ActiveForm).Y
                      );
    }
Rectangle activeScreenDimensions = Screen.FromControl(this).Bounds;
this.Size = new Size(activeScreenDimensions.Width + activeScreenDimensions.X, activeScreenDimensions.Height + activeScreenDimensions.Y);
        {
    List<Screen> arrAvailableDisplays = new List<Screen>();
    List<string> arrDisplayNames = new List<string>();

    foreach (Screen Display in Screen.AllScreens)
    {
        arrAvailableDisplays.Add(Display);
        arrDisplayNames.Add(Display.DeviceName);
    }

    Screen scrCurrentDisplayInfo = Screen.FromControl(this);
    string strDeviceName = Screen.FromControl(this).DeviceName;
    int idxDevice = arrDisplayNames.IndexOf(strDeviceName);

    MessageBox.Show(this, "Number of Displays Found: " + arrAvailableDisplays.Count.ToString() + Constants.vbCrLf + "ID: " + idxDevice.ToString() + Constants.vbCrLf + "Device Name: " + scrCurrentDisplayInfo.DeviceName.ToString + Constants.vbCrLf + "Primary: " + scrCurrentDisplayInfo.Primary.ToString + Constants.vbCrLf + "Bounds: " + scrCurrentDisplayInfo.Bounds.ToString + Constants.vbCrLf + "Working Area: " + scrCurrentDisplayInfo.WorkingArea.ToString + Constants.vbCrLf + "Bits per Pixel: " + scrCurrentDisplayInfo.BitsPerPixel.ToString + Constants.vbCrLf + "Width: " + scrCurrentDisplayInfo.Bounds.Width.ToString + Constants.vbCrLf + "Height: " + scrCurrentDisplayInfo.Bounds.Height.ToString + Constants.vbCrLf + "Work Area Width: " + scrCurrentDisplayInfo.WorkingArea.Width.ToString + Constants.vbCrLf + "Work Area Height: " + scrCurrentDisplayInfo.WorkingArea.Height.ToString, "Current Info for Display '" + scrCurrentDisplayInfo.DeviceName.ToString + "' - ID: " + idxDevice.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Information);
}
 Dim arrAvailableDisplays As New List(Of Screen)()
    Dim arrDisplayNames As New List(Of String)()

    For Each Display As Screen In Screen.AllScreens
        arrAvailableDisplays.Add(Display)
        arrDisplayNames.Add(Display.DeviceName)
    Next

    Dim scrCurrentDisplayInfo As Screen = Screen.FromControl(Me)
    Dim strDeviceName As String = Screen.FromControl(Me).DeviceName
    Dim idxDevice As Integer = arrDisplayNames.IndexOf(strDeviceName)

    MessageBox.Show(Me,
                    "Number of Displays Found: " + arrAvailableDisplays.Count.ToString & vbCrLf &
                    "ID: " & idxDevice.ToString + vbCrLf &
                    "Device Name: " & scrCurrentDisplayInfo.DeviceName.ToString + vbCrLf &
                    "Primary: " & scrCurrentDisplayInfo.Primary.ToString + vbCrLf &
                    "Bounds: " & scrCurrentDisplayInfo.Bounds.ToString + vbCrLf &
                    "Working Area: " & scrCurrentDisplayInfo.WorkingArea.ToString + vbCrLf &
                    "Bits per Pixel: " & scrCurrentDisplayInfo.BitsPerPixel.ToString + vbCrLf &
                    "Width: " & scrCurrentDisplayInfo.Bounds.Width.ToString + vbCrLf &
                    "Height: " & scrCurrentDisplayInfo.Bounds.Height.ToString + vbCrLf &
                    "Work Area Width: " & scrCurrentDisplayInfo.WorkingArea.Width.ToString + vbCrLf &
                    "Work Area Height: " & scrCurrentDisplayInfo.WorkingArea.Height.ToString,
                    "Current Info for Display '" & scrCurrentDisplayInfo.DeviceName.ToString & "' - ID: " & idxDevice.ToString, MessageBoxButtons.OK, MessageBoxIcon.Information)