DPI制御の問題

この章では、従来版VBVBAなどとの違いで懸案事項に揚がったことなどを説明します。
DPI制御とは?   文字サイズ変更

この画像は、最近の「高DPIノートPC」のディスプレイ設定の状態で「150%」が推奨であり、デフォルトの設定になっているものです。
12~13インチクラスでフルHDのディスプレイを搭載するようなノートPCが一般化しているのが現状になってきています。
このサイズでフルHDとなると「100%」では文字が小さすぎて読めないことからこのような設定になっています。
この「150%(推奨)」となっているのが「DPI制御」であり、通常のデスクトップPCであれば「100%」なのです。

この「DPI制御」は近年出てきたものではなく、WindowsXPでも搭載されていて、デフォルトは全て「100%」だったのですが、 細かい文字が見にくくなった年輩者や視力が弱い人がこれを変更して用いることが一部に見られた程度でした。
しかし、近年では「高DPIノートPC」が当たり前のように出荷される時代になっており、プログラム側でもこの対応を行なう必要が出てきています。

文字サイズ(DPI値)を「100%」から変えると何が問題なのか
結果的に言うとこの問題はWindowsのバージョンによって動作が異なります。
まずはWindows7で標準の「100%(96DPI)」環境で表示させます。当然、これは正常な状態です。
ここからの4つの画像は標準の「100%(96DPI)」で表示できるデスクトップPCでの画像になります。

DPI制御
(画像をクリックすると、このページのサンプルがダウンロードできます)

次は上記のフォームをWindows7の「125%(120DPI)」の環境で表示させてみます。

DPI制御

このようにフォームや各コントロールの大きさが変わらないのに、文字だけ大きくなってしまうので、文字列がコントロールの表示域に収まらない状態になってしまいます。 「150%(144DPI)」だったら、もっととんでもない状態になります。

ここでこのページの下方のフォームやコントロールの独自サイズ制御の対応を行なうと、

DPI制御

このようにフォームや各コントロールが125%に拡大されて正常に表示されます。
このページのサンプルでは、単にDPI制御の違いだけではなく、「配属情報」で使用しているグループボックスを独自コントロールに変更しています。 このグループボックスを独自コントロールは上の画像のような標準のグループボックスが「境界線」が薄くて見にくいために作成しているものです。

一方、これはWindows10の「150%(144DPI)」の状態です。

DPI制御

デスクトップPCと同じ拡大率での画面コピーで比較しているのでやや「ボケ」た表示になっていますが、 実際は小さい画面のノートPCの精細スクリーン上の表示なのでこんなに大きい表示にはなりません。

DPI制御

見た目の大きさはこの程度の感じです。ややボケた表示ですが、文字が読めないようなことにはなりません。(この画像は縮小しています)
最近の小型で高精細度のノートPCはこの状態がデフォルトになっています。

これは上記の「独自サイズ制御」ではなく、Windows8.1以降で行なわれる「DPI仮想化」による制御で、 プログラム側には「100%(96DPI)」で通知されてくるため「独自サイズ制御」は動作していません。

この「DPI仮想化」は非常に良くできていて、このノートPCに「100%(96DPI)」で表示できる外部ディスプレィを接続させた場合、 ノートPC側と外部ディスプレィの間でウィンドウを移動させると、ウィンドウサイズ(DPI設定)が切り替わるのが判ります。

Windows7はスクリーンごとのDPI設定には対応していなかったため、文字サイズを拡大するとウィンドウが拡大されたままスクリーン間を移動する状態でしたが、 Windows8.1以降では、スクリーンの境界を越えるタイミングで移動先スクリーンのDPI設定に合わせて切り替わります。

Windows側に「独自サイズ制御ができるのだからDPI仮想化を働かせるな」という指定はできるようなのですが、 スクリーンごとのDPI制御にプログラム側で対応するのはかなり困難です。 また、DPI制御の問題はウィンドウ・コントロールのサイズ制御だけではなく、ウィンドウ(フォーム)の出現位置制御にも関わります。
当サイトの「ダウンロード」にあるVB.NETで作成したフリーソフトはほとんどが小さいウィンドウサイズのもので、 スクリーンの隅で利用できるものなので、次回の起動時に前回閉じた位置に表示させるように閉じた位置を保持させて再現させるように対応させていますが、 この時にスクリーンの構成や各スクリーンのDPI設定がが前回と同じか、 スクリーンごとに異なるDPI設定である上での閉じた位置の保持・再現方法はどうするかなどまで独自にやることが可能なのか、 これによる作成プログラム側の負荷がどのようなのかまで考えると「DPI仮想化」に乗ってしまう方が良いと考えるようになりました。

ですから、ここではWindows8.1より前のWindowsで起動された時の対応としての「独自サイズ制御」を紹介します。 いずれ将来Windows8.1より前のWindowsが根絶すれば要らなくなるというものになります。

それではソースコードです。
上記のフォ-ム側のソースコードで、この「DPI制御」に関するものは、フォーム初期化(New)の最後の1行だけです。

    '***********************************************************************************************
    ' ■■■ 初期化 ■■■
    '***********************************************************************************************
    '* 処理名 :New
    '* 機能  :初期化
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = データベースI/Oクラス(Object)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2017年02月05日
    '* 作成者 :井上 治
    '* 更新日 :2018年12月01日
    '* 更新者 :井上 治
    '* 機能説明:
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub New(ByRef objAboutMDB As clsAboutMDB3)
        '-------------------------------------------------------------------------------------------
        ' ※Windowsフォームデザイナ初期化(必須)
        Call InitializeComponent()
        ' フォームデザイナモード時は以下をスキップする
        If Me.DesignMode Then Exit Sub
        '-------------------------------------------------------------------------------------------
        g_objAboutMDB = objAboutMDB                         ' データベースI/Oクラス(MDB用)
        '-------------------------------------------------------------------------------------------
        ' 未更新終了チェック関連クラスの初期化
        g_objCheckNotUpdate = New clsCheckNotUpdate2(Me)
        '-------------------------------------------------------------------------------------------
        ' DPI値によるフォーム/コントロールの位置・サイズ調整
        Call GP_AdjustFormSizeByDpi(Me)
    End Sub
添付のサンプルでは一覧画面と詳細画面がありますが、一覧画面の方は「GP_AdjustFormSizeByDpi3」が呼び出されており、 詳細画面の方は「GP_AdjustFormSizeByDpi」が呼び出されます。
下記の「modFormDpiMgr3」を見てもらえば解るのですが、実際の「DPI制御」の起動部分は「GP_AdjustFormSizeByDpi3」側に記述されていて、 「GP_AdjustFormSizeByDpi」からは先頭で「GP_AdjustFormSizeByDpi3」が呼び出されています。 「GP_AdjustFormSizeByDpi」の方はそれ以外に各入力コントロールのEnterイベント等で入力文字列を全選択させる機能を実装させています。
一覧画面はテキストボックスなどの入力コントロールがないので「GP_AdjustFormSizeByDpi3」の方を呼び出しています。

では、「DPI制御」の中核部分である「modFormDpiMgr3」です。
モジュールファイル名は「modFormDpiMgr3」なのですが、内部名は「modFormDpiMgr1」です。 この用途のモジュールはプロジェクトに複数を持ち込むことはないので内部名を同じにしていますが、末尾の番号は作成歴による世代を現わしています。
上で説明した「GP_AdjustFormSizeByDpi」「GP_AdjustFormSizeByDpi3」はこのモジュールの先頭2つのプロシージャになります。
それ以降は一部に入力文字列全選択のイベントプロシージャがありますが、それらを含めてソースコード上では外部から呼び出されることはありません。
モジュールレベル変数を見て判るように「利用者DPIによる拡大率」は「1.0」であって、 呼び出される時のDPI96DPIを超えてこない限りこの制御は働きません。 Windows8.1以降では「DPI仮想化」が96DPIしか返さなくなるので、 この長い記述の大半は不要になってしまうことになります。

'***************************************************************************************************
'     フォーム用DPI調整機能共通プロシージャ                 modFormDpiMgr3(Module)
'
'   作成者:井上治  URL:https://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
' 変更日付 Rev     変更履歴内容-------------------------------------------------------------------->
' 14/08/27(1.8.0.0)新規作成
' 14/11/07(1.8.2.4)GP_AdjustFormSizeByDpiSubでTabControlのタイトル部のサイズを調整を追加
' 14/11/07(1.8.2.4)フォームやパネルの最小・最大サイズの対応を追加
' 15/08/25(1.10.1.0)GroupBoxのBorderColor調整を追加
' 17/09/27(1.11.0.0)入力コントロールの文字列全選択対応をEnter⇒GotFocusに変更する対応
' 18/11/29(1.12.0.0)不要なモジュール変数を削除⇒モジュール名変更
'***************************************************************************************************
Module modFormDpiMgr1
    '-----------------------------------------------------------------------------------------------
    ' 標準DPI設定
    Private Const g_cnsStandardDPI As Single = 96                   ' 標準DPI値
    ' 利用者DPIによる拡大率
    Friend g_sngMagnifyingPowerX As Single = 1.0F                   ' DPI拡大率(横)
    Friend g_sngMagnifyingPowerY As Single = 1.0F                   ' DPI拡大率(縦)
    '対象フォーム
    Private g_objForm As Object = Nothing                           ' 親フォーム

    '***********************************************************************************************
    ' ■■■ サブ処理 ■■■
    '***********************************************************************************************
    '* 処理名 :GP_AdjustFormSizeByDpi
    '* 機能  :DPI値によるフォーム/コントロールの位置・サイズ調整
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 対象フォーム(Form)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年08月27日
    '* 作成者 :井上 治
    '* 更新日 :2018年11月29日
    '* 更新者 :井上 治
    '* 機能説明:入力系コントロールがある場合に使用(Enterイベントで全選択にする対応を含む)
    '* 注意事項:DataGridViewの列幅調整は本処理の後で行なうこと
    '***********************************************************************************************
    Friend Sub GP_AdjustFormSizeByDpi(ByVal objForm As Object)
        '-------------------------------------------------------------------------------------------
        ' DPI値によるフォーム/コントロールの位置・サイズ調整
        Call GP_AdjustFormSizeByDpi3(objForm)
        '-------------------------------------------------------------------------------------------
        ' 入力コントロールの文字列を全選択状態にする(再帰処理)
        Call GP_EntryControlsAddHandlerSub(g_objForm)
    End Sub

    '***********************************************************************************************
    '* 処理名 :GP_AdjustFormSizeByDpi3
    '* 機能  :DPI値によるフォーム/コントロールの位置・サイズ調整
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 対象フォーム(Form)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年08月27日
    '* 作成者 :井上 治
    '* 更新日 :2018年11月29日
    '* 更新者 :井上 治
    '* 機能説明:入力系コントロールがない場合に使用
    '* 注意事項:DataGridViewの列幅調整は本処理の後で行なうこと
    '***********************************************************************************************
    Friend Sub GP_AdjustFormSizeByDpi3(ByVal objForm As Object)
        '-------------------------------------------------------------------------------------------
        g_objForm = objForm
        ' 利用者DPI設定の確認
        Dim sngUserDpiX As Single = objForm.CreateGraphics.DpiX     ' DPI値(横)
        Dim sngUserDpiY As Single = objForm.CreateGraphics.DpiY     ' DPI値(縦)
        '-------------------------------------------------------------------------------------------
        ' 標準(96DPI)でない場合はフォント調整を行なう
        If ((sngUserDpiX > g_cnsStandardDPI) OrElse (sngUserDpiY > g_cnsStandardDPI)) Then
            ' 利用者DPIによる拡大率の算出
            g_sngMagnifyingPowerX = sngUserDpiX / g_cnsStandardDPI
            g_sngMagnifyingPowerY = sngUserDpiY / g_cnsStandardDPI
            ' フォームのサイズを調整
            With CType(g_objForm, Form)
                ' 最大サイズの調整
                .MaximumSize = FP_GetMagnifyingSize(.MaximumSize)
                ' フォームのサイズ調整
                .Size = FP_GetMagnifyingSize(.Size)
                ' 最小サイズの調整
                .MinimumSize = FP_GetMagnifyingSize(.MinimumSize)
            End With
            ' 各コントロールの位置・サイズ調整(再帰処理)
            Call GP_AdjustFormSizeByDpiSub(g_objForm)
        End If
    End Sub

    '***********************************************************************************************
    ' ■■■ 共通サブ処理 ■■■
    '***********************************************************************************************
    '* 処理名 :GP_AdjustFormSizeByDpiSub
    '* 機能  :DPI値によるコントロールの位置・サイズ調整(サブ処理)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 所属するコンテナ(Object)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年08月26日
    '* 作成者 :井上 治
    '* 更新日 :2015年08月25日
    '* 更新者 :井上 治
    '* 機能説明:コンテナ上の各コントロールの位置・サイズ調整
    '* 注意事項:本処理は再帰動作
    '***********************************************************************************************
    Private Sub GP_AdjustFormSizeByDpiSub(ByVal objContainer As Object)
        '-------------------------------------------------------------------------------------------
        ' コントロールの種別によって処理を切り分け
        For Each objCont As Control In objContainer.Controls
            ' コンテナを優先
            If TypeOf objCont Is TabControl Then
                '-----------------------------------------------------------------------------------
                ' タブコントロール
                With CType(objCont, TabControl)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                    ' 各タブページのタイトル部のサイズを調整
                    .ItemSize = FP_GetMagnifyingSize(.ItemSize)
                End With
                ' コンテナ時は再帰呼び出し
                Call GP_AdjustFormSizeByDpiSub(objCont)

            ElseIf TypeOf objCont Is TabPage Then
                '-----------------------------------------------------------------------------------
                ' タブページ(Dockプロパティ無し=再帰のみ)
                ' コンテナ時は再帰呼び出し
                Call GP_AdjustFormSizeByDpiSub(objCont)

            ElseIf TypeOf objCont Is Panel Then
                '-----------------------------------------------------------------------------------
                ' パネル
                With CType(objCont, Panel)
                    ' 最大サイズの調整
                    .MaximumSize = FP_GetMagnifyingSize(.MaximumSize)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                    ' 最小サイズの調整
                    .MinimumSize = FP_GetMagnifyingSize(.MinimumSize)
                End With
                ' コンテナ時は再帰呼び出し
                Call GP_AdjustFormSizeByDpiSub(objCont)

            ElseIf TypeOf objCont Is GroupBox Then
                '-----------------------------------------------------------------------------------
                ' グループボックス
                With CType(objCont, GroupBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With
                ' コンテナ時は再帰呼び出し
                Call GP_AdjustFormSizeByDpiSub(objCont)

            ElseIf TypeOf objCont Is TableLayoutPanel Then
                '-----------------------------------------------------------------------------------
                ' タブレイアウトパネル
                With CType(objCont, TableLayoutPanel)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With
                ' コンテナ時は再帰呼び出し
                Call GP_AdjustFormSizeByDpiSub(objCont)

            ElseIf TypeOf objCont Is FlowLayoutPanel Then
                '-----------------------------------------------------------------------------------
                ' フローレイアウトパネル
                With CType(objCont, FlowLayoutPanel)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With
                ' コンテナ時は再帰呼び出し
                Call GP_AdjustFormSizeByDpiSub(objCont)

            ElseIf TypeOf objCont Is SplitContainer Then
                '-----------------------------------------------------------------------------------
                ' スプリットコンテナ
                With CType(objCont, SplitContainer)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With
                ' コンテナ時は再帰呼び出し
                Call GP_AdjustFormSizeByDpiSub(objCont)

            ElseIf TypeOf objCont Is UserControl Then
                '-----------------------------------------------------------------------------------
                ' ユーザーコントロール
                With CType(objCont, UserControl)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With
                ' コンテナ時は再帰呼び出し
                Call GP_AdjustFormSizeByDpiSub(objCont)


                '===================================================================================
                ' 以下は非コンテナ
            ElseIf TypeOf objCont Is TextBox Then
                '-----------------------------------------------------------------------------------
                ' テキストボックス(高さの調整は複数行仕様時のみ)
                With CType(objCont, TextBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Width = .Width * g_sngMagnifyingPowerX
                            If .Multiline Then
                                .Height = .Height * g_sngMagnifyingPowerY
                            End If
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            If .Multiline Then
                                .Height = .Height * g_sngMagnifyingPowerY
                            End If
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is Label Then
                '-----------------------------------------------------------------------------------
                ' ラベル(AutoSize時は位置のみ)
                With CType(objCont, Label)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            If Not .AutoSize Then
                                .Size = FP_GetMagnifyingSize(.Size)
                                Select Case g_sngMagnifyingPowerX
                                    Case 1.25F
                                        If .Height = 25 Then .Height = 24
                                    Case 1.5F
                                        If .Height = 30 Then .Height = 27
                                End Select
                            End If
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            If Not .AutoSize Then
                                .Height = .Height * g_sngMagnifyingPowerY
                                Select Case g_sngMagnifyingPowerX
                                    Case 1.25F
                                        If .Height = 25 Then .Height = 24
                                    Case 1.5F
                                        If .Height = 30 Then .Height = 27
                                End Select
                            End If
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            If Not .AutoSize Then
                                .Width = .Width * g_sngMagnifyingPowerX
                            End If
                    End Select
                End With

            ElseIf TypeOf objCont Is ComboBox Then
                '-----------------------------------------------------------------------------------
                ' コンボボックス(幅のみ)
                With CType(objCont, ComboBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Width = .Width * g_sngMagnifyingPowerX
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is DataGridView Then
                '-----------------------------------------------------------------------------------
                ' DataGridView
                Dim COL As Integer = 0
                With CType(objCont, DataGridView)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                    ' DataGridViewは列幅も調整
                    Do While COL < .Columns.Count
                        With .Columns(COL)
                            .Width = .Width * g_sngMagnifyingPowerX
                        End With
                        COL += 1
                    Loop
                    .ColumnHeadersHeight = .ColumnHeadersHeight * g_sngMagnifyingPowerY
                    .RowHeadersWidth = .RowHeadersWidth * g_sngMagnifyingPowerX
                    If .Rows.Count <> 0 Then
                        Dim GYO As Integer = 0
                        Do While GYO < .Rows.Count
                            With .Rows(GYO)
                                .Height = .Height * g_sngMagnifyingPowerY
                            End With
                            GYO += 1
                        Loop
                    End If
                End With

            ElseIf TypeOf objCont Is MaskedTextBox Then
                '-----------------------------------------------------------------------------------
                ' マスクドテキストボックス(幅のみ)
                With CType(objCont, MaskedTextBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Width = .Width * g_sngMagnifyingPowerX
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is CheckBox Then
                '-----------------------------------------------------------------------------------
                ' チェックボックス(AutoSize時は位置のみ)
                With CType(objCont, CheckBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            If Not .AutoSize Then
                                .Size = FP_GetMagnifyingSize(.Size)
                            End If
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            If Not .AutoSize Then
                                .Height = .Height * g_sngMagnifyingPowerY
                            End If
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            If Not .AutoSize Then
                                .Width = .Width * g_sngMagnifyingPowerX
                            End If
                    End Select
                End With

            ElseIf TypeOf objCont Is Button Then
                '-----------------------------------------------------------------------------------
                ' ボタン
                With CType(objCont, Button)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is RadioButton Then
                '-----------------------------------------------------------------------------------
                ' ラジオボタン(AutoSize時は位置のみ)
                With CType(objCont, RadioButton)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            If Not .AutoSize Then
                                .Size = FP_GetMagnifyingSize(.Size)
                            End If
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            If Not .AutoSize Then
                                .Height = .Height * g_sngMagnifyingPowerY
                            End If
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            If Not .AutoSize Then
                                .Width = .Width * g_sngMagnifyingPowerX
                            End If
                    End Select
                End With

            ElseIf TypeOf objCont Is ListBox Then
                '-----------------------------------------------------------------------------------
                ' リストボックス
                With CType(objCont, ListBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is LinkLabel Then
                '-----------------------------------------------------------------------------------
                ' リンクラベル(AutoSize時は位置のみ)
                With CType(objCont, LinkLabel)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            If Not .AutoSize Then
                                .Size = FP_GetMagnifyingSize(.Size)
                            End If
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            If Not .AutoSize Then
                                .Height = .Height * g_sngMagnifyingPowerY
                            End If
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            If Not .AutoSize Then
                                .Width = .Width * g_sngMagnifyingPowerX
                            End If
                    End Select
                End With

            ElseIf TypeOf objCont Is NumericUpDown Then
                '-----------------------------------------------------------------------------------
                ' NumericUpDown(幅のみ)
                With CType(objCont, NumericUpDown)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Width = .Width * g_sngMagnifyingPowerX
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is RichTextBox Then
                '-----------------------------------------------------------------------------------
                ' RichTextBox
                With CType(objCont, RichTextBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is CheckedListBox Then
                '-----------------------------------------------------------------------------------
                ' CheckedListBox
                With CType(objCont, CheckedListBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is DateTimePicker Then
                '-----------------------------------------------------------------------------------
                ' DateTimePicker(幅のみ)
                With CType(objCont, DateTimePicker)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Width = .Width * g_sngMagnifyingPowerX
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is ListView Then
                '-----------------------------------------------------------------------------------
                ' ListView
                With CType(objCont, ListView)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is TreeView Then
                '-----------------------------------------------------------------------------------
                ' TreeView
                With CType(objCont, TreeView)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is MonthCalendar Then
                '-----------------------------------------------------------------------------------
                ' MonthCalendar
                With CType(objCont, MonthCalendar)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is ProgressBar Then
                '-----------------------------------------------------------------------------------
                ' ProgressBar
                With CType(objCont, ProgressBar)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is WebBrowser Then
                '-----------------------------------------------------------------------------------
                ' WebBrowser
                With CType(objCont, WebBrowser)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is PictureBox Then
                '-----------------------------------------------------------------------------------
                ' PictureBox
                With CType(objCont, PictureBox)
                    ' Dock=Fill以外を調整
                    Select Case .Dock
                        Case DockStyle.None
                            ' 位置・サイズを調整
                            .Left = .Left * g_sngMagnifyingPowerX
                            .Top = .Top * g_sngMagnifyingPowerY
                            .Size = FP_GetMagnifyingSize(.Size)
                        Case DockStyle.Top, DockStyle.Bottom
                            ' 高さのみ調整
                            .Height = .Height * g_sngMagnifyingPowerY
                        Case DockStyle.Left, DockStyle.Right
                            ' 幅のみ調整
                            .Width = .Width * g_sngMagnifyingPowerX
                    End Select
                End With

            ElseIf TypeOf objCont Is MenuStrip Then
                '-----------------------------------------------------------------------------------
                ' MenuStrip
                With CType(objCont, MenuStrip)
                    .Height = .Height * g_sngMagnifyingPowerY
                End With

            ElseIf TypeOf objCont Is StatusStrip Then
                '-----------------------------------------------------------------------------------
                ' StatusStrip
                With CType(objCont, StatusStrip)
                    .Height = .Height * g_sngMagnifyingPowerY
                End With

            Else
                '-----------------------------------------------------------------------------------
                ' その他
                Console.WriteLine("GP_AdjustFormSizeByDpiSubタイプ不明コントロール:" & _
                    objCont.Name & " /ON:" & objContainer.Name)
            End If
        Next objCont
    End Sub

    '***********************************************************************************************
    '* 処理名 :FP_GetMagnifyingSize
    '* 機能  :DPI制御後のサイズ取得
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :サイズ(Size)
    '* 引数  :Arg1 = 元のサイズ(Size)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年11月07日
    '* 作成者 :井上 治
    '* 更新日 :2014年11月07日
    '* 更新者 :井上 治
    '* 機能説明:Width,Heightそれぞれ個々に設定できない場合に使用
    '* 注意事項:
    '***********************************************************************************************
    Private Function FP_GetMagnifyingSize(ByVal objOriginalSize As Size) As Size
        '-------------------------------------------------------------------------------------------
        Dim intWidth As Integer, intHeight As Integer
        intWidth = objOriginalSize.Width * g_sngMagnifyingPowerX
        intHeight = objOriginalSize.Height * g_sngMagnifyingPowerY
        Return New Size(intWidth, intHeight)
    End Function

    '***********************************************************************************************
    '* 処理名 :GP_EntryControlsAddHandlerSub
    '* 機能  :入力コントロールの文字列を全選択状態にする(サブ処理)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :Arg1 = 所属するコンテナ(Object)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年07月07日
    '* 作成者 :井上 治
    '* 更新日 :2017年09月27日
    '* 更新者 :井上 治
    '* 機能説明:Enterイベントで初期表示された文字列を全選択状態にする
    '* 注意事項:本処理は再帰動作
    '***********************************************************************************************
    Private Sub GP_EntryControlsAddHandlerSub(ByVal objContainer As Object)
        '-------------------------------------------------------------------------------------------
        ' コントロールの種別によって処理を切り分けてイベント実装
        For Each objCont As Control In objContainer.Controls
            If TypeOf objCont Is TextBox Then
                '-----------------------------------------------------------------------------------
                ' テキストボックス
                AddHandler CType(objCont, TextBox).GotFocus, AddressOf TextBox_GotFocus

            ElseIf TypeOf objCont Is ComboBox Then
                '-----------------------------------------------------------------------------------
                ' コンボボックス
                AddHandler CType(objCont, ComboBox).GotFocus, AddressOf ComboBox_GotFocus

            ElseIf TypeOf objCont Is NumericUpDown Then
                '-----------------------------------------------------------------------------------
                ' NumericUpDown
                AddHandler CType(objCont, NumericUpDown).GotFocus, AddressOf NumericUpDown_GotFocus

            ElseIf TypeOf objCont Is MaskedTextBox Then
                '-----------------------------------------------------------------------------------
                ' マスクドテキストボックス
                AddHandler CType(objCont, MaskedTextBox).GotFocus, AddressOf MaskedTextBox_GotFocus

            ElseIf ((TypeOf objCont Is TabControl) OrElse _
                    (TypeOf objCont Is TabPage) OrElse _
                    (TypeOf objCont Is Panel) OrElse _
                    (TypeOf objCont Is GroupBox) OrElse _
                    (TypeOf objCont Is TableLayoutPanel) OrElse _
                    (TypeOf objCont Is FlowLayoutPanel) OrElse _
                    (TypeOf objCont Is SplitContainer) OrElse _
                    (TypeOf objCont Is UserControl)) Then
                '-----------------------------------------------------------------------------------
                ' コンテナ時は再帰呼び出し
                Call GP_EntryControlsAddHandlerSub(objCont)
            End If
        Next objCont
    End Sub

    '***********************************************************************************************
    '* 処理名 :TextBox_GotFocus
    '* 機能  :各入力テキストボックスイベント(GotFocus)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年07月07日
    '* 作成者 :井上 治
    '* 更新日 :2017年09月27日
    '* 更新者 :井上 治
    '* 機能説明:初期表示された文字列を全選択状態にする
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub TextBox_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs)
        '-------------------------------------------------------------------------------------------
        With CType(sender, TextBox)
            If Not .ReadOnly AndAlso Not .Multiline Then
                .SelectAll()
            Else
                .Select(0, 0)
            End If
        End With
    End Sub

    '***********************************************************************************************
    '* 処理名 :ComboBox_GotFocus
    '* 機能  :各入力コンボボックスイベント(GotFocus)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年07月07日
    '* 作成者 :井上 治
    '* 更新日 :2017年09月27日
    '* 更新者 :井上 治
    '* 機能説明:初期表示された文字列を全選択状態にする
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub ComboBox_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs)
        '-------------------------------------------------------------------------------------------
        With CType(sender, ComboBox)
            If .DropDownStyle <> ComboBoxStyle.DropDownList Then
                .SelectAll()
            End If
        End With
    End Sub

    '***********************************************************************************************
    '* 処理名 :NumericUpDown_GotFocus
    '* 機能  :各数値入力ボックスイベント(GotFocus)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年07月07日
    '* 作成者 :井上 治
    '* 更新日 :2017年09月27日
    '* 更新者 :井上 治
    '* 機能説明:初期表示された文字列を全選択状態にする
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub NumericUpDown_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs)
        '-------------------------------------------------------------------------------------------
        With CType(sender, NumericUpDown)
            If Not .ReadOnly Then
                .Select(0, .Text.ToString.Length)
            Else
                .Select(0, 0)
            End If
        End With
    End Sub

    '***********************************************************************************************
    '* 処理名 :MaskedTextBox_GotFocus
    '* 機能  :各入力マスクドテキストボックスイベント(GotFocus)
    '-----------------------------------------------------------------------------------------------
    '* 返り値 :(なし)
    '* 引数  :(デフォルト)
    '-----------------------------------------------------------------------------------------------
    '* 作成日 :2014年07月07日
    '* 作成者 :井上 治
    '* 更新日 :2017年09月27日
    '* 更新者 :井上 治
    '* 機能説明:初期表示された文字列を全選択状態にする
    '* 注意事項:
    '***********************************************************************************************
    Friend Sub MaskedTextBox_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs)
        '-------------------------------------------------------------------------------------------
        With CType(sender, MaskedTextBox)
            If Not .ReadOnly AndAlso Not .Multiline Then
                .SelectAll()
            Else
                .Select(0, 0)
            End If
        End With
    End Sub

    '---------------------------------------<< End of Source >>-------------------------------------
End Module