質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

2回答

10330閲覧

c#によるディスプレイ解像度ならびに、拡大倍率の取得

tommy_seiya

総合スコア32

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

1クリップ

投稿2022/05/20 22:25

c#の機能について質問です。
ディスプレイの拡大表示設定で設定する、拡大倍率を取得する方法はございますでしょうか。
windows10で言うところの、「拡大縮小とレイアウト」で設定する内容です。

直接的にこの設定値を取得できない場合、拡大倍率を上げる前のディスプレイ固有の縦横の画素数と、拡大倍率を上げた状態のディスプレイの縦横の画素数の両方を取得できれば間接的に拡大倍率を求められると思います。

例えば、
①フルHD(1920x1080)のディスプレイ使用時に、”System.Windows.Forms.Screen”クラスより縦横の画素数(解像度)を取得する場合、通常の拡大倍率(100%)時には、縦(横)の画素数は1080(1920)となり、
②拡大倍率を150%に上げた状態では、縦(横)の画素数は720(1280)となります。(ディスプレイ固有の画素数に、拡大倍率の逆数がかかっている値が取得できる)

以上より、①と②の両方の値を取得することができれば「1080/720=1.5(=拡大倍率150%)」が取得できます。
しかし実際には、拡大倍率を上げた状態では、①のようにディスプレイ固有の縦横の画素数を取得することができません。
上記の問題が生じるそもそもの原因と、解決策をご教示願います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2022/05/20 23:53 編集

[質問文に記載の内容を読み落としてのコメントだったので削除]
guest

回答2

0

自己解決

方針をガラリと変え、SetThreadDpiAwarenessContext()によりDPIAwareをPerMonitorとしたのち、
各フォーム画面のAutoScaleModeをNoneにし(もともとはFontとなっていた)、システム側での拡大処理を行わず、アプリケーション側で拡大処理に対応する方向としました。

質問内容の拡大倍率は以下のようにすると求めることができました。

----- Rectangle rect = new Rectangle(); rect = Screen.GetBounds(new Point(0,0)); int h1 = rect.Height; SetThreadDpiAwarenessContext(-3);//DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE rect = Screen.GetBounds(new Point(0,0)); int h2 = rect.Height; //拡大倍率 double ratio = (double)h2 / h1; -----

SetThreadDpiAwarenessContext()によりレイアウトの乱れが生じていた点が問題でしたが、
フォームの拡大処理をアプリケーション側で行う方向に切り替え、対応しました。

投稿2022/05/24 12:58

tommy_seiya

総合スコア32

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ディスプレイの拡大表示設定で設定する、拡大倍率を取得する方法はございますでしょうか。

Win32API を使用する方法になります。

DPI-related APIs and registry settings

Primary display DPI scale factor
を参考にすると
SetProcessDPIAware()
GetDeviceCaps()
を使って Table 2 DPI Scale Factors の表から DPI を 96 で割れば拡大率を求められるようです。
(私は C++ アプリで拡大率を取得する場合にこの方法を使用しています)
LOGPIXELSX と LOGPIXELSY の値は以下で確認しています。
https://referencesource.microsoft.com/

C#

1using System.Runtime.InteropServices; 2 3... 4 const int LOGPIXELSX = 88; 5 const int LOGPIXELSY = 90; 6 [DllImport("user32.dll")] 7 extern static bool SetProcessDPIAware(); 8 [DllImport("user32.dll")] 9 extern static IntPtr GetDC(IntPtr hwnd); 10 [DllImport("gdi32.dll")] 11 extern static int GetDeviceCaps(IntPtr hdc, int index); 12 [DllImport("user32.dll")] 13 extern static int ReleaseDC(IntPtr hwnd, IntPtr hdc); 14 15 private void button1_Click(object sender, EventArgs e) { 16 SetProcessDPIAware(); 17 var hdc = GetDC(IntPtr.Zero); 18 var scaleFactorX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0; 19 var scaleFactorY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0; 20 ReleaseDC(IntPtr.Zero, hdc); 21 button1.Text = scaleFactorX.ToString(); 22 } 23...

投稿2022/05/21 02:04

lehshell

総合スコア1147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tommy_seiya

2022/05/21 10:46

SetProcessDPIAware()に関する記述は他サイトで目にし、試しておりました。 Windowsフォームの開発で質問内容に挙げた課題に直面しているのですが、SetProcessDPIAware()を呼び出すことで、Formのレイアウトが崩れてしまうのです。 SetProcessDPIAware()によってapp.manifestファイルなどによって、アプリケーションがDPIAwareであることを宣言すること(?)ができるようですが、拡大率の取得後は、SetProcessDPIAware()呼び出し前の状態に戻したいのですが、このメソッドによってDPIAwareの「切り替え」は可能なのでしょうか…
lehshell

2022/05/21 12:21

> Formのレイアウトが崩れてしまうのです。 拡大倍率を取得して起動側に返すコンソールアプリにして、Form アプリからコンソールアプリの終了値として取得するのはどうでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問