简体   繁体   中英

Actual resolution of secondary screen for custom DPI

I'm working on adaptation of application to custom DPI values (Windows scaling).

If I've understood correctly, scaling makes applications think, that resolution is smaller, than it actually is. For example, having 125% scale, if you have 1920x1080 resolution, actual size of maximized window will be 1536x864. And for sure, it may cause some problems, if you control some sizes and positions from code.

For now, I'm using next values for positioning etc:

  • SystemParameters.FullPrimaryScreenWidth and SystemParameters.FullPrimaryScreenHeight as "virtual" (scaled) resolution;
  • Screen.PrimaryScreen.WorkingArea.Width and Screen.PrimaryScreen.WorkingArea.Height for original resolution;

From this values, it is easy to get scaling value, which can be used in any positioning and sizing.

But all of this values are actually for primary screen. What if I will need to do positioning and sizing for secondary screen, which might have different actual (and, therefore, different "virtual") resolution?

For now I'm getting screen like this

var screen = Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(Application.Current.MainWindow).Handle);

Which allows me to get actual resolution, using WorkingArea rectangle. But what about "virtual" resolution? Is there analog of SystemParameters.FullPrimaryScreenWidth etc of any screen aside of primary?

PS. I know, that scale is shared, so by getting its value for primary screen, I can use it for any other screen, but I'd like to know answer, if there is direct variable to get this values, anyway.

You may use the following ratio

        // calculates text size in that main window (i.e. 100%, 125%,...)
        var ratio = Math.Max(Screen.PrimaryScreen.WorkingArea.Width / SystemParameters.PrimaryScreenWidth,
                        Screen.PrimaryScreen.WorkingArea.Height / SystemParameters.PrimaryScreenHeight);

For example, if you'd like to show maximized windows on all screen, you need to use the following rectangles (code is from App.xaml.cs):

        foreach (var screen in Screen.AllScreens)
        {
            var mainViewModel = container.Resolve<IMainWindowModel>();

            var window = new MainWindow(mainViewModel);
            if (screen.Primary)
                Current.MainWindow = window;

            window.Left = screen.WorkingArea.Left / ratio;
            window.Top = screen.WorkingArea.Top / ratio;
            window.Width = screen.WorkingArea.Width / ratio;
            window.Height = screen.WorkingArea.Height / ratio;
            window.Show();
            window.WindowState = WindowState.Maximized;
        }

In addition, you may take a look at my post https://ireznykov.com/2017/01/13/wpf-windows-on-two-screens/ , that refers to GitHub sample application that outputs maximized windows on all screens.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM