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é
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é