web-dev-qa-db-fra.com

C #: Obtenir la taille complète du bureau?

Comment connaître la taille de tout le bureau? Pas la "zone de travail" et pas la "résolution de l'écran", qui font tous deux référence à un seul écran. Je souhaite connaître la largeur et la hauteur totales du bureau virtuel dont chaque moniteur n’affiche qu’une partie.

72
Timwi

Vous avez deux options:

  1. PresentationFramework.dll

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

    SystemInformation.VirtualScreen.Width   
    SystemInformation.VirtualScreen.Height
    

Utilisez l'option first si vous développez une application WPF. 

125
Dennis

Je pense qu'il est temps de mettre cette réponse à jour avec un peu LINQ, ce qui facilite l'obtention de la taille du bureau avec une seule expression.

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

Ma réponse originale suit:


Je suppose que ce que tu veux est quelque chose comme ça:

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

Gardez à l'esprit que cela ne raconte pas toute l'histoire. Il est possible que plusieurs moniteurs soient échelonnés ou agencés de manière non rectangulaire. Par conséquent, il se peut que tout l'espace entre (minx, miny) et (maxx, maxy) ne soit pas visible.

MODIFIER:

Je viens de me rendre compte que le code pourrait être un peu plus simple en utilisant 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
P Daddy

Vérifier:

SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height
16
chris LB

Vous pouvez utiliser ceci pour obtenir la taille de pixel physique du moniteur.

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


}
7
Andreas

Cela ne répond pas à la question, mais ajoute simplement des informations supplémentaires sur le point (emplacement) de la fenêtre dans tous les écrans.

Utilisez le code ci-dessous pour savoir si un point (par exemple, le dernier emplacement connu de la fenêtre) se trouve dans les limites de l'ensemble du bureau. Sinon, réinitialisez l'emplacement de la fenêtre sur la valeur par défaut pBaseLoc ;

Le code ne tient pas compte de la barre des tâches ni des autres barres d’outils, vous y êtes propre.

Exemple d'utilisation: enregistrez l'emplacement de la fenêtre dans une base de données à partir de station A . L'utilisateur se connecte à station B avec 2 moniteurs et déplace la fenêtre sur le deuxième moniteur, se déconnecte pour enregistrer le nouvel emplacement. Retour à station A et la fenêtre ne sera pas affichée à moins que le code ci-dessus ne soit utilisé.

Ma résolution supplémentaire implémentée consistait à enregistrer l'ID utilisateur et l'adresse IP de la station (& winLoc) dans la base de données ou le fichier de préférences d'utilisateur local pour une application donnée, puis de charger la préférence utilisateur pour cette station et cette application.

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;
6
TechStuffBC

Vous pouvez utiliser les limites de System.Drawing.

Vous pouvez créer une fonction comme celle-ci

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

et que vous pouvez obtenir l’écran un, deux, etc. dans une variable comme celle-ci:

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

alors vous pouvez obtenir les limites de l'écran:

System.Drawing.Rectangle screen1Bounds = screen1.Bounds;

Avec ce code, vous obtiendrez toutes les propriétés telles que Width, Height, etc.

1
JD - DC TECH

Cette méthode renvoie le rectangle contenant toutes les limites de l'écran en utilisant les valeurs les plus basses pour Left et Top, et les valeurs les plus hautes pour Right et 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);
}
1
dynamichael

Je pense que le meilleur moyen d’obtenir la "vraie" taille d’écran est d’obtenir les valeurs directement à partir du contrôleur vidéo.


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

Cela devrait faire le travail;) Salutations ...

1
core.tweaks

Obtenir la Taille d'un affichage virtuel sans aucune dépendance

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);
}
0
Konstantin S.