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

Tim*_*mwi 74 .net c# desktop screen screen-resolution

如何找出整个桌面的大小?不是 "工作区"而不是 "屏幕分辨率",两者都只涉及一个屏幕.我想找出每个显示器只显示一部分的虚拟桌面的总宽度和高度.

Den*_*nis 125

您有两种选择:

  1. PresentationFramework.dll

    SystemParameters.VirtualScreenWidth   
    SystemParameters.VirtualScreenHeight
    
    Run Code Online (Sandbox Code Playgroud)
  2. System.Windows.Forms.dll中

    SystemInformation.VirtualScreen.Width   
    SystemInformation.VirtualScreen.Height
    
    Run Code Online (Sandbox Code Playgroud)

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


P D*_*ddy 28

我认为是时候用一点LINQ把这个答案更新了,这样就可以很容易地用一个表达式获得整个桌面大小.

Console.WriteLine(
    Screen.AllScreens.Select(screen=>screen.Bounds)
    .Aggregate(Rectangle.Union)
    .Size
);
Run Code Online (Sandbox Code Playgroud)

我的原始答案如下:


我想你想要的是这样的:

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);
Run Code Online (Sandbox Code Playgroud)

请记住,这并不能说明整个故事.多个监视器可以交错排列,或者以非矩形形状排列.因此,可能不是(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);
Run Code Online (Sandbox Code Playgroud)

  • 我是乌克兰程序员.我正在验证此代码是否正常工作.只需复制并粘贴即可. (3认同)

chr*_* LB 16

校验:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height
Run Code Online (Sandbox Code Playgroud)


小智 6

这并没有回答这个问题,只是增加了对所有屏幕内窗口点(位置)的额外见解.

使用下面的代码来确定Point(例如,最后一个已知的窗口位置)是否在整个桌面的范围内.如果没有,将窗口的位置重置为默认的pBaseLoc ;

代码不考虑TaskBar或其他工具栏,你自己在那里.

示例使用:将窗口位置从站A保存到数据库.用户使用2个监视器登录到B站并将窗口移动到第2个监视器,注销保存新位置.返回站A,除非使用上述代码,否则不会显示窗口.

我进一步解决了将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;
Run Code Online (Sandbox Code Playgroud)

  • 如果您*知道*这不回答问题,为什么要将其作为问题的答案发布?难道第一句不应该敲响警钟吗? (6认同)
  • 另一方面,这正是我在搜索这个主题时所寻找的 (2认同)

And*_*eas 6

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

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


}
Run Code Online (Sandbox Code Playgroud)