简体   繁体   English

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

[英]C#: Get complete desktop size?

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.我想找出每个显示器只显示一部分的虚拟桌面的总宽度和高度。

You have two options: 您有两种选择:

  1. PresentationFramework.dll PresentationFramework.dll

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

     SystemInformation.VirtualScreen.Width SystemInformation.VirtualScreen.Height 

Use the first option if you developing a WPF application. 如果您正在开发WPF应用程序,请使用第一个选项

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. 我认为现在是时候用一点LINQ把这个答案更新了,这样可以很容易地用一个表达式获得整个桌面大小。

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. 因此,可能不是(minx,miny)和(maxx,maxy)之间的所有空间都是可见的。

EDIT: 编辑:

I just realized that the code could be a bit simpler using Rectangle.Union : 我刚刚意识到使用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);

Check: 校验:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height

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 (eg last known Location of window) is within the bounds of the overall Desktop. 使用下面的代码来确定Point(例如,最后一个已知的窗口位置)是否在整个桌面的范围内。 If not, reset the window's Location to the default pBaseLoc ; 如果没有,将窗口的位置重置为默认的pBaseLoc ;

Code does not account for the TaskBar or other Toolbars, yer on yer own there. 代码不考虑TaskBar或其他工具栏,你自己在那里。

Example Use: Save the Window location to a database from station A . 示例使用:将窗口位置从站A保存到数据库。 User logs into station B with 2 monitors and moves the window to the 2nd monitor, logs out saving new location. 用户使用2个监视器登录到B站并将窗口移动到第2个监视器,注销保存新位置。 Back to station A and the window wouldn't be shown unless the above code is used. 返回站A ,除非使用上述代码,否则不会显示窗口。

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. 我进一步解决了将userID和工作站的IP(&winLoc)保存到给定应用程序的数据库或本地用户prefs文件,然后加载该工作站和应用程序的用户首选项。

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;

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


}

You can use the Bounds of System.Drawing . 您可以使用System.Drawing的Bounds。

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. 使用此代码,您将获得所有属性,如WidthHeight等。

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

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 ... 这应该做的工作;)问候......

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

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

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.我使用 PInvoke.User32 nuget 包取得了最大的成功。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM