プライマリスクリーンのサイズの取り方(SystemParameters/Screen)

目次
https://tera1707.com/entry/2022/02/06/144447

やりたいこと

PCに接続しているディスプレイの大きさ、特にプライマリディスプレイ(1番のディスプレイ)の大きさを知りたい。

で、以前調べたWPFのAPIを使ったやり方以外にも、WinFormsのAPIを使ったやり方もあるっぽい。
どっちを使ってもよさそうだが、どう違うのか調べたい。

やったこと

単純に、両方使ってみて取れる値と動きを調べた。

使ったコード

WPF WPFのAPISystemParametersを使ったコード。

using System.Windows;

namespace WpfLibrary1
{
    public class Dispray
    {
        public static (double Width, double Height) GetPrimaryScreenSize()
        {
            return (SystemParameters.PrimaryScreenWidth, SystemParameters.PrimaryScreenHeight);
        }
    }
}

WinFormsのAPIScreenを使ったコード。

namespace WinFormsLibrary1
{
    public class Display
    {
        public static (double Width, double Height) GetPrimaryScreenSize()
        {
            return (Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        }
    }
}

それらを使ったWPFアプリ。

using System;
using System.Diagnostics;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_LocationChanged(object sender, EventArgs e)
        {
            var sizeWpf = WpfLibrary1.Dispray.GetPrimaryScreenSize();
            var sizeForm = WinFormsLibrary1.Display.GetPrimaryScreenSize();
            Debug.WriteLine($"({sizeWpf.Width}, {sizeWpf.Height}),({sizeForm.Width}, {sizeForm.Height})");
        }
    }
}

取れた値

1920*1080のディスプレイをプライマリディスプレイとして使って、どういう値が取れるか見た。

使ったAPI 150%時 125%時 100%時
SystemParameters 1280, 720
※1.5で割った値
1536、864
※1.25で割った値
1920, 1080
Screen 1920, 1080 1920, 1080 1920, 1080

SystemParametersのほうは、拡大率(dpi)の倍率で割った値が取れる。
Screenのほうは、拡大率がいくらでも、100%時の値が取れる。

ただし、上記の表は、アプリ起動前にdpiをセットしていた場合。

アプリ起動中に、 拡大率を変化させると Screenのほうが変な動きをする。

アプリ起動中に、

100%にセット→アプリ起動→150%にする
⇒100%のときは(1920, 1080)だが、150%になると (1280,720) になる。

150%にセット→アプリ起動→100%にする
⇒150%のときは(1920, 1080)だが、100%になると (2880, 1620) になる。

アプリ起動時の値に、変化した拡大率をかけてしまう様子。
(拡大率(dpi)の変化を想定しているようでしていないような動き??)

どちらがいいのか?

アプリの起動中にdpiを変えると、同じ倍率でも取れる値が変化してしまうという意味で、 Screenは使いづらいと感じた。

なので、個人的には、WPFSystemParameters がよいかと思う。

そのほか、思ったこと

ただ、今回のようなプライマリディスプレイの大きさを取りたい、とかいう場合、 その値を使って、アプリをディスプレイの真ん中に持っていきたい、とか、大きさを画面の大きさの何分の一かにしたい、とか、そういう場合じゃないかなと思うのだが、SystemParametersで取れる値は100%の時の幅を拡大率で割った値が取れるが、ウインドウの位置を指定できるAPIは、それをそのまま渡したらよいとは限らない気がする。
(100%のときの数字を渡さないといけないとか、100%のときの数字に拡大率を書けないといけないとか..具体的になんのAPIがそうか、は面倒だったので調べてないが)

SystemParametarsで取れた値を、どう使うかは、使うAPIに合わせて拡大率をかけたり割ったりして、いいようにすること。

参考

SystemParametersクラス

https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.systemparameters?view=windowsdesktop-6.0

Screenクラス

https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.screen?view=windowsdesktop-6.0

WPFAPIを使ったやり方

https://qiita.com/tera1707/items/15fd23cab641c75945b9