Management of window coordinates and sizes for multiple screens of different resolutions
-
Hello, first of all I just need a hint on how to approach this topic in the most sensible way. I have an older application that can only determine its coordinates correctly when it is running on only one monitor. Now the application needs to run in environments with multiple screens with different resolutions. Example: Notebook with 1920x1080 + 3840×2160 + 1920x1200 (main screen). In addition, screens with a scaling other than just 100% can be run (e.g. 175%). As you can see here, a colourful mixture. I would like to determine the exact position and window size of the program. I am primarily a backend developer, so I have never had anything to do with this topic before. For this reason, I am turning to you in the hope of getting a push before I go the wrong direction. Many thanks in advance and best regards René
-
Hello, first of all I just need a hint on how to approach this topic in the most sensible way. I have an older application that can only determine its coordinates correctly when it is running on only one monitor. Now the application needs to run in environments with multiple screens with different resolutions. Example: Notebook with 1920x1080 + 3840×2160 + 1920x1200 (main screen). In addition, screens with a scaling other than just 100% can be run (e.g. 175%). As you can see here, a colourful mixture. I would like to determine the exact position and window size of the program. I am primarily a backend developer, so I have never had anything to do with this topic before. For this reason, I am turning to you in the hope of getting a push before I go the wrong direction. Many thanks in advance and best regards René
Hi René! You are going to have to give more detail as to what exactly you need help with - I have three monitors here, all different resolutions (1920x1080, 1080x1920, and 1280x1024 @ 100%), plus my Surface Go 2 (1920x1280 @ 150%) which I can write / test apps on (plus gawd knows what once the software is released) and generally it's not a problem. Why does you app need to "know where it is"? What is it doing that it needs this? What will it do with the info? What's the problem in finding out? My apps generally "remember" where they were, and restore their position on that particular system:
#region Event Handlers #region Form /// /// Restore size and location (if the user doesn't /// override it) /// /// /// private void FrmMain\_Load(object sender, EventArgs e) { if ((ModifierKeys & Keys.Shift) == 0) { this.LoadLocation(); } } /// /// Save the size and location (if the user doesn't /// override it) /// /// /// private void FrmMain\_FormClosing(object sender, FormClosingEventArgs e) { if ((ModifierKeys & Keys.Shift) == 0) { this.SaveLocation(); } }
Is part of my standard "new form" code, along with the support methods:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Data;
using System.Drawing;
using System.Diagnostics;namespace OneOffJobs
{
/// /// Provides the storage related code
///
public static class Storage
{
#region Constants
/// /// Restore command, used as a parameter to ShowWindow
///
private const int SW_RESTORE = 9;
#endregion#region DLL Imports // Sets the window to be foreground \[DllImport("User32")\] private static extern int SetForegroundWindow(IntPtr hwnd); // Activate or minimize a window \[DllImportAttribute("User32.DLL")\] priv
-
Hi René! You are going to have to give more detail as to what exactly you need help with - I have three monitors here, all different resolutions (1920x1080, 1080x1920, and 1280x1024 @ 100%), plus my Surface Go 2 (1920x1280 @ 150%) which I can write / test apps on (plus gawd knows what once the software is released) and generally it's not a problem. Why does you app need to "know where it is"? What is it doing that it needs this? What will it do with the info? What's the problem in finding out? My apps generally "remember" where they were, and restore their position on that particular system:
#region Event Handlers #region Form /// /// Restore size and location (if the user doesn't /// override it) /// /// /// private void FrmMain\_Load(object sender, EventArgs e) { if ((ModifierKeys & Keys.Shift) == 0) { this.LoadLocation(); } } /// /// Save the size and location (if the user doesn't /// override it) /// /// /// private void FrmMain\_FormClosing(object sender, FormClosingEventArgs e) { if ((ModifierKeys & Keys.Shift) == 0) { this.SaveLocation(); } }
Is part of my standard "new form" code, along with the support methods:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Data;
using System.Drawing;
using System.Diagnostics;namespace OneOffJobs
{
/// /// Provides the storage related code
///
public static class Storage
{
#region Constants
/// /// Restore command, used as a parameter to ShowWindow
///
private const int SW_RESTORE = 9;
#endregion#region DLL Imports // Sets the window to be foreground \[DllImport("User32")\] private static extern int SetForegroundWindow(IntPtr hwnd); // Activate or minimize a window \[DllImportAttribute("User32.DLL")\] priv
Hello "OriginalGriff" first of all, thank you for your post. With my poor English, I'll try to explain the problem a little better. We have an application that was programmed with SAL. SAL is a programming language developed by the Gupta company in the 90s. Gupta has a colourful history: first it was called Gupta, then Centura, later Unify and today it is owned by OpenText. As far as window management is concerned, SAL applications unfortunately only work correctly with one screen. Working with several different screens causes SAL applications major problems. Now SAL can integrate and use .NET DLLs developed with Framework 4.8. This is where I would like to start in order to take over the window management myself. I want to be able to determine and restore the window position and size of the SAL application on any screen, regardless of resolution and scaling. Thank you again and best regards René
-
Hello "OriginalGriff" first of all, thank you for your post. With my poor English, I'll try to explain the problem a little better. We have an application that was programmed with SAL. SAL is a programming language developed by the Gupta company in the 90s. Gupta has a colourful history: first it was called Gupta, then Centura, later Unify and today it is owned by OpenText. As far as window management is concerned, SAL applications unfortunately only work correctly with one screen. Working with several different screens causes SAL applications major problems. Now SAL can integrate and use .NET DLLs developed with Framework 4.8. This is where I would like to start in order to take over the window management myself. I want to be able to determine and restore the window position and size of the SAL application on any screen, regardless of resolution and scaling. Thank you again and best regards René
THe screen resolutions and DPI settings don't matter. All you need is the Top, Left, Width, and Height properties of the window. That's it. How you do that is a custom programming language nobody has ever heard of is entirely on you. You may be able to use .NET DLL's, but the windows are not being created by those DLL's, I assume? In that case, you're going to have to get the window handle of your apps main window somehow, then use that to call the GetWindowRect function[^] to get the screen coordinates and size rectangle.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave Kreskowiak -
Hello "OriginalGriff" first of all, thank you for your post. With my poor English, I'll try to explain the problem a little better. We have an application that was programmed with SAL. SAL is a programming language developed by the Gupta company in the 90s. Gupta has a colourful history: first it was called Gupta, then Centura, later Unify and today it is owned by OpenText. As far as window management is concerned, SAL applications unfortunately only work correctly with one screen. Working with several different screens causes SAL applications major problems. Now SAL can integrate and use .NET DLLs developed with Framework 4.8. This is where I would like to start in order to take over the window management myself. I want to be able to determine and restore the window position and size of the SAL application on any screen, regardless of resolution and scaling. Thank you again and best regards René
If it can "use and integrate .NET", you could bolt a WPF or Window Forms (or UWP?) "UI" onto SAL. Whether that's output only, can't tell from your post.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
-
Hello, first of all I just need a hint on how to approach this topic in the most sensible way. I have an older application that can only determine its coordinates correctly when it is running on only one monitor. Now the application needs to run in environments with multiple screens with different resolutions. Example: Notebook with 1920x1080 + 3840×2160 + 1920x1200 (main screen). In addition, screens with a scaling other than just 100% can be run (e.g. 175%). As you can see here, a colourful mixture. I would like to determine the exact position and window size of the program. I am primarily a backend developer, so I have never had anything to do with this topic before. For this reason, I am turning to you in the hope of getting a push before I go the wrong direction. Many thanks in advance and best regards René
-
THe screen resolutions and DPI settings don't matter. All you need is the Top, Left, Width, and Height properties of the window. That's it. How you do that is a custom programming language nobody has ever heard of is entirely on you. You may be able to use .NET DLL's, but the windows are not being created by those DLL's, I assume? In that case, you're going to have to get the window handle of your apps main window somehow, then use that to call the GetWindowRect function[^] to get the screen coordinates and size rectangle.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave Kreskowiak -
Why do screen resolutions and DPI settings not matter? The windows are not created by .NET. But I have a window handle that I could use.
Because you're going to get screen coordinates no matter what the resolution and DPI are.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave Kreskowiak -
Because you're going to get screen coordinates no matter what the resolution and DPI are.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave KreskowiakYes. I have looked into the subject more closely. Here I find that Windows always ensures that the dpi number remains the same with different scaling. To do this, Windows changes the number of pixels. Here is an example from my Dell XPS with 3840x2400 pixels: with a scaling of 175%, Windows calculates with a screen resolution of 2194x1371. This means that the scaling at this resolution remains 100% at 96 dpi. Nevertheless, our old software gets confused with this. I assume that it calculates the scaling factor internally incorrectly - actually, this should not be taken into account at all as long as Windows programmatically delivers a scaling of 100% at 96 dpi. Here is a programme code that shows me (and confirms) everything essential in the debugger:
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\];