C # : 得到完整的桌面尺寸?

我如何找出整个桌面的大小?没有的“工作区”和 没有的“屏幕分辨率”,这两者都指只有一个屏幕。我想找出虚拟桌面的总宽度和高度,其中每个显示器只显示一部分。

86605 次浏览

我认为是时候使用一个小 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,max)之间的所有空间都是可见的。

编辑:

我刚刚意识到使用 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);

这并不能回答这个问题,只是增加了对所有屏幕中窗口的 Point (位置)的额外了解。

使用下面的代码找出一个 Point (例如最后已知的窗口位置)是否在整个桌面的范围内。如果没有,重置窗口的位置到默认的 PBaseLoc;

代码没有考虑到任务栏或其他工具栏,你自己在那里。

示例使用: 将 Window 位置从 A 站保存到数据库。用户登录到 B 站与2个监视器和移动窗口到第二个监视器,登出保存新的位置。返回到 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;

检查:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height

你有两个选择:

  1. 演示文稿框架

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

    SystemInformation.VirtualScreen.Width
    SystemInformation.VirtualScreen.Height
    

Use the first option if you developing a WPF application.

可以使用 System.Drawing的范围。

您可以创建这样的函数

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

然后你可以得到屏幕1,2,等等,在一个像这样的变量中:

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

然后你就可以得到屏幕的边界:

System.Drawing.Rectangle screen1Bounds = screen1.Bounds;

使用这段代码,您将获得所有属性,如 WidthHeight等。

此方法通过使用 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);
}

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


    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);
}
}
}
}

这应该可以完成任务;) 你好。

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

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);
}




}

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

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);
}

从 SM _ XVIRTUALSCREEN 等导出的值是物理坐标,而不等于控制面板中屏幕缩放125% 、150% 、175% 时的逻辑坐标。

您会发现许多窗口操作还不可用,或者可能永远不可用。我在 PInvoke 上取得了巨大的成功。User32 nuget 软件包。

var screenX = PInvoke.User32.GetSystemMetrics(PInvoke.User32.SystemMetric.SM_CXSCREEN);
var screenY = PInvoke.User32.GetSystemMetrics(PInvoke.User32.SystemMetric.SM_CYSCREEN);