C#: Get complete desktop size?

C#.NetDesktopScreenScreen Resolution

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

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

Solution 3 - C#

Check:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height

Solution 4 - C#

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


}

Solution 5 - C#

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;

Solution 6 - C#

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 ...

Solution 7 - C#

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.

Solution 8 - C#

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

Solution 9 - C#

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

Solution 10 - C#

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.

Solution 11 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTimwiView Question on Stackoverflow
Solution 1 - C#DennisView Answer on Stackoverflow
Solution 2 - C#P DaddyView Answer on Stackoverflow
Solution 3 - C#chris LBView Answer on Stackoverflow
Solution 4 - C#AndreasView Answer on Stackoverflow
Solution 5 - C#TechStuffBCView Answer on Stackoverflow
Solution 6 - C#core.tweaksView Answer on Stackoverflow
Solution 7 - C#JD - DC TECHView Answer on Stackoverflow
Solution 8 - C#dynamichaelView Answer on Stackoverflow
Solution 9 - C#Konstantin S.View Answer on Stackoverflow
Solution 10 - C#Alexander AlexanderView Answer on Stackoverflow
Solution 11 - C#N-ateView Answer on Stackoverflow