# 画面設計書 99-Screens

## 概要

本ドキュメントは、IntegrationTestAppアプリケーションにおけるScreensPageの画面設計書です。マルチモニター環境でのスクリーン情報取得機能をテストするためのページとして設計されています。

### 本画面の処理概要

**業務上の目的・背景**：本画面は、Avaloniaフレームワークにおけるスクリーン（ディスプレイ）情報取得機能の統合テストを目的としています。マルチモニター環境での画面配置、解像度、スケーリング、ワークエリア、画面の向きなどの情報を正しく取得できることを検証するためのテストUIを提供します。クロスプラットフォームでのディスプレイ管理機能のテストに使用されます。

**画面へのアクセス方法**：IntegrationTestAppのメインウィンドウ左側のListBoxナビゲーションから「Screens」項目を選択することでアクセスします。

**主要な操作・処理内容**：
1. 「Refresh」ボタンをクリックして現在のスクリーン情報を取得
2. 取得したスクリーン情報（DisplayName、Handle、Scaling、Bounds、WorkArea、Orientation）を表示
3. 前回取得したスクリーン参照との同一性を確認

**画面遷移**：この画面はIntegrationTestAppのメインウィンドウ内のページとして表示されます。他画面への遷移機能はありません。

**権限による表示制御**：特になし。すべてのユーザーが全機能を利用可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 46 | Screens | 主機能 | スクリーンのテスト。マルチモニター環境での画面情報取得 |

## 画面種別

テスト・検証画面

## URL/ルーティング

デスクトップアプリケーションのため、URLルーティングはなし。MainWindowのListBoxナビゲーションから「Screens」を選択。

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| ScreenRefresh | 入力 | Button | - | スクリーン情報更新トリガー |

## 表示項目

| 項目名 | コントロール名 | 説明 |
|--------|--------------|------|
| ScreenName | TextBox | スクリーンの表示名（DisplayName） |
| ScreenHandle | TextBox | プラットフォーム固有のハンドル |
| ScreenScaling | TextBox | DPIスケーリング値 |
| ScreenBounds | TextBox | スクリーンの境界矩形（Bounds） |
| ScreenWorkArea | TextBox | 作業領域（タスクバー等を除く）の矩形 |
| ScreenOrientation | TextBox | スクリーンの向き（Landscape/Portrait等） |
| ScreenSameReference | TextBox | 前回取得との参照同一性（True/False） |

## イベント仕様

### 1-ScreenRefresh_Click

**トリガー**: 「Refresh」ボタン押下

**処理内容**:
1. TopLevel.GetTopLevelで現在のウィンドウを取得
2. window.Screens.ScreenFromWindow(window)で現在のウィンドウが存在するスクリーンを取得
3. 前回のスクリーン参照を保存
4. 各TextBoxにスクリーン情報を設定：
   - ScreenName.Text = screen?.DisplayName
   - ScreenHandle.Text = screen?.TryGetPlatformHandle()?.ToString()
   - ScreenBounds.Text = screen?.Bounds.ToString()
   - ScreenWorkArea.Text = screen?.WorkingArea.ToString()
   - ScreenScaling.Text = screen?.Scaling.ToString(CultureInfo.InvariantCulture)
   - ScreenOrientation.Text = screen?.CurrentOrientation.ToString()
   - ScreenSameReference.Text = ReferenceEquals(lastScreen, screen).ToString()

## データベース更新仕様

### 操作別データベース影響一覧

本画面はUIコントロールのテスト用であり、データベース操作は行いません。

## メッセージ仕様

本画面ではシステムメッセージの表示はありません。

## 例外処理

| 例外 | 発生条件 | 処理 |
|------|----------|------|
| AvaloniaInternalException | TopLevel.GetTopLevelがnullを返した場合 | 例外をスロー |

## 備考

- UseFloatingPlaceholder="true"により、プレースホルダーがフローティングラベルとして表示
- _lastScreenフィールドで前回取得したスクリーン参照を保持
- ReferenceEqualsで参照の同一性を確認（スクリーン情報のキャッシュ動作検証）
- TryGetPlatformHandle()はプラットフォーム固有のハンドルを取得（Windows: HMONITOR等）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、Screenクラスの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Screen.cs | `src/Avalonia.Controls/Screen.cs` | DisplayName、Bounds、WorkingArea、Scaling、CurrentOrientationプロパティ |
| 1-2 | Screens.cs | `src/Avalonia.Controls/Screens.cs` | Screensクラス、ScreenFromWindow()メソッド |

**読解のコツ**: Screenクラスはプラットフォーム固有の実装にデリゲートしており、TryGetPlatformHandle()でネイティブハンドルを取得できます。

#### Step 2: エントリーポイントを理解する

処理の起点となるページファイルを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ScreensPage.axaml | `samples/IntegrationTestApp/Pages/ScreensPage.axaml` | UI構造、各TextBoxの定義 |
| 2-2 | ScreensPage.axaml.cs | `samples/IntegrationTestApp/Pages/ScreensPage.axaml.cs` | イベントハンドラの実装 |

**主要処理フロー**:
1. **行8-9 (axaml)**: Refreshボタンの定義
2. **行11-17 (axaml)**: 各情報表示用TextBoxの定義
3. **行18-31 (axaml.cs)**: ScreenRefresh_Clickイベントハンドラ

#### Step 3: イベント処理を理解する

スクリーン情報取得処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ScreensPage.axaml.cs | `samples/IntegrationTestApp/Pages/ScreensPage.axaml.cs` | ScreenRefresh_Clickの実装詳細 |

**主要処理フロー**:
- **行20-21**: ウィンドウ取得と例外処理
- **行22-23**: 前回スクリーンの保存と新規スクリーン取得
- **行24-30**: 各プロパティをTextBoxに設定

### プログラム呼び出し階層図

```
ScreensPage
    │
    ├─ _lastScreen フィールド（前回取得スクリーン保持）
    │
    └─ ScreenRefresh_Click
           │
           ├─ TopLevel.GetTopLevel(this) as Window
           │
           ├─ window.Screens.ScreenFromWindow(window)
           │
           └─ 各TextBoxへの値設定
                  ├─ ScreenName.Text = screen?.DisplayName
                  ├─ ScreenHandle.Text = screen?.TryGetPlatformHandle()
                  ├─ ScreenBounds.Text = screen?.Bounds
                  ├─ ScreenWorkArea.Text = screen?.WorkingArea
                  ├─ ScreenScaling.Text = screen?.Scaling
                  ├─ ScreenOrientation.Text = screen?.CurrentOrientation
                  └─ ScreenSameReference.Text = ReferenceEquals(...)
```

### データフロー図

```
[入力]                         [処理]                      [出力]

Refreshボタン      ───▶  ScreenFromWindow()       ───▶  Screenオブジェクト取得
クリック                │
                        └─ 各プロパティ抽出       ───▶  7つのTextBoxに表示
                              ├─ DisplayName
                              ├─ TryGetPlatformHandle()
                              ├─ Bounds
                              ├─ WorkingArea
                              ├─ Scaling
                              ├─ CurrentOrientation
                              └─ ReferenceEquals()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ScreensPage.axaml | `samples/IntegrationTestApp/Pages/ScreensPage.axaml` | ソース | ページのUI定義 |
| ScreensPage.axaml.cs | `samples/IntegrationTestApp/Pages/ScreensPage.axaml.cs` | ソース | ページのコードビハインド |
| MainWindow.axaml | `samples/IntegrationTestApp/MainWindow.axaml` | ソース | メインウィンドウとナビゲーション |
| MainWindow.axaml.cs | `samples/IntegrationTestApp/MainWindow.axaml.cs` | ソース | ページ生成ファクトリ（行92） |
