Laden...

Verwaltung von Fensterkoordinaten bei mehreren Bildschirmen unterschiedlicher Auflösungen

Erstellt von pollito vor einem Jahr Letzter Beitrag vor einem Jahr 893 Views
pollito Themenstarter:in
314 Beiträge seit 2010
vor einem Jahr
Verwaltung von Fensterkoordinaten bei mehreren Bildschirmen unterschiedlicher Auflösungen

Hallo,

ich brauche zunächst nur einen Hinweis, wie man dieses Thema am sinnvollsten angeht.

Ich habe eine Anwendung, die nicht viel mit .NET anfangen kann – maximal ein .NET-Programm ausführen. Diese Anwendung kann ihre eigenen Koordinaten nur dann richtig ermitteln, wenn Sie auf nur einem oder auf dem Hauptbildschirm ausgeführt wird. Allerdings läuft sie auch in Umgebungen mit mehreren Bildschirmen mit unterschiedlichen Auflösungen. Beispiel: Notebook mit 1920x1080 + 3840×2160 + 1920x1200 (Hauptbildschirm). Wie man hier sieht, eine bunte Mischung.

Nun geht es darum, die genaue Position des Programms zu ermitteln, wobei – wie bereits erwähnt – das Programm maximal in der Lage ist, ein .NET-Programm zu starten. Ich stelle mir vor, dem .NET-Programm wird die PID des rufenden Programms übergeben, um in Return-Value dessen Koordinaten zurück zu liefern. Vielleicht gibt es auch andere Möglichkeiten.

Als in erster Linie Backend-Entwickler habe ich mit dieser Thematik bisher nie was zu tun – daher wende ich mich an euch in der Hoffnung, einen Richtungsanstoß zu bekommen, bevor ich der falschen Fährte nachjage.

Danke un lG

René

René

pollito Themenstarter:in
314 Beiträge seit 2010
vor einem Jahr

Ich habe mir das Thema genauer angesehen. Dabei habe ich festgestellt, dass Windows immer dafür sorgt, dass die dpi-Zahl bei unterschiedlicher Skalierung gleich bleibt. Dazu ändert Windows die Anzahl der Pixel. Hier ein Beispiel von meinem Dell XPS mit 3840x2400 Pixeln: bei einer Skalierung von 175% rechnet Windows mit einer Bildschirmauflösung von 2194x1371. Das bedeutet, dass die Skalierung bei dieser Auflösung weiterhin 100% bei 96 dpi bleibt.

Trotzdem kommt unsere alte Software damit durcheinander. Ich vermute, dass sie selbst einen Skalierungsfaktor berechnet und sich dabei verrechnet. Eigentlich sollte die Software gar keine Skalierung berücksichtigen, solange Windows selbst eine Skalierung von 100% bei 96 dpi liefert.

Hier ist ein Stück Programmcode, der mir alles Wesentliche im Debugger zeigt (und bestätigt):


using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace multimonitor1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Abrufen der DPI-Skalierung und Skalierungsstufe jedes Bildschirms
            List<(float, float, int)> screenDpiScales = new List<(float, float, int)>();

            while (true)
            {
                foreach (Screen screen in Screen.AllScreens)
                {
                    using (var form = new Form() { Bounds = screen.Bounds, TopMost = true })
                    {
                        form.Show();

                        Graphics g = Graphics.FromHwnd(form.Handle);

                        float	dpiX	= g.DpiX;
                        float	dpiY	= g.DpiY;
                        int		scale	= (int) Math.Round(dpiX / 96.0 * 100);
                        
						screenDpiScales.Add((dpiX, dpiY, scale));
                        
						form.Hide();
                    }
                }

                // Ermitteln der Größe und Position der Anwendung
                int appLeft		= 0;
                int appTop		= 0;
                int appWidth	= 0;
                int appHeight	= 0;

                // Hier müssen die genauen Koordinaten der Anwendung in Bezug auf den Bildschirm ermittelt werden.
                // *** [English] The exact coordinates of the application in relation to the screen must be determined here. ***

                // Berechnen der Größe und Position der Anwendung auf jedem Bildschirm
                for (int i = 0; i < Screen.AllScreens.Length; i++)
                {
                    Screen screen = Screen.AllScreens[i];

                    (float, float, int) dpiScale = screenDpiScales[i];

                    Rectangle screenBounds = screen.Bounds;

                    float	dpiX	= dpiScale.Item1;
                    float	dpiY	= dpiScale.Item2;
                    int		scale	= dpiScale.Item3;

                    appLeft		= (int) (appLeft	* screenBounds.Width	/ (dpiX / 96.0 * scale));
                    appTop		= (int) (appTop		* screenBounds.Height	/ (dpiY / 96.0 * scale));
                    appWidth	= (int) (appWidth	* screenBounds.Width	/ (dpiX / 96.0 * scale));
                    appHeight	= (int) (appHeight	* screenBounds.Height	/ (dpiY / 96.0 * scale));

                    // Ausgabe der Größe und Position der Anwendung
                    Console.WriteLine($"Left:   {appLeft}");
                    Console.WriteLine($"Top:    {appTop}");
                    Console.WriteLine($"Width:  {appWidth}");
                    Console.WriteLine($"Height: {appHeight}");
                }

                Console.ReadLine();
            }
        }
    }
}

Damit ist der Fall für mich gelöst.

Vielen Dank und beste Grüße

René

René