На C#: получить полный размер рабочего стола?



Как узнать размер всего рабочего стола? Не "рабочая область" и не "разрешение экрана", оба из которых относятся только к одному экрану. Я хочу узнать общую ширину и высоту виртуального рабочего стола, на котором каждый монитор показывает только часть.

1519   8  

8 ответов:

у вас есть два варианта:

  1. PresentationFramework.dll

    SystemParameters.VirtualScreenWidth   
    SystemParameters.VirtualScreenHeight
    

Я думаю, что пришло время обновить этот ответ с помощью небольшого LINQ, что позволяет легко получить весь размер рабочего стола с помощью одного выражения.

Console.WriteLine(
    Screen.AllScreens.Select(screen=>screen.Bounds)
    .Aggregate(Rectangle.Union)
    .Size
);

мой оригинальный ответ ниже:


Я думаю, что вы хотите, что-то вроде этого:

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

имейте в виду, что это не рассказать всю историю. Возможно для множественных мониторов быть расположенным в шахматном порядке, или аранжированным в нерегулярной форме. Поэтому может оказаться, что не все пространство между (minx, miny) и (maxx, maxy) видно.

EDIT:

Я просто понял, что код может быть немного проще, используя 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);

проверка:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height

чтобы получить физический размер пикселя монитора, вы можете использовать это.

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


}

Это не отвечает на вопрос, а просто добавляет дополнительную информацию о точке (местоположении) окна во всех экранах).

используйте приведенный ниже код, чтобы узнать, находится ли точка (например, последнее известное местоположение окна) в пределах общего рабочего стола. Если нет, сбросьте расположение окна по умолчанию pBaseLoc;

код не учитывает панель задач или другие панели инструментов, вы сами там.

пример использования: сохранить окно расположение в базе данных от станция A. Пользователь входит в станция B С 2 мониторами и перемещает окно на 2-й монитор, выходит из системы сохранения нового местоположения. Назад к станция A и окно не будет отображаться, если не используется приведенный выше код.

мое дальнейшее решение реализовано сохранение идентификатора пользователя и IP-адреса станции (&winLoc) в файл базы данных или локального пользователя prefs для данного приложения, а затем загрузите в user pref для этой станции и приложения.

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;

вы можете использовать границы System.Drawing.

вы можете создать такую функцию

public System.Windows.Form.Screen[] GetScreens(){
    Screen[] screens = Screen.AllScreens;
    return screens;
}

и чем вы можете получить один, два и т. д. в переменной, как это:

System.Windows.Form.Screen[] screens = func.GetScreens();
System.Windows.Form.Screen screen1 = screens[0];

тогда вы можете получить границы экрана:

System.Drawing.Rectangle screen1Bounds = screen1.Bounds;

С помощью этого кода Вы получите все свойства, такие как Width,Height и т. д.

Я думаю, что лучший способ получить "реальный" размер экрана - это получить значения непосредственно из видеоконтроллера.


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

Это должно сделать работу ;) Приветствия...

этот метод возвращает прямоугольник, содержащий все границы экранов, используя самые низкие значения для левого и Верхнего, а также самые высокие значения для правого и Нижнего...

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

Comments

    Ничего не найдено.