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.
Solution 1:
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.
Solution 2:
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:
Check:
SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height
Solution 4:
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:
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;