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

发布于 2024-08-02 10:05:15 字数 112 浏览 3 评论 0原文

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

How do I find out the size of the entire desktop? Not the "working area" and not the "screen resolution", both of which refer to only one screen. I want to find out the total width and height of the virtual desktop of which each monitor is showing only a part.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

嘿嘿嘿 2024-08-09 10:05:15

您有两个选择:

  1. PresentationFramework.dll

    SystemParameters.VirtualScreenWidth   
    系统参数.VirtualScreenHeight
    
  2. System.Windows.Forms.dll

    SystemInformation.VirtualScreen.Width   
    系统信息.虚拟屏幕.高度
    

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

You have two options:

  1. PresentationFramework.dll

    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.

不一样的天空 2024-08-09 10:05:15

我认为是时候用一点 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);

I think it's time to bring this answer up to date with a little LINQ, which makes it easy to get the entire desktop size with a single expression.

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

My original answer follows:


I guess what you want is something like this:

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

Keep in mind that this doesn't tell the whole story. It is possible for multiple monitors to be staggered, or arranged in a nonrectangular shape. Therefore, it may be that not all of the space between (minx, miny) and (maxx, maxy) is visible.

EDIT:

I just realized that the code could be a bit simpler using 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);
ゝ杯具 2024-08-09 10:05:15

查看:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height

Check:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height
悟红尘 2024-08-09 10:05:15

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

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


}

To get the physical pixel size of the monitor you can use this.

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


}
稍尽春風 2024-08-09 10:05:15

这并没有回答问题,而只是增加了对窗口在所有屏幕中的点(位置)的额外了解。

使用下面的代码来查明某个点(例如窗口的最后已知位置)是否在整个桌面的范围内。如果没有,请将窗口的位置重置为默认的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;

This doesn't answer the question, but merely adds additional insight on a window's Point (location) within all the screens).

Use the code below to find out if a Point (e.g. last known Location of window) is within the bounds of the overall Desktop. If not, reset the window's Location to the default pBaseLoc;

Code does not account for the TaskBar or other Toolbars, yer on yer own there.

Example Use: Save the Window location to a database from station A. User logs into station B with 2 monitors and moves the window to the 2nd monitor, logs out saving new location. Back to station A and the window wouldn't be shown unless the above code is used.

My further resolve implemented saving the userID and station's IP (& winLoc) to database or local user prefs file for a given app, then load in user pref for that station & app.

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;
唯憾梦倾城 2024-08-09 10:05:15

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


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

这应该可以完成工作;)
问候 ...

I think the best way to get the "real" screen-size, is to get the values directly from the video-controller.


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

This should do the job ;)
Greetings ...

尬尬 2024-08-09 10:05:15

您可以使用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;

使用此代码,您将获得所有属性,例如 Width高度等。

You can use the Bounds of System.Drawing.

You can create a function like this

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

and than you can get the screen one, two, etc. in a variable like this:

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

then you can get the bounds of the screen:

System.Drawing.Rectangle screen1Bounds = screen1.Bounds;

With this code you will get all the properties like Width, Height, etc.

别挽留 2024-08-09 10:05:15

此方法通过使用“左”和“上”的最低值以及“右”和“下”的最高值来返回包含所有屏幕边界的矩形...

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

This method returns the rectangle that contains all of the screens' bounds by using the lowest values for Left and Top, and the highest values for Right and 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);
}
Oo萌小芽oO 2024-08-09 10:05:15

获取虚拟显示器的大小,无需任何依赖项

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

Get the Size of a virtual display without any dependencies

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);
}
幸福丶如此 2024-08-09 10:05:15

从 SM_XVIRTUALSCREEN 等派生的值是物理坐标,不等于控制面板中屏幕缩放 125%、150%、175% 时的逻辑坐标。

Values, derived from SM_XVIRTUALSCREEN and so on are physical coordinates and not equals to logical coordinates at screen scaling 125%, 150%, 175% in Control Panel.

机场等船 2024-08-09 10:05:15

您会发现许多窗口操作尚不可用或可能永远不可用。我在 PInvoke.User32 nuget 包方面取得了最大的成功。

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

You'll find that many window manipulations are not yet available or may not ever be made available. I've had the greatest success with PInvoke.User32 nuget package.

var screenX = PInvoke.User32.GetSystemMetrics(PInvoke.User32.SystemMetric.SM_CXSCREEN);
var screenY = PInvoke.User32.GetSystemMetrics(PInvoke.User32.SystemMetric.SM_CYSCREEN);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文