Windows 新元号対応アップデートでフォームのレイアウトが崩れる原因と、影響のあるフォントの調査方法

#Windows Update にて解消(2019/5/15追記)

フォームのサイズが変化してしまう件について、こちらでアップデートを適用し解消されることを確認しました。

※確認した環境

- 確認したOS：Windows 10 Pro 1809 64bit
- フォームのサイズに関する不具合が発生したKB：KB4495667
- 不具合対応が入っていたKB：KB4494441

なお、不具合の対象フォントはMS UI GothicとMS Pゴシックという事が判明していますので、本記事の対象フォントを調査する方法はポイントに限って有効なものとなります。

#現象

新元号対応アップデートを行うとフォームのレイアウトが崩れる現象が発生している。
対象KBを適用していないPCで実行した時のフォームサイズとKB適用済みのフォームサイズが異なる。
高さ/幅が変化するケースがあり、高さが低くなる場合は、フォーム内に配置されているコントロールが欠ける等の現象となる。

#発生条件(調査済みのもののみ)

* 不具合確認済みOS : Windows8.1 64bit KB4493443/Windows10 64bit (1809) KB4495667 (Windows7 SP1では再現できず、他のOSやVerは未確認)
* 不具合確認済み開発環境 Visual Studio 2012 Update 5
* Form.AutoScaleMode = Fontであること
* 対象KBを適用していないPCにてフォームデザイナを利用して作成/修正したフォームを対象KBを適用しているPCにて実行した場合(KBの適用済/未適用が反対の場合も該当)
* xxxx.Designer.vbにて生成されるInitializecomponent()内でMe.SuspendLayout()、Me.ResumeLayout(False)の記述がある (必ず自動で記述されると思われる)
* 対象KBを適用済みのOSと、対象KB未適用のOSでフォントサイズの計測値が異なるフォント・ポイント (例:MS UI Gothic 9ポイント)
* Form.ControlBoxやForm.FormBorderStyleの値によりフォームサイズの挙動は異なる

#フォームのソース例と原因

```vb:Form1.Designer.vb
Private Sub InitializeComponent()
	Me.Label1 = New System.Windows.Forms.Label()
	Me.SuspendLayout()
	'
	'Form1
	'
	Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
	Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
	Me.ClientSize = New System.Drawing.Size(525, 261)
	Me.ControlBox = False
	Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
	Me.Name = "Form1"
	Me.Text = "Form1"
	Me.ResumeLayout(False)
End Sub
```


KB適用済みの場合は下記になる

```vb:
Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 12.0!)
```
なお、この行はAutoScaleMode=FontまたはDpiの場合に生成される
(Fontの場合はフォントのサイズ、Dpiの場合はDpiの縦・横の数値が入る)


KB未適用の場合は下記になる

```vb:
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
```

何れの場合も下記のタイミングで実行時のAutoScaleDimensionsがセットされ、ソース上のサイズと実行時のサイズがアンマッチになると不都合が生じるようである(原理は未調査)

```vb:
Me.ResumeLayout(False)
```

#影響となるフォント・ポイントの調査方法

どのフォント、サイズで問題が発生するか調査を行うために、下記のソースを作成してみた。

下記のソースはForm1を作成後、デザイナでボタンを1つ配置してからコピペすると動作するようになっている。

```vb:Form1.vb
Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim resultFilePath As String = System.IO.Path.Combine(Application.StartupPath, "result.csv")

        Dim fontPointArray() As Single = {
            8.25!,
            9.0!,
            9.75!,
            11.25!,
            12.0!,
            14.25!,
            15.75!
        }

        Dim fontFamilyNameArray() As String = {
            "MS UI Gothic",
            "Meiryo UI",
            "メイリオ",
            "游ゴシック",
            "游明朝",
            "ＭＳ ゴシック",
            "ＭＳ 明朝",
            "ＭＳ Ｐゴシック",
            "ＭＳ Ｐ明朝",
            "Yu Gothic UI"
        }

        Using textWriter As New System.IO.StreamWriter(resultFilePath, False, System.Text.Encoding.UTF8)
            For Each fontFamilyName As String In fontFamilyNameArray
                For Each fontPoint As Single In fontPointArray
                    Using targetFont As Font = New System.Drawing.Font(fontFamilyName, fontPoint, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(128, Byte))
                        Me.Font = targetFont
                        Dim fontScale As SizeF = Me.CurrentAutoScaleDimensions
                        Me.Font = Nothing
                        textWriter.WriteLine(fontFamilyName & "," & CStr(fontPoint) & "," & CStr(fontScale.Width) & "," & CStr(fontScale.Height))
                    End Using
                Next
            Next
        End Using

    End Sub
End Class

```

特定フォント・サイズ(単位はポイント)に限定し、フォームのCurrentAutoScaleDimensions(フォントに対するサイズの計測結果)をcsvファイルで保存する。

このプログラムを新元号アップデートを適用している環境としていない環境で実行してみると、影響が把握できる。

#実行結果

差分のみ表示しているが、調査したフォントの中では MS UI GothicとＭＳ　Ｐゴシックのいくつかのポイントで発生していることがわかる
(Windows10 Pro 64bit 1809にて確認)
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85872/773b4d1d-2e11-124f-a262-8af555b128e2.png)