OSDN Git Service

動画のエンコードを軽量化。
[strokestylet/CsWin10Desktop3.git] / FDK / ApplicationForm.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Drawing;
5 using System.Linq;
6 using System.Windows.Forms;
7 using SharpDX;
8 using FDK.メディア;
9
10 namespace FDK
11 {
12         public class ApplicationForm : SharpDX.Windows.RenderForm, IDisposable
13         {
14                 /// <summary>
15                 ///             ウィンドウの表示モード(全画面 or ウィンドウ)を示す。
16                 ///             true なら全画面モード、false ならウィンドウモードである。
17                 ///             値を set することで、モードを変更することもできる。
18                 /// </summary>
19                 /// <remarks>
20                 ///             正確には、「全画面(fullscreen)」ではなく「最大化(maximize)」。
21                 /// </remarks>
22                 public bool 全画面モード
23                 {
24                         get
25                                 => this.IsFullscreen;
26
27                         set
28                         {
29                                 Trace.Assert( this._初期化完了 );
30
31                                 if( this.IsFullscreen )
32                                 {
33                                         Log.Info( "ウィンドウモードに移行します。" );
34
35                                         this.WindowState = FormWindowState.Normal;
36                                         this.ClientSize = this._ウィンドウモードの情報のバックアップ.clientSize;
37                                         this.FormBorderStyle = this._ウィンドウモードの情報のバックアップ.formBorderStyle;
38
39                                         this.IsFullscreen = false;
40                                 }
41                                 else
42                                 {
43                                         Log.Info( "全画面モードに移行します。" );
44
45                                         this._ウィンドウモードの情報のバックアップ.clientSize = this.ClientSize;
46                                         this._ウィンドウモードの情報のバックアップ.formBorderStyle = this.FormBorderStyle;
47
48                                         // (参考) http://www.atmarkit.co.jp/ait/articles/0408/27/news105.html
49                                         this.WindowState = FormWindowState.Normal;
50                                         this.FormBorderStyle = FormBorderStyle.None;
51                                         this.WindowState = FormWindowState.Maximized;
52
53                                         this.IsFullscreen = true;
54                                 }
55                         }
56                 }
57
58                 static protected グラフィックデバイス グラフィックデバイス
59                 {
60                         get;
61                         set;
62                 } = null;
63
64
65                 /// <summary>
66                 ///             初期化処理。
67                 /// </summary>
68                 public ApplicationForm( SizeF 設計画面サイズ, SizeF 物理画面サイズ )
69                 {
70                         this.SetStyle( ControlStyles.ResizeRedraw, true );
71                         this.ClientSize = 物理画面サイズ.ToSize();
72                         this.MinimumSize = new Size( 640, 360 );
73                         this.Text = "FDK.ApplicationForm";
74
75                         ApplicationForm.グラフィックデバイス = new グラフィックデバイス( this.Handle, 設計画面サイズ, 物理画面サイズ );
76
77                         this.UserResized += this.OnUserResize;
78
79                         this._初期化完了 = true;
80                 }
81
82                 /// <summary>
83                 ///             終了処理。
84                 /// </summary>
85                 public new void Dispose()
86                 {
87                         Debug.Assert( this._初期化完了 );
88
89                         ApplicationForm.グラフィックデバイス.Dispose();
90                         ApplicationForm.グラフィックデバイス = null;
91
92                         this._初期化完了 = false;
93
94                         base.Dispose();
95                 }
96
97                 /// <summary>
98                 ///             メインループ。
99                 ///             派生クラスでオーバーライドすること。
100                 /// </summary>
101                 public virtual void Run()
102                 {
103                         SharpDX.Windows.RenderLoop.Run( this, () => {
104
105                                 var gd = ApplicationForm.グラフィックデバイス;
106
107                                 // 全面を黒で塗りつぶすだけのサンプル。
108                                 gd.D2DDeviceContext.BeginDraw();
109                                 gd.D2DDeviceContext.Clear( Color4.Black );
110                                 gd.D2DDeviceContext.EndDraw();
111
112                                 gd.SwapChain.Present( 1, SharpDX.DXGI.PresentFlags.None );
113
114                         } );
115                 }
116
117
118                 /// <summary>
119                 ///             <see cref="Run"/>での初期化が終わり、メインループに入っていれば true。
120                 /// </summary>
121                 protected bool _初期化完了 = false;
122
123                 /// <summary>
124                 ///             フォーム生成時のパラメータを返す。
125                 /// </summary>
126                 protected override CreateParams CreateParams
127                 {
128                         get
129                         {
130                                 // DWM によってトップウィンドウごとに割り当てられるリダイレクトサーフェスを持たない
131                                 const int WS_EX_NOREDIRECTIONBITMAP = 0x00200000;
132
133                                 var cp = base.CreateParams;
134                                 cp.ExStyle |= WS_EX_NOREDIRECTIONBITMAP;
135                                 return cp;
136                         }
137                 }
138
139                 /// <summary>
140                 ///             ウィンドウサイズが変更された。
141                 /// </summary>
142                 protected virtual void OnUserResize( object sender, EventArgs e )
143                 {
144                         using( Log.Block( FDKUtilities.現在のメソッド名 ) )
145                         {
146                                 Log.Info( $"新しいサイズ: {this.ClientSize}" );
147
148                                 // メインループ(RenderLoop)が始まる前にも数回呼び出されるので、それをはじく。
149                                 if( !( this._初期化完了 ) )
150                                 {
151                                         Log.Info( "アプリケーションの初期化がまだ完了していないので、リサイズ処理をスキップします。" );
152                                         return;
153                                 }
154
155                                 //if( ApplicationForm.グラフィックデバイス.物理画面サイズ.Equals( this.ClientSize ) )
156                                 //{
157                                 //      Log.Info( "サイズが変更されていないので、リサイズ処理をスキップします。" );
158                                 //      return;
159                                 //}
160
161                                 var gd = ApplicationForm.グラフィックデバイス;
162
163                                 gd.D3DDeviceを取得する( ( d3dDevice ) => {
164
165                                         this.スワップチェーンに依存するグラフィックリソースを解放する();
166
167                                         gd.サイズを変更する( this.ClientSize, d3dDevice );
168
169                                         this.スワップチェーンに依存するグラフィックリソースを作成する( d3dDevice );
170                                 } );
171                         }
172                 }
173
174                 protected virtual void スワップチェーンに依存するグラフィックリソースを作成する( SharpDX.Direct3D11.Device d3dDevice ) { }
175                 protected virtual void スワップチェーンに依存するグラフィックリソースを解放する() { }
176
177
178                 /// <summary>
179                 ///             ウィンドウを全画面モードにする直前に取得し、
180                 ///             再びウィンドウモードに戻して状態を復元する時に参照する。
181                 ///             (<see cref="全画面モード"/> を参照。)
182                 /// </summary>
183                 private (Size clientSize, FormBorderStyle formBorderStyle) 
184                         _ウィンドウモードの情報のバックアップ;
185         }
186 }