C#:获取完整的桌面大小?


77

如何找出整个桌面的大小?不是“工作区域”,也不是“屏幕分辨率”,两者均仅指一个屏幕。我想找出每个监视器仅显示一部分的虚拟桌面的总宽度和高度。


2
也许“完整的桌面尺寸”将取决于屏幕的放置方式。不确定如何计算,但是您仍然可以使用System.Windows.Forms.Screen.AllScreens捕获屏幕数和每个屏幕的分辨率。
Havenard

Answers:


129

您有两种选择:

  1. PresentationFramework.dll

    SystemParameters.VirtualScreenWidth   
    SystemParameters.VirtualScreenHeight
    
  2. System.Windows.Forms.dll

    SystemInformation.VirtualScreen.Width   
    SystemInformation.VirtualScreen.Height
    

如果您开发WPF应用程序,请使用第一个选项


1
更多类似的答案!简短,正确,美观!
Bitterblue '17

我发现了以下情形:如果启用缩放,则这些值将仅注册一个屏幕。可能取决于硬件,尚不确定。
凯利·埃尔顿

这很可能早在2011年就已实现,但多桌面扩展并不是一回事。如果找到解决方法,@ KellyElton会更新答案。
丹尼斯

1
我找不到解决方案,我认为这是一个错误。我正在使用Blackweb BWA17HO002 usb3转hdmi适配器,以及Intel HD 520(笔记本电脑)。当笔记本电脑的显示比例> 150%时,这些值将仅返回笔记本电脑的屏幕尺寸。删除缩放比例后,它将注册第二个监视器。
凯莉·艾尔顿

31

我认为是时候使用一些LINQ来更新此答案了,这使通过单个表达式轻松获取整个桌面大小变得容易。

Console.WriteLine(
    Screen.AllScreens.Select(screen=>screen.Bounds)
    .Aggregate(Rectangle.Union)
    .Size
);

我的原始答案如下:


我猜你想要的是这样的:

int minx, miny, maxx, maxy;
minx = miny = int.MaxValue;
maxx = maxy = int.MinValue;

foreach(Screen screen in Screen.AllScreens){
    var bounds = screen.Bounds;
    minx = Math.Min(minx, bounds.X);
    miny = Math.Min(miny, bounds.Y);
    maxx = Math.Max(maxx, bounds.Right);
    maxy = Math.Max(maxy, bounds.Bottom);
}

Console.WriteLine("(width, height) = ({0}, {1})", maxx - minx, maxy - miny);

请记住,这并不能说明全部情况。多个监视器可能交错或排列成非矩形。因此,可能不是(minx,miny)和(maxx,maxy)之间的所有空间都是可见的。

编辑:

我只是意识到使用以下代码可能会更简单Rectangle.Union

Rectangle rect = new Rectangle(int.MaxValue, int.MaxValue, int.MinValue, int.MinValue);

foreach(Screen screen in Screen.AllScreens)
    rect = Rectangle.Union(rect, screen.Bounds);

Console.WriteLine("(width, height) = ({0}, {1})", rect.Width, rect.Height);

3
我是乌克兰程序员。我正在验证此代码是否在包装盒中正常工作。只需复制并粘贴。
Vova Popov

15

检查:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height

7

要获取显示器的物理像素大小,您可以使用它。

static class DisplayTools
{
    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

    private enum DeviceCap
    {
        Desktopvertres = 117,
        Desktophorzres = 118
    }

    public static Size GetPhysicalDisplaySize()
    {
        Graphics g = Graphics.FromHwnd(IntPtr.Zero);
        IntPtr desktop = g.GetHdc();

        int physicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.Desktopvertres);
        int physicalScreenWidth = GetDeviceCaps(desktop, (int)DeviceCap.Desktophorzres);

        return new Size(physicalScreenWidth, physicalScreenHeight);
    }


}

这是第一个报告正确大小的报告,但仅适用于单个监视器。😑
BrainSlugs83

6

这并不能回答问题,而只是在所有屏幕内的窗口点(位置)上增加了其他见解。

使用下面的代码找出一个点(例如,窗口的最后一个已知位置)是否在整个桌面的范围内。否则,将窗口的Location重置为默认的pBaseLoc

代码没有考虑任务栏或其他工具栏,它们自己存在。

使用示例:将窗口位置从站点A保存到数据库中。用户使用2个监视器登录到B站,然后将窗口移至第二个监视器,注销并保存新位置。返回站点A,除非使用上述代码,否则不会显示该窗口。

我的进一步解决方案是将用户ID和工作站的IP(&winLoc)保存到给定应用程序的数据库或本地用户首选项文件中,然后在该工作站和应用程序的用户首选项中加载。

Point pBaseLoc = new Point(40, 40)
int x = -500, y = 140;
Point pLoc = new Point(x, y);
bool bIsInsideBounds = false;

foreach (Screen s in Screen.AllScreens)
{
    bIsInsideBounds = s.Bounds.Contains(pLoc);
    if (bIsInsideBounds) { break; }
}//foreach (Screen s in Screen.AllScreens)

if (!bIsInsideBounds) { pLoc = pBaseLoc;  }

this.Location = pLoc;

6
如果您知道这不能回答问题,那么为什么要发布它作为问题的答案?第一句话不应该敲响警钟吗?
Timwi

1
另一方面,这正是我搜索该主题时一直在寻找的东西
Simon Gillbee,2013年

3

我认为获取“真实”屏幕尺寸的最佳方法是直接从视频控制器获取值。


    using System;
    using System.Management;
    using System.Windows.Forms;

    namespace MOS
    {
        public class ClassMOS
        {
            public static void Main()
            {
                try
                {
                    ManagementObjectSearcher searcher = 
                        new ManagementObjectSearcher("root\\CIMV2", 
                        "SELECT * FROM Win32_VideoController"); 

                    foreach (ManagementObject queryObj in searcher.Get())
                    {
                        Console.WriteLine("CurrentHorizontalResolution: {0}", queryObj["CurrentHorizontalResolution"]);
                        Console.WriteLine("-----------------------------------");
                        Console.WriteLine("CurrentVerticalResolution: {0}", queryObj["CurrentVerticalResolution"]);
                    }
                }
                catch (ManagementException e)
                {
                    MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
                }
            }
        }
}

这应该做的工作;)问候...


1

您可以使用的范围System.Drawing

您可以创建一个这样的功能

public System.Windows.Form.Screen[] GetScreens(){
    Screen[] screens = Screen.AllScreens;
    return screens;
}

然后您可以像这样在变量中获得屏幕一,二等:

System.Windows.Form.Screen[] screens = func.GetScreens();
System.Windows.Form.Screen screen1 = screens[0];

那么您可以获取屏幕的边界:

System.Drawing.Rectangle screen1Bounds = screen1.Bounds;

有了这个代码,你会得到像所有属性WidthHeight等等。


1

此方法通过使用Left和Top的最小值和Right和Bottom的最大值来返回包含所有屏幕边界的矩形...

static Rectangle GetDesktopBounds() {
   var l = int.MaxValue;
   var t = int.MaxValue;
   var r = int.MinValue;
   var b = int.MinValue;
   foreach(var screen in Screen.AllScreens) {
      if(screen.Bounds.Left   < l) l = screen.Bounds.Left  ;
      if(screen.Bounds.Top    < t) t = screen.Bounds.Top   ;
      if(screen.Bounds.Right  > r) r = screen.Bounds.Right ;
      if(screen.Bounds.Bottom > b) b = screen.Bounds.Bottom;
   }
   return Rectangle.FromLTRB(l, t, r, b);
}

请解释一下。
Syeda Zunaira

它遍历所有屏幕。如果左边缘小于变量“ l”,则将“ l”设置为该新值,如果底部边缘大于“ b”,则将其设置为新值。最终结果是将l,t,r,b设置为整个可见桌面的左,上,右和下边缘。
dynamichael

1

获取没有任何依赖关系的虚拟显示的大小

public enum SystemMetric
{
    VirtualScreenWidth = 78, // CXVIRTUALSCREEN 0x0000004E 
    VirtualScreenHeight = 79, // CYVIRTUALSCREEN 0x0000004F 
}

[DllImport("user32.dll")]
public static extern int GetSystemMetrics(SystemMetric metric);

public static Size GetVirtualDisplaySize()
{
    var width = GetSystemMetrics(SystemMetric.VirtualScreenWidth);
    var height = GetSystemMetrics(SystemMetric.VirtualScreenHeight);

    return new Size(width, height);
}

IMO的最佳答案,没有明确的依赖关系。
Zintom
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.