C #: Vollständige Desktopgröße erhalten?

77

Wie finde ich die Größe des gesamten Desktops heraus? Nicht der "Arbeitsbereich" und nicht die "Bildschirmauflösung", die sich beide nur auf einen Bildschirm beziehen. Ich möchte die Gesamtbreite und -höhe des virtuellen Desktops herausfinden, von dem jeder Monitor nur einen Teil anzeigt.

Timwi
quelle
2
Möglicherweise hängt die "vollständige Desktopgröße" davon ab, wie die Bildschirme positioniert sind. Sie sind sich nicht sicher, wie Sie das berechnen sollen, aber Sie können trotzdem die Anzahl der Bildschirme und die Auflösung jedes Bildschirms mit System.Windows.Forms.Screen.AllScreens erfassen.
Havenard

Antworten:

129

Sie haben zwei Möglichkeiten:

  1. PresentationFramework.dll

    SystemParameters.VirtualScreenWidth   
    SystemParameters.VirtualScreenHeight
    
  2. System.Windows.Forms.dll

    SystemInformation.VirtualScreen.Width   
    SystemInformation.VirtualScreen.Height
    

Verwenden Sie die erste Option, wenn Sie eine WPF-Anwendung entwickeln.

Dennis
quelle
1
Weitere Antworten wie diese! Kurz, korrekt und ästhetisch ansprechend!
Bitterblue
Ich habe Szenarien gefunden, in denen diese Werte nur einen Bildschirm registrieren, wenn die Skalierung aktiviert ist. Möglicherweise hardwareabhängig, noch nicht sicher.
Kelly Elton
Das wurde wahrscheinlich schon 2011 gegeben. Multi-Desktop-Skalierung war keine Sache. @ KellyElton aktualisiert die Antwort, wenn Sie eine Lösung finden.
Dennis
1
Ich konnte keine Lösung dafür finden, ich denke, es ist ein Fehler. Ich verwende einen Blackweb BWA17HO002 USB3-zu-HDMI-Adapter mit einem Intel HD 520 (Laptop). Wenn die Anzeigeskalierung auf dem Laptop> 150% ist, geben diese Werte nur die Bildschirmabmessungen des Laptops zurück. Sobald ich die Skalierung entferne, registriert sie den zweiten Monitor.
Kelly Elton
31

Ich denke, es ist Zeit, diese Antwort mit einem kleinen LINQ auf den neuesten Stand zu bringen, was es einfach macht, die gesamte Desktopgröße mit einem einzigen Ausdruck zu erhalten.

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

Meine ursprüngliche Antwort lautet:


Ich denke, was Sie wollen, ist ungefähr so:

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

Denken Sie daran, dass dies nicht die ganze Geschichte erzählt. Es ist möglich, dass mehrere Monitore versetzt oder nicht rechteckig angeordnet sind. Daher kann es sein, dass nicht der gesamte Raum zwischen (minx, miny) und (maxx, maxy) sichtbar ist.

BEARBEITEN:

Ich habe gerade festgestellt, dass der Code mit etwas einfacher sein könnte 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);
P Papa
quelle
3
Ich bin ukrainischer Programmierer. Ich überprüfe, ob dieser Code von der Box aus funktioniert. Einfach kopieren und einfügen.
Vova Popov
15

Prüfen:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height
chris LB
quelle
7

Um die physische Pixelgröße des Monitors zu ermitteln, können Sie diese verwenden.

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


}
Andreas
quelle
Dies ist der erste, der die richtige Größe angibt, jedoch nur für einen einzelnen Monitor. 😑
BrainSlugs83
6

Dies beantwortet die Frage nicht, sondern fügt lediglich zusätzliche Einblicke in den Punkt (Position) eines Fensters in allen Bildschirmen hinzu.

Verwenden Sie den folgenden Code, um herauszufinden, ob sich ein Punkt (z. B. der letzte bekannte Standort des Fensters) innerhalb der Grenzen des gesamten Desktops befindet. Wenn nicht, setzen Sie den Speicherort des Fensters auf den Standardwert von pBaseLoc zurück .

Code berücksichtigt nicht die Taskleiste oder andere Symbolleisten, die Sie dort selbst besitzen.

Beispiel Verwendung: Speichern Sie die Fensterposition auf eine Datenbank von Station A . Der Benutzer meldet sich mit 2 Monitoren bei Station B an und verschiebt das Fenster zum 2. Monitor. Er meldet sich ab und speichert einen neuen Standort. Zurück zu Station A und das Fenster wird nur angezeigt, wenn der obige Code verwendet wird.

In meiner weiteren Lösung wurde das Speichern der Benutzer-ID und der IP-Adresse der Station (& winLoc) in einer Datenbank oder einer lokalen Benutzereinstellungsdatei für eine bestimmte App implementiert und anschließend die Benutzereinstellung für diese Station und App geladen.

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;
TechStuffBC
quelle
6
Wenn Sie wissen, dass dies die Frage nicht beantwortet, warum veröffentlichen Sie sie als Antwort auf die Frage? Sollte der erste Satz nicht eine Alarmglocke geläutet haben?
Timwi
1
Auf der anderen Seite ist dies genau das, wonach ich gesucht habe, als ich nach diesem Thema gesucht habe
Simon Gillbee
3

Ich denke, der beste Weg, um die "echte" Bildschirmgröße zu erhalten, besteht darin, die Werte direkt vom Videocontroller abzurufen.


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

Das sollte den Job machen;) Grüße ...

core.tweaks
quelle
1

Sie können die Grenzen von verwenden System.Drawing.

Sie können eine solche Funktion erstellen

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

und dann können Sie den Bildschirm eins, zwei usw. in einer Variablen wie dieser erhalten:

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

dann können Sie die Grenzen des Bildschirms erhalten:

System.Drawing.Rectangle screen1Bounds = screen1.Bounds;

Mit diesem Code erhalten Sie alle Eigenschaften wie Width, Heightusw.

JD - DC TECH
quelle
1

Diese Methode gibt das Rechteck zurück, das alle Bildschirmgrenzen enthält, indem die niedrigsten Werte für Links und Oben und die höchsten Werte für Rechts und Unten verwendet werden.

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);
}
Dynamichael
quelle
Bitte erklären Sie ein wenig.
Syeda Zunaira
Es durchläuft alle Bildschirme. Wenn die linke Kante kleiner als die Variable 'l' ist, setzt sie 'l' auf diesen neuen Wert. Wenn die untere Kante größer als 'b' ist, setzt sie diesen Wert. Das Endergebnis ist, dass l, t, r, b an den linken, oberen, rechten und unteren Rändern Ihres gesamten sichtbaren Desktops festgelegt sind.
Dynamichael
1

Ermitteln Sie die Größe einer virtuellen Anzeige ohne Abhängigkeiten

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);
}
Konstantin S.
quelle
Beste Antwort IMO, keine expliziten Abhängigkeiten.
Zintom