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.
-
2Maybe the "complete desktop size" will depend on how the screens are positioned. Not sure how to calculate that, but you still can catch the number of screens and resolution of each screen with System.Windows.Forms.Screen.AllScreens. – Havenard Aug 22 '09 at 22:53
11 Answers
You have two options:
PresentationFramework.dll
SystemParameters.VirtualScreenWidth SystemParameters.VirtualScreenHeight
System.Windows.Forms.dll
SystemInformation.VirtualScreen.Width SystemInformation.VirtualScreen.Height
Use the first option if you developing a WPF application.

- 20,275
- 4
- 64
- 80
-
1More of answers like this! Short, correct and esthetically pleasing! – Bitterblue Feb 17 '17 at 12:03
-
I've found scenarios where these values will only register one screen if scaling is enabled. May be hardware dependent, not sure yet. – Kelly Elton May 07 '20 at 06:35
-
That's likely given back in 2011 multi-desktop scaling wasn't a thing. @KellyElton update the answer if you find a fix. – Dennis May 08 '20 at 03:53
-
1I wasn't able to find a solution to this, I think it's a bug. I'm using a Blackweb BWA17HO002 usb3 to hdmi adapter, with an intel HD 520 (laptop). When I have the display scaling > 150% on the laptop, these values will only return the laptop screen dimensions. Once I remove the scaling, then it registers the second monitor. – Kelly Elton May 11 '20 at 23:29
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);

- 28,912
- 9
- 68
- 92
-
3I'm Ukrainian programmer. I'm verifying that this code is working from the box. Just copy and paste. – Vova Popov Jun 24 '13 at 15:50
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);
}
}

- 3,843
- 3
- 40
- 53
-
This one is the first one that reports the correct size, but only for a single monitor. – BrainSlugs83 Aug 01 '19 at 23:01
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;

- 76,112
- 22
- 180
- 195

- 121
- 2
- 3
-
6If you *know* that this doesn’t answer the question, why are you posting it as an answer to the question? Shouldn’t the first sentence have rung an alarm bell? – Timwi Jul 30 '10 at 08:11
-
2On this other hand, this is exactly what I was looking for when I came searching on this topic – Simon Gillbee Dec 01 '16 at 20:13
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 ...

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

- 3,071
- 5
- 30
- 51

- 1,193
- 9
- 13
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);
}

- 807
- 9
- 9
-
-
It loops through all the screens. If the left edge is lesser than the variable 'l' it sets 'l' to this new value, if the bottom edge is greater than 'b' then it sets that. The end result is l, t, r, b are set to the left, top, right, and bottom edges of your entire visible desktop. – dynamichael Feb 10 '18 at 06:26
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);
}

- 1,307
- 14
- 19
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.
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);

- 6,051
- 2
- 40
- 48