OSDN Git Service

#47668 DTXC内で扱う分解能を下辺にするための布石。
[dtxmania/dtxmania.git] / DTXCreator / コード / 00.全体 / Cメインフォーム.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Globalization;
4 using System.Threading;
5 using System.Windows.Forms;
6 using System.Drawing;
7 using System.ComponentModel;
8 using System.IO;
9 using System.Text;
10 using System.Diagnostics;
11 using System.Xml.Serialization;
12 using DTXCreator.チップパレット関連;
13 using DTXCreator.譜面;
14 using DTXCreator.WAV_BMP_AVI;
15 using DTXCreator.UndoRedo;
16 using DTXCreator.オプション関連;
17 using DTXCreator.MIDIインポート;
18 using DTXCreator.MIDIExport;
19 using DTXCreator.汎用;
20 using DTXCreator.Properties;
21 using FDK;
22
23 namespace DTXCreator
24 {
25         public partial class Cメインフォーム : Form
26         {
27                 // コンストラクタ
28
29                 #region [ コンストラクタ ]
30                 //-----------------
31                 public Cメインフォーム()
32                 {
33                         this.InitializeComponent();
34                 }
35                 //-----------------
36                 #endregion
37
38
39                 // プロパティ
40
41                 #region [ プロパティ ]
42                 //-----------------
43
44                 public AppSetting appアプリ設定;
45                 public Cチップパレット dlgチップパレット;
46                 private Cオプション管理 mgrオプション管理者 = null;
47                 private C選択モード管理 mgr選択モード管理者 = null;
48                 internal C編集モード管理 mgr編集モード管理者 = null;
49                 internal C譜面管理 mgr譜面管理者 = null;
50                 internal CWAVリスト管理 mgrWAVリスト管理者 = null;
51                 internal CBMPリスト管理 mgrBMPリスト管理者 = null;
52                 internal CAVIリスト管理 mgrAVIリスト管理者 = null;
53                 internal CUndoRedo管理 mgrUndoRedo管理者 = null;
54                 internal Cクリップボード cbクリップボード = null;
55                 private CMIDIインポート管理 mgrMIDIインポート管理者 = null;
56                 private CMIDIExportManager mgrMIDIExportManager = null;
57
58                 internal MakeTempDTX makeTempDTX = null;
59
60                 public bool b選択モードである
61                 {
62                         get
63                         {
64                                 if( this.toolStripButton選択モード.CheckState != CheckState.Checked )
65                                 {
66                                         return false;
67                                 }
68                                 return true;
69                         }
70                 }
71                 public bool b編集モードである
72                 {
73                         get
74                         {
75                                 if( this.toolStripButton編集モード.CheckState != CheckState.Checked )
76                                 {
77                                         return false;
78                                 }
79                                 return true;
80                         }
81                 }
82                 public decimal dc現在のBPM
83                 {
84                         get
85                         {
86                                 return this.numericUpDownBPM.Value;
87                         }
88                 }
89                 internal int n現在選択中のWAV_BMP_AVIリストの行番号0to1294;
90
91                 /// <summary>
92                 /// DTXC.exe のあるフォルダの絶対パス。
93                 /// </summary>
94                 public string strDTXCのあるフォルダ名;
95
96                 /// <summary>
97                 /// 各種ファイル(WAVなど)の相対パスの基点となるフォルダの絶対パス。
98                 /// </summary>
99                 public string str作業フォルダ名;
100
101                 /// <summary>
102                 /// 現在作成中のDTXファイル名。パスは含まない。(例:"test.dtx")
103                 /// </summary>
104                 public string strDTXファイル名;
105
106                 /// <summary>
107                 /// <para>未保存の場合にtrueとなり、ウィンドウタイトルに[*]が加えられる。</para>
108                 /// </summary>
109                 internal bool b未保存
110                 {
111                         get
112                         {
113                                 return this._b未保存;
114                         }
115                         set
116                         {
117                                 // 現状と値が違うときだけ更新する。
118
119                                 if( this._b未保存 != value )
120                                 {
121                                         this._b未保存 = value;               // #24133 2011.1.14 yyagi: 「代入後にif文分岐」するよう、代入を頭に移動。
122
123                                         // タイトル文字列を取得。
124
125                                         string strタイトル = Resources.strデフォルトウィンドウタイトル;
126
127                                         if( this.strDTXファイル名.Length > 0 )
128                                                 strタイトル = this.strDTXファイル名;
129
130
131                                         // タイトル文字列を修正。
132
133                                         if (this._b未保存)
134                                         {
135                                                 // 変更ありかつ未保存なら「*」を付ける
136                                                 if (COS.bIsWin10OrLater(COS.WIN10BUILD._19H1))  // Win10 19H1以降のお作法は、タイトルバーの頭に*を表示
137                                                 {
138                                                         this.Text = "*DTXC [" + strタイトル + "]";
139                                                 }
140                                                 else
141                                                 {
142                                                         this.Text = "DTXC* [" + strタイトル + "]";
143                                                 }
144                                                 this.toolStripMenuItem上書き保存.Enabled = true;
145                                                 this.toolStripButton上書き保存.Enabled = true;
146                                         }
147                                         else
148                                         {
149                                                 // 保存後変更がないなら「*」なない
150
151                                                 this.Text = "DTXC [" + strタイトル + "]";
152                                                 this.toolStripMenuItem上書き保存.Enabled = false;
153                                                 this.toolStripButton上書き保存.Enabled = false;
154                                         }
155                                 }
156                         }
157                 }
158                 
159                 /// <summary>
160                 /// 最後にMIDIを読み込んだフォルダ
161                 /// </summary>
162                 public string strMIDIインポートフォルダ;
163
164                 /// <summary>
165                 /// 最後に読み込まれたMIDIインポート設定ファイル
166                 /// </summary>
167                 public string strMIDIインポート設定ファイル;
168
169                 //-----------------
170                 #endregion
171
172
173                 // シナリオ
174
175                 #region [ アプリの起動・初期化、終了 ]
176                 //-----------------
177                 private void tアプリ起動時に一度だけ行う初期化処理()
178                 {
179                         // 初期化
180
181                         #region [ アプリ設定オブジェクトを生成する。]
182                         //-----------------
183                         this.appアプリ設定 = new AppSetting();
184                         //-----------------
185                         #endregion
186
187                         #region [ DTXCreator.exe の存在するフォルダを取得する。 ]
188                         //-----------------
189                         this.strDTXCのあるフォルダ名 = Directory.GetCurrentDirectory() + @"\";
190                         //-----------------
191                         #endregion
192                         #region [ 作業フォルダを取得する。]
193                         //-----------------
194                         this.str作業フォルダ名 = this.strDTXCのあるフォルダ名;
195                         //-----------------
196                         #endregion
197
198                         #region [ デザイナで設定できないイベントを実装する。]
199                         //-----------------
200                         this.splitContainerタブと譜面を分割.MouseWheel += new MouseEventHandler( this.splitContainerタブと譜面を分割_MouseWheel );
201                         //-----------------
202                         #endregion
203
204                         #region [ 全体を通して必要な管理者オブジェクトを生成する。]
205                         //-----------------
206                         this.mgrオプション管理者 = new Cオプション管理( this );
207                         this.mgrMIDIインポート管理者 = new CMIDIインポート管理(this);
208                         this.mgrMIDIExportManager    = new CMIDIExportManager(this);
209                         //-----------------
210                         #endregion
211
212                         #region [ クリップボードオブジェクトを生成する。 ]
213                         //-----------------
214                         this.cbクリップボード = new Cクリップボード( this );
215                         //-----------------
216                         #endregion
217
218                         #region [ Viewer再生用一時DTX生成オブジェクトを生成する。 ]
219                         makeTempDTX = new MakeTempDTX();
220                         #endregion
221
222                         #region [ 譜面を初期化する。]
223                         //-----------------
224                         this.t譜面を初期化する();
225                         //-----------------
226                         #endregion
227
228                         #region [ アプリ設定ファイル (DTXCreatorSetting.config) を読み込む。]
229                         //-----------------
230                         this.tアプリ設定の読み込み(); // 譜面の生成後に行うこと。(GUIイベント発生時にmgr各種が使われるため。)
231                         //-----------------
232                         #endregion
233
234                         #region [ チップパレットウィンドウの初期位置を変更する。(読み込んだアプリ設定に合わせる。)]
235                         //-----------------
236                         this.dlgチップパレット.Left = this.Left + ( ( this.Width - this.dlgチップパレット.Width ) / 2 );
237                         this.dlgチップパレット.Top = this.Top + ( ( this.Height - this.dlgチップパレット.Height ) / 2 );
238                         //-----------------
239                         #endregion
240
241                         #region [ [ファイル]メニューに、最近使ったファイルを追加する。]
242                         //-----------------
243                         this.t最近使ったファイルをFileメニューへ追加する();
244                         //-----------------
245                         #endregion
246
247
248                         // ファイル指定があればそれを開く。
249
250                         #region [ コマンドライン引数にファイルの指定があるならそれを開く。 ]
251                         //-----------------
252                         string[] commandLineArgs = Environment.GetCommandLineArgs();
253                         if ((commandLineArgs.Length > 1) && File.Exists(commandLineArgs[1]))
254                         {
255                                 this.t演奏ファイルを開いて読み込む(commandLineArgs[1]);
256                                 return;
257                         }
258                         //-----------------
259                         #endregion
260
261                         #region [ 設定で「最後に編集していたファイルを、DTXC起動時に読み込む」ようにしていたならそれを開く。 ]
262                         //-----------------
263                         if (this.appアプリ設定.RecentFilesNum > 0 && this.appアプリ設定.StartupMode == true)
264                         {
265                                 this.t演奏ファイルを開いて読み込む(this.appアプリ設定.RecentUsedFile[0]);
266                         }
267                         //-----------------
268                         #endregion
269                 }
270                 private void tアプリ終了時に行う終了処理()
271                 {
272                         #region [ アプリ設定ファイル (DTXCreatorSetting.config) を保存する。]
273                         //-----------------
274                         this.tアプリ設定の保存();
275                         //-----------------
276                         #endregion
277
278                         #region [ 各管理者で必要な終了処理を行う。]
279                         //-----------------
280                         this.mgrWAVリスト管理者.tDirectSoundの解放();
281                         //-----------------
282                         #endregion
283
284                         #region [ Viewer再生用一時DTX生成オブジェクトの終了処理を行う。 ]
285                         makeTempDTX.Dispose();
286                         makeTempDTX = null;
287                         #endregion
288                 }
289                 private void tアプリ設定の読み込み()
290                 {
291                         string str設定ファイル名 =
292                                 this.strDTXCのあるフォルダ名 + @"DTXCreatorSetting.config";
293
294
295                         // 読み込む。
296
297                         #region [ アプリ設定ファイルを読み込む。 → 失敗したら内容リセットして継続する。]
298                         //-----------------
299                         if( File.Exists( str設定ファイル名 ) )
300                         {
301                                 try
302                                 {
303                                         // アプリ設定ファイル(XML形式)を this.appアプリ設定 に読み込む。
304
305                                         var serializer = new XmlSerializer( typeof( AppSetting ) );
306                                         var stream = new FileStream( str設定ファイル名, FileMode.Open );
307                                         this.appアプリ設定 = (AppSetting) serializer.Deserialize( stream );
308                                         stream.Close();
309                                 }
310                                 catch( Exception )
311                                 {
312                                         // 失敗時:内容をリセットして継続する。
313
314                                         this.appアプリ設定 = new AppSetting();
315                                 }
316
317
318                                 // 反復要素とか足りなかったりしてもリセットする。
319
320                                 if( this.appアプリ設定.SoundListColumnWidth.Length != 5
321                                         || this.appアプリ設定.GraphicListColumnWidth.Length != 4
322                                         || this.appアプリ設定.MovieListColumnWidth.Length != 3
323                                         || !this.appアプリ設定.bSameVersion() )
324                                 {
325                                         this.appアプリ設定 = new AppSetting();
326                                 }
327
328
329                                 // 内容の妥当性を確認する。
330
331                                 this.appアプリ設定.Confirm();
332                         }
333                         //-----------------
334                         #endregion
335
336
337                         // 読み込んだアプリ設定を DTXCreator に反映する。
338
339                         #region [ ウィンドウの位置とサイズ ]
340                         //-----------------
341                         #region [ ウインドウが画面外に表示されようとしている場合は、左上にウインドウを強制的に移動する ]
342                         int h = System.Windows.Forms.Screen.GetBounds( this ).Height;
343                         int w = System.Windows.Forms.Screen.GetBounds( this ).Width;
344                         if (this.appアプリ設定.X > w || this.appアプリ設定.Y > h)
345                         {
346                                 this.appアプリ設定.X = this.appアプリ設定.Y = 0;
347                         }
348                         #endregion
349                         this.SetDesktopBounds( this.appアプリ設定.X, this.appアプリ設定.Y, this.appアプリ設定.Width, this.appアプリ設定.Height );
350                         //-----------------
351                         #endregion
352                         #region [ 最大化 ]
353                         //-----------------
354                         if( this.appアプリ設定.Maximized )
355                                 this.WindowState = FormWindowState.Maximized;
356                         //-----------------
357                         #endregion
358                         #region [ タブ(左側)と譜面(右側)の表示幅の割合 ]
359                         //-----------------
360                         this.splitContainerタブと譜面を分割.SplitterDistance =
361                                 this.appアプリ設定.SplitterDistance;
362                         //-----------------
363                         #endregion
364                         #region [ WAV・BMP・AVIリストの各列の幅 ]
365                         //-----------------
366                         for( int i = 0; i < 5; i++ )
367                                 this.listViewWAVリスト.Columns[ i ].Width = this.appアプリ設定.SoundListColumnWidth[ i ];
368
369                         for( int i = 0; i < 4; i++ )
370                                 this.listViewBMPリスト.Columns[ i ].Width = this.appアプリ設定.GraphicListColumnWidth[ i ];
371
372                         for( int i = 0; i < 3; i++ )
373                                 this.listViewAVIリスト.Columns[ i ].Width = this.appアプリ設定.MovieListColumnWidth[ i ];
374                         //-----------------
375                         #endregion
376                         #region [ 譜面拡大率 ]
377                         //-----------------
378                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
379                         this.toolStripComboBox譜面拡大率.SelectedIndex =
380                                 this.appアプリ設定.HViewScaleIndex;
381                         //-----------------
382                         #endregion
383                         #region [ ガイド間隔 ]
384                         //-----------------
385                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
386                         this.toolStripComboBoxガイド間隔.SelectedIndex =
387                                 this.appアプリ設定.GuideIndex;
388                         //-----------------
389                         #endregion
390                         #region [ 演奏速度 ]
391                         //-----------------
392                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
393                         this.toolStripComboBox演奏速度.SelectedIndex = 5;
394                         //-----------------
395                         #endregion
396                         #region [ 作業フォルダ ]
397                         //-----------------
398                         this.str作業フォルダ名 =
399                                 this.appアプリ設定.LastWorkFolder;
400                         
401                         if( Directory.Exists( this.str作業フォルダ名 ) )
402                         {
403                                 //Directory.SetCurrentDirectory( this.str作業フォルダ名 );               // #35399: 2015/8/15 カレントディレクトリを変更すると、.NET4以降用にbuildしたDTXMania本体での再生に失敗するため、カレントディレクトリの変更を中止する
404                                 // #35399: ただし作業フォルダは維持する(書き設定行は不要だが、if分岐は残す必要あり)
405                                 // this.str作業フォルダ名 = this.appアプリ設定.LastWorkFolder;      
406                         }
407                         else
408                         {
409                                 // 作業フォルダが既になくなってる場合はカレントフォルダを適用。
410
411                                 this.str作業フォルダ名 = Directory.GetCurrentDirectory();
412                         }
413                         //-----------------
414                         #endregion
415                         #region [ レーン表示/非表示の反映 #26005 2011.8.29 yyagi; added ]
416                         for ( int i = 0; i < this.appアプリ設定.LanesInfo.Count; i++ )
417                         {
418                                 for ( int j = 0; j < this.mgr譜面管理者.listレーン.Count; j++ )
419                                 {
420                                         if ( this.mgr譜面管理者.listレーン[ j ].strレーン名 == this.appアプリ設定.LanesInfo[ i ].Name )
421                                         {
422                                                 this.mgr譜面管理者.listレーン[ j ].bIsVisible = this.appアプリ設定.LanesInfo[ i ].Checked;
423                                                 break;
424                                         }
425                                 }
426                         }
427                         this.mgr譜面管理者.tRefreshDisplayLanes();
428                         #endregion
429                         #region [ 選択モード/編集モードの設定 ]
430                         if ( this.appアプリ設定.InitialOperationMode )
431                         {
432                                 this.t選択モードにする();
433                         }
434                         else
435                         {
436                                 this.t編集モードにする();
437                         }
438                         #endregion
439                         #region [ MIDIインポートフォルダ関連 ]
440                         //-----------------
441                         this.strMIDIインポートフォルダ = this.appアプリ設定.LastMIDIImportFolder;
442                         
443                         if( ! Directory.Exists( this.strMIDIインポートフォルダ ) )
444                                 this.strMIDIインポートフォルダ = Directory.GetCurrentDirectory();
445
446                         // 設定ファイル
447                         this.strMIDIインポート設定ファイル = this.appアプリ設定.LastMIDIImportSettingsFile;
448                         
449                         if( ! File.Exists( this.strMIDIインポート設定ファイル ) ) this.strMIDIインポート設定ファイル = Directory.GetCurrentDirectory() + @"\" + "DTXCreatorSMFSettings.xml";
450                         //-----------------
451                         #endregion
452
453                 }
454                 private void tアプリ設定の保存()
455                 {
456                         string str設定ファイル名 = 
457                                 this.strDTXCのあるフォルダ名 + @"DTXCreatorSetting.config";
458
459
460                         // DTXCreator から保存すべきアプリ設定を取得する。
461
462                         #region [ #23729 2010.11.22 yyagi: to get DTXC's x, y, width & height correctly, set windowstate "normal" if it is "minimized." ]
463                         if (this.WindowState == FormWindowState.Minimized)
464                         {
465                                 this.WindowState = FormWindowState.Normal;
466                         }
467                         #endregion
468                         #region [ ウィンドウの位置とサイズ ]
469                         //-----------------
470                         this.appアプリ設定.X = this.Location.X;
471                         this.appアプリ設定.Y = this.Location.Y;
472                         this.appアプリ設定.Width = this.Width;
473                         this.appアプリ設定.Height = this.Height;
474                         //-----------------
475                         #endregion
476                         #region [ 最大化 ]
477                         //-----------------
478                         this.appアプリ設定.Maximized =
479                                 ( this.WindowState == FormWindowState.Maximized ) ? true : false;
480                         //-----------------
481                         #endregion
482                         #region [ タブ(左側)と譜面(右側)の表示幅の割合 ]
483                         //-----------------
484                         this.appアプリ設定.SplitterDistance =
485                                 this.splitContainerタブと譜面を分割.SplitterDistance;
486                         //-----------------
487                         #endregion
488                         #region [ WAV・BMP・AVIリストの各列の幅 ]
489                         //-----------------
490                         for( int i = 0; i < 5; i++ )
491                                 this.appアプリ設定.SoundListColumnWidth[ i ] = this.listViewWAVリスト.Columns[ i ].Width;
492
493                         for( int i = 0; i < 4; i++ )
494                                 this.appアプリ設定.GraphicListColumnWidth[ i ] = this.listViewBMPリスト.Columns[ i ].Width;
495
496                         for( int i = 0; i < 3; i++ )
497                                 this.appアプリ設定.MovieListColumnWidth[ i ] = this.listViewAVIリスト.Columns[ i ].Width;
498                         //-----------------
499                         #endregion
500                         #region [ 譜面拡大率 ]
501                         //-----------------
502                         this.appアプリ設定.HViewScaleIndex =
503                                 this.toolStripComboBox譜面拡大率.SelectedIndex;
504                         //-----------------
505                         #endregion
506                         #region [ ガイド間隔 ]
507                         //-----------------
508                         this.appアプリ設定.GuideIndex =
509                                 this.toolStripComboBoxガイド間隔.SelectedIndex;
510                         //-----------------
511                         #endregion
512                         #region [ 作業フォルダ ]
513                         //-----------------
514                         this.appアプリ設定.LastWorkFolder =
515                                 this.str作業フォルダ名;
516                         //-----------------
517                         #endregion
518                         #region [ レーン表示/非表示 #26005 2011.8.29 yyagi; added ]
519                         this.appアプリ設定.LanesInfo.Clear();
520                         foreach ( DTXCreator.譜面.Cレーン c in this.mgr譜面管理者.listレーン )
521                         {
522                                 this.appアプリ設定.AddLanesInfo( c.strレーン名, c.bIsVisible );
523                         }
524                         #endregion
525                         #region [ MIDIインポートフォルダ関連 ]
526                         //-----------------
527                         this.appアプリ設定.LastMIDIImportFolder = this.strMIDIインポートフォルダ;
528                         this.appアプリ設定.LastMIDIImportSettingsFile = this.strMIDIインポート設定ファイル;
529                         //-----------------
530                         #endregion
531
532                         // 保存する。
533
534                         #region [ アプリ設定をXML形式ファイルで出力する。 ]
535                         //-----------------
536                         var serializer = new XmlSerializer( typeof( AppSetting ) );
537                         using ( var stream = new FileStream( str設定ファイル名, FileMode.Create ) )              // #33204 2014.2.13 yyagi usingを使って、エラー発生時のファイルロックを回避
538                         {
539                                 serializer.Serialize( (Stream) stream, this.appアプリ設定 );
540                         }
541                         //-----------------
542                         #endregion
543                 }
544                 //-----------------
545                 #endregion
546                 #region [ 新規作成 ]
547                 //-----------------
548                 public void tシナリオ_新規作成()
549                 {
550                         // 作成前の保存確認。
551
552                         #region [ 未保存なら保存する。→ キャンセルされた場合はここで中断。]
553                         //-----------------
554                         if( this.t未保存なら保存する() == DialogResult.Cancel )
555                                 return; // 中断
556                         //-----------------
557                         #endregion
558
559
560                         // 新規作成。
561
562                         #region [「初期化中です」ポップアップを表示する。]
563                         //-----------------
564                         this.dlgチップパレット.t一時的に隠蔽する();
565
566                         Cメッセージポップアップ msg
567                                 = new Cメッセージポップアップ( Resources.str初期化中ですMSG + Environment.NewLine + Resources.strしばらくお待ち下さいMSG );
568                         msg.Owner = this;
569                         msg.Show();
570                         msg.Refresh();
571                         //-----------------
572                         #endregion
573
574                         this.t譜面を初期化する();
575
576                         #region [「初期化中です」ポップアップを閉じる。]
577                         //-----------------
578                         msg.Close();
579                         this.dlgチップパレット.t一時的な隠蔽を解除する();
580
581                         this.Refresh();                 // リスト内容等を消すために再描画
582                         //-----------------
583                         #endregion
584                 }
585                 private void t譜面を初期化する()
586                 {
587                         this.strDTXファイル名 = "";
588
589                         // 画面項目の初期化。
590
591                         #region [ 基本情報タブの初期化 ]
592                         //-----------------
593                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBox曲名.Clear();
594                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBox製作者.Clear();
595                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxGenre.Clear();
596                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxコメント.Clear();
597                         CUndoRedo管理.bUndoRedoした直後 = true;   this.numericUpDownBPM.Value = 120.0M;
598                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxDLEVEL.Text = "50";
599                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxGLEVEL.Text = "0";
600                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxBLEVEL.Text = "0";
601                         CUndoRedo管理.bUndoRedoした直後 = true;   this.hScrollBarDLEVEL.Value = 50;
602                         CUndoRedo管理.bUndoRedoした直後 = true;   this.hScrollBarGLEVEL.Value = 0;
603                         CUndoRedo管理.bUndoRedoした直後 = true;   this.hScrollBarBLEVEL.Value = 0;
604                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxパネル.Clear();
605                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxPREVIEW.Clear();
606                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxPREIMAGE.Clear();
607                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxSTAGEFILE.Clear();
608                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxBACKGROUND.Clear();
609                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBoxRESULTIMAGE.Clear();
610                         CUndoRedo管理.bUndoRedoした直後 = true; this.check556x710BGAAVI.Checked = false;
611                         //-----------------
612                         #endregion
613                         
614                         #region [ WAVタブ・BMPタブ・AVIタブの初期化 ]
615                         //-----------------
616                         this.listViewWAVリスト.Items.Clear();
617                         this.mgrWAVリスト管理者 = new CWAVリスト管理( this, this.listViewWAVリスト );
618
619                         this.listViewBMPリスト.Items.Clear();
620                         this.mgrBMPリスト管理者 = new CBMPリスト管理( this, this.listViewBMPリスト );
621
622                         this.listViewAVIリスト.Items.Clear();
623                         this.mgrAVIリスト管理者 = new CAVIリスト管理( this, this.listViewAVIリスト );
624
625                         this.tWAV_BMP_AVIリストのカーソルを全部同じ行に合わせる( 0 );
626                         //-----------------
627                         #endregion
628                         
629                         #region [ 自由入力タブの初期化 ]
630                         //-----------------
631                         CUndoRedo管理.bUndoRedoした直後 = true;   this.textBox自由入力欄.Clear();
632                         //-----------------
633                         #endregion
634
635                         #region [ チップパレットの初期化 ]
636                         //-----------------
637                         if( this.dlgチップパレット != null )
638                                 this.dlgチップパレット.Close();
639
640                         this.dlgチップパレット = new Cチップパレット( this );
641                         this.dlgチップパレット.Left = this.Left + ( this.Width - this.dlgチップパレット.Width ) / 2;
642                         this.dlgチップパレット.Top = this.Top + ( this.Height - this.dlgチップパレット.Height ) / 2;
643                         this.dlgチップパレット.Owner = this;
644
645                         if( this.toolStripButtonチップパレット.CheckState == CheckState.Checked )
646                                 this.dlgチップパレット.t表示する();
647                         //-----------------
648                         #endregion
649
650                         #region [ 譜面の生成・初期化 ]
651                         //-----------------
652                         if ( this.mgr譜面管理者 == null )          // 初回起動時は、レーン表示有無の構成に初期値を使用(して、後でDTXCreatorConfig.settingsのものに置き換える)
653                         {
654                                 this.mgr譜面管理者 = new C譜面管理( this );
655                                 this.mgr譜面管理者.t初期化();
656                         }
657                         else                                                                    // 起動後のdtxファイル読み込み等の場合は、直前のレーン表示有無の構成を踏襲する
658                         {
659                                 #region [ レーン表示/非表示状態の待避 #26005 2011.8.30 yyagi; added ]
660                                 List<Cレーン> lc = new List<Cレーン>(this.mgr譜面管理者.listレーン);
661                                 #endregion
662
663                                 this.mgr譜面管理者 = new C譜面管理( this );
664                                 this.mgr譜面管理者.t初期化();
665
666                                 #region [ レーン表示/非表示の反映 #26005 2011.8.30 yyagi; added ]
667                                 for ( int i = 0; i < this.mgr譜面管理者.listレーン.Count; i++ )
668                                 {
669                                         this.mgr譜面管理者.listレーン[ i ].bIsVisible = lc[ i ].bIsVisible;
670                                 }
671                                 this.mgr譜面管理者.tRefreshDisplayLanes();
672                                 #endregion
673                         }
674                         //-----------------
675                         #endregion
676
677                         #region [ DTXViewer 関連 GUI の初期化 ]
678                         //-----------------
679                         this.tDTXV演奏関連のボタンとメニューのEnabledの設定();
680                         //-----------------
681                         #endregion
682
683                         #region [ ガイド間隔の初期値を設定する。]
684                         //-----------------
685                         this.tガイド間隔を変更する( 16 );
686                         //-----------------
687                         #endregion
688
689
690                         // 内部処理の初期化。
691
692                         #region [ Undo/Redoリストのリセット ]
693                         //-----------------
694                         this.mgrUndoRedo管理者 = new CUndoRedo管理();
695
696                         CUndoRedo管理.bUndoRedoした直後 = false;
697                         this.tUndoRedo用GUIの有効無効を設定する();
698                         //-----------------
699                         #endregion
700
701                         #region [ 「2大モード」の管理者を生成、初期モードは、設定値から取得する・・・が、起動時は譜面生成後に設定値を読みだすので、設定値読み出し後に再設定すること。。]
702                         //-----------------
703                         this.mgr選択モード管理者 = new C選択モード管理( this );
704                         this.mgr編集モード管理者 = new C編集モード管理( this );
705
706                         if ( this.appアプリ設定.InitialOperationMode )
707                         {
708                                 this.t選択モードにする();
709                         }
710                         else
711                         {
712                                 this.t編集モードにする();
713                         }
714                         //-----------------
715                         #endregion
716
717
718                         // 上記のプロパティ変更操作により未保存フラグがtrueになってしまってるので、元に戻す。
719
720                         #region [ 未保存フラグをクリアする。]
721                         //-----------------
722                         this.b未保存 = false;
723                         //-----------------
724                         #endregion
725                         #region [ 再生制御用フラグを立てる。(DTXVに必ずリロードさせるため) ]
726                         //-----------------
727                         this.bDTXファイルを開いた = true;
728                         //-----------------
729                         #endregion
730                 }
731                 //-----------------
732                 #endregion
733                 #region [ 開く ]
734                 //-----------------
735                 private void tシナリオ_開く()
736                 {
737                         // 作成前の保存確認。
738
739                         #region [ 未保存なら保存する。→ キャンセルされた場合はここで中断。]
740                         //-----------------
741                         if( this.t未保存なら保存する() == DialogResult.Cancel )
742                                 return; // 中断
743                         //-----------------
744                         #endregion
745
746
747                         // 開くファイルを選択させる。
748
749                         #region [ 「ファイルを開く」ダイアログでファイルを選択する。 ]
750                         //-----------------
751                         this.dlgチップパレット.t一時的に隠蔽する();
752
753                         OpenFileDialog dialog = new OpenFileDialog();
754                         dialog.Title = Resources.strDTXファイル選択ダイアログのタイトル;
755                         dialog.Filter = Resources.strDTXファイル選択ダイアログのフィルタ;
756                         dialog.FilterIndex = 1;
757                         dialog.InitialDirectory = this.str作業フォルダ名;
758                         DialogResult result = dialog.ShowDialog();
759
760                         this.dlgチップパレット.t一時的な隠蔽を解除する();
761                         this.Refresh();     // メインフォームを再描画してダイアログを完全に消す
762
763                         if( result != DialogResult.OK )
764                                 return;
765                         //-----------------
766                         #endregion
767
768
769                         // 選択されたファイルを読み込む。
770
771                         #region [ ファイルを読み込む。]
772                         //-----------------
773                         this.t演奏ファイルを開いて読み込む( dialog.FileName );
774                         //-----------------
775                         #endregion
776                 }
777                 private void tシナリオ_DragDropされたファイルを開く( string[] DropFiles )
778                 {
779                         // 開くファイルを決定する。
780
781                         #region [ Dropされたファイルが複数個ある → 先頭のファイルだけを有効とする。 ]
782                         //-----------------
783                         string strファイル名 = DropFiles[ 0 ];
784                         //-----------------
785                         #endregion
786
787
788                         // 開く前の保存確認。
789
790                         #region [ 未保存なら保存する。→ キャンセルされた場合はここで中断。]
791                         //-----------------
792                         if( this.t未保存なら保存する() == DialogResult.Cancel )
793                                 return; // 中断
794                         //-----------------
795                         #endregion
796
797
798                         // Drop されたファイルを読み込む。
799
800                         #region [ ファイルを読み込む。]
801                         //-----------------
802                         string strExt = Path.GetExtension( strファイル名 ).ToLower();
803
804                         if ( strExt.Equals(".dtx") || strExt.Equals(".gda") || strExt.Equals(".g2d") || strExt.Equals(".bms") || strExt.Equals(".bme") )
805                         {
806                                 this.t演奏ファイルを開いて読み込む( strファイル名 );
807                         }
808                         else if (strExt.Equals(".smf") || strExt.Equals(".mid"))
809                         {
810                                 this.mgrMIDIインポート管理者.tMIDIインポート管理を開く( strファイル名 );
811                                 this.mgr譜面管理者.tRefreshDisplayLanes(); // レーンの表示/非表示切り替えに備えて追加
812                         }
813                         else
814                         {
815                                 MessageBox.Show(
816                                         Resources.strDTXファイルではありませんMSG,
817                                         Resources.str確認ダイアログのタイトル,
818                                         MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1 );
819
820                                 return; // 中断
821                         }
822                         //-----------------
823                         #endregion
824                 }
825                 private void t演奏ファイルを開いて読み込む( string strファイル名 )
826                 {
827                         // 前処理。
828
829                         #region [ ファイルの存在を確認する。なかったらその旨を表示して中断する。]
830                         //-----------------
831                         if( !File.Exists( strファイル名 ) )
832                         {
833                                 MessageBox.Show(
834                                         Resources.strファイルが存在しませんMSG,
835                                         Resources.str確認ダイアログのタイトル,
836                                         MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1 );
837
838                                 return; // 中断
839                         }
840                         //-----------------
841                         #endregion
842
843                         #region [ 拡張子からデータ種別を判定する。]
844                         //-----------------
845                         
846                         CDTX入出力.E種別 e種別 = CDTX入出力.E種別.DTX;
847
848                         string str拡張子 = Path.GetExtension( strファイル名 );
849
850                         if( str拡張子.Equals( ".dtx", StringComparison.OrdinalIgnoreCase ) )
851                         {
852                                 e種別 = CDTX入出力.E種別.DTX;
853                         }
854                         else if( str拡張子.Equals( ".gda", StringComparison.OrdinalIgnoreCase ) )
855                         {
856                                 e種別 = CDTX入出力.E種別.GDA;
857                         }
858                         else if( str拡張子.Equals( ".g2d", StringComparison.OrdinalIgnoreCase ) )
859                         {
860                                 e種別 = CDTX入出力.E種別.G2D;
861                         }
862                         else if( str拡張子.Equals( ".bms", StringComparison.OrdinalIgnoreCase ) )
863                         {
864                                 e種別 = CDTX入出力.E種別.BMS;
865                         }
866                         else if( str拡張子.Equals( ".bme", StringComparison.OrdinalIgnoreCase ) )
867                         {
868                                 e種別 = CDTX入出力.E種別.BME;
869                         }
870                         else
871                         {
872                                 MessageBox.Show(
873                                         Resources.strDTXファイルではありませんMSG,
874                                         Resources.str確認ダイアログのタイトル,
875                                         MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1 );
876
877                                 return; // 中断
878                         }
879                         //-----------------
880                         #endregion
881
882                         this.dlgチップパレット.t一時的に隠蔽する();
883
884                         #region [「読み込み中です」ポップアップを表示する。]
885                         //-----------------
886                         Cメッセージポップアップ msg
887                                 = new Cメッセージポップアップ( Resources.str読み込み中ですMSG + Environment.NewLine + Resources.strしばらくお待ち下さいMSG );
888                         msg.Owner = this;
889                         msg.Show();
890                         msg.Refresh();
891                         //-----------------
892                         #endregion
893
894
895                         // 読み込む。
896
897
898                         this.t譜面を初期化する();
899
900                         #region [ DTXファイルを読み込む。]
901                         //-----------------
902
903                         // 全部を1つの string として読み込む。
904
905                         StreamReader reader = new StreamReader( strファイル名, Encoding.GetEncoding( 932/*Shift-JIS*/ ) );
906                         string str全入力文字列 = reader.ReadToEnd();
907                         reader.Close();
908
909
910                         // その string から DTX データを読み込む。
911
912                         new CDTX入出力( this ).tDTX入力( e種別, ref str全入力文字列 );
913
914
915                         // ファイル名、作業フォルダ名を更新する。
916
917                         this.strDTXファイル名 = Path.ChangeExtension( Path.GetFileName( strファイル名 ), ".dtx" );            // 拡張子は強制的に .dtx に変更。
918                         this.str作業フォルダ名 = Path.GetDirectoryName( strファイル名 ) + @"\";             // 読み込み後、カレントフォルダは、作業ファイルのあるフォルダに移動する。
919                                                                                                                                                                                 // #35399: カレントディレクトリの変更はしない。.NET4以降でbuildしたDTXMania本体で再生できなくなるため。
920                         //-----------------
921                         #endregion
922
923                         #region [ 読み込んだファイルを [ファイル]メニューの最近使ったファイル一覧に追加する。]
924                         //-----------------
925                         this.appアプリ設定.AddRecentUsedFile( this.str作業フォルダ名 + this.strDTXファイル名 );
926                         this.t最近使ったファイルをFileメニューへ追加する();
927                         //-----------------
928                         #endregion
929
930                         #region [ DTX以外を読み込んだ場合は、(DTXに変換されているので)最初から未保存フラグを立てる。]
931                         //-----------------
932                         if( e種別 != CDTX入出力.E種別.DTX )
933                                 this.b未保存 = true;
934                         //-----------------
935                         #endregion
936
937
938                         #region [「読み込み中です」ポップアップを閉じる。 ]
939                         //-----------------
940                         msg.Close();
941                         this.Refresh(); // リスト内容等を消すために再描画する。
942                         //-----------------
943                         #endregion
944
945                         #region [ 未保存フラグをクリアする。]
946                         //-----------------
947                         this.b未保存 = true; // ウィンドウタイトルを書き換えるため、一度未保存フラグをtrueにして b未保存の setter を作動させる。
948                         this.b未保存 = false;
949                         //-----------------
950                         #endregion
951                 }
952                 //-----------------
953                 #endregion
954                 #region [ 上書き保存/名前をつけて保存 ]
955                 //-----------------
956                 private void tシナリオ_上書き保存()
957                 {
958                         // 前処理。
959                         bool bDoSave = true;
960
961                         this.dlgチップパレット.t一時的に隠蔽する();
962
963                         #region [「保存中です」ポップアップを表示する。 ]
964                         //-----------------
965                         var msg = new Cメッセージポップアップ( Resources.str保存中ですMSG + Environment.NewLine + Resources.strしばらくお待ち下さいMSG );
966                         msg.Owner = this;
967                         msg.Show();
968                         msg.Refresh();
969                         //-----------------
970                         #endregion
971
972                         #region [ ファイル名がない → 初めての保存と見なし、ファイル保存ダイアログで保存ファイル名を指定させる。 ]
973                         //-----------------
974                         if( string.IsNullOrEmpty( this.strDTXファイル名 ) )
975                         {
976                                 // ダイアログでファイル名を取得する。
977
978                                 string str絶対パスファイル名 = this.tファイル保存ダイアログを開いてファイル名を取得する();
979
980                                 if (string.IsNullOrEmpty(str絶対パスファイル名))
981                                 {
982                                         bDoSave = false;
983                                 }
984                                 else
985                                 {
986                                         //this.str作業フォルダ名 = Directory.GetCurrentDirectory() + @"\";       // ダイアログでディレクトリを変更した場合、カレントディレクトリも変更されている。
987                                         this.str作業フォルダ名 = Path.GetDirectoryName(str絶対パスファイル名) + @"\";
988                                         this.strDTXファイル名 = Path.GetFileName(str絶対パスファイル名);
989
990                                         // WAV・BMP・AVIリストにあるすべてのファイル名を、作業フォルダに対する相対パスに変換する。
991                                         this.mgrWAVリスト管理者.tファイル名の相対パス化(this.str作業フォルダ名);
992                                         this.mgrBMPリスト管理者.tファイル名の相対パス化(this.str作業フォルダ名);
993                                         this.mgrAVIリスト管理者.tファイル名の相対パス化(this.str作業フォルダ名);
994                                 }
995                         }
996                         //-----------------
997                         #endregion
998
999                         // DTXファイルへ出力。
1000                         if (bDoSave)
1001                         {
1002
1003                                 #region [ 選択モードだったなら選択を解除する。]
1004                                 //-----------------
1005                                 if (this.b選択モードである)
1006                                         this.mgr選択モード管理者.t全チップの選択を解除する();
1007                                 //-----------------
1008                                 #endregion
1009
1010                                 #region [ DTXファイルを出力する。]
1011                                 //-----------------
1012                                 var sw = new StreamWriter(this.str作業フォルダ名 + this.strDTXファイル名, false, Encoding.GetEncoding("utf-16"));
1013                                 new CDTX入出力(this).tDTX出力(sw);
1014                                 sw.Close();
1015                                 //-----------------
1016                                 #endregion
1017
1018                                 #region [ 出力したファイルのパスを、[ファイル]メニューの最近使ったファイル一覧に追加する。 ]
1019                                 //-----------------
1020                                 this.appアプリ設定.AddRecentUsedFile(this.str作業フォルダ名 + this.strDTXファイル名);
1021                                 this.t最近使ったファイルをFileメニューへ追加する();
1022                                 //-----------------
1023                                 #endregion
1024
1025                                 #region [ Viewer用の一時ファイルを削除する (修正+保存、直後のViewer再生時に、直前の修正が反映されなくなることへの対応) ]
1026                                 tViewer用の一時ファイルを削除する();
1027                                 #endregion
1028
1029                                 // 後処理。
1030                                 this.b未保存 = false;
1031                         }
1032
1033                         #region [「保存中です」ポップアップを閉じる。]
1034                         //-----------------
1035                         msg.Close();
1036                         this.Refresh();         // リスト内容等を消すために再描画する。
1037                         //-----------------
1038                         #endregion
1039
1040                         this.dlgチップパレット.t一時的な隠蔽を解除する();
1041                 }
1042                 private void tシナリオ_名前をつけて保存()
1043                 {
1044                         // 前処理。
1045
1046                         #region [ ユーザに保存ファイル名を入力させる。]
1047                         //-----------------
1048                         // ファイル保存ダイアログを表示し、出力するファイル名を指定させる。キャンセルされたらここで中断。
1049
1050                         string str絶対パスファイル名 = this.tファイル保存ダイアログを開いてファイル名を取得する();
1051                         if( string.IsNullOrEmpty( str絶対パスファイル名 ) )
1052                                 return; // 中断
1053
1054
1055                         // フォルダ名とファイル名を更新。
1056
1057                         //this.str作業フォルダ名 = Directory.GetCurrentDirectory() + @"\";       // ダイアログでディレクトリを変更した場合は、カレントディレクトリも変更されている。
1058                         this.str作業フォルダ名 = Path.GetDirectoryName(str絶対パスファイル名) + @"\";
1059                         this.strDTXファイル名 = Path.GetFileName( str絶対パスファイル名 );
1060                         //-----------------
1061                         #endregion
1062
1063                         #region [ WAV・BMP・AVIリストにあるすべてのファイル名を、作業フォルダに対する相対パスに変換する。 ]
1064                         //-----------------
1065                         this.mgrWAVリスト管理者.tファイル名の相対パス化( this.str作業フォルダ名 );
1066                         this.mgrBMPリスト管理者.tファイル名の相対パス化( this.str作業フォルダ名 );
1067                         this.mgrAVIリスト管理者.tファイル名の相対パス化( this.str作業フォルダ名 );
1068                         //-----------------
1069                         #endregion
1070
1071
1072                         // 保存する。
1073                         
1074                         this.tシナリオ_上書き保存();
1075
1076
1077                         // 後処理。
1078
1079                         this.b未保存 = true; // ウィンドウタイトルに表示されているファイル名を変更するため一度 true にする。
1080                         this.b未保存 = false;
1081                 }
1082                 private string tファイル保存ダイアログを開いてファイル名を取得する()
1083                 {
1084                         // ダイアログでファイル名を取得。
1085
1086                         this.dlgチップパレット.t一時的に隠蔽する();
1087
1088                         string _title = (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName == "ja") ?
1089                                 "名前を付けて保存" : "Save As";
1090
1091                         string _filter = (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName == "ja") ?
1092                                 "DTXファイル(*.dtx)|*.dtx" : "DTX file(*.dtx)|*.dtx";
1093
1094                         var dialog = new SaveFileDialog() {
1095                                 Title = _title,
1096                                 Filter = _filter,
1097                                 FilterIndex = 1,
1098                                 InitialDirectory = this.str作業フォルダ名
1099                         };
1100                         DialogResult result = dialog.ShowDialog();
1101
1102                         this.dlgチップパレット.t一時的な隠蔽を解除する();
1103
1104
1105                         // 画面を再描画。
1106
1107                         this.Refresh();
1108
1109
1110                         // キャンセルされたら "" を返す。
1111
1112                         if( result != DialogResult.OK )
1113                                 return "";
1114
1115
1116                         // ファイルの拡張子を .dtx に変更。
1117
1118                         string fileName = dialog.FileName;
1119                         if( Path.GetExtension( fileName ).Length == 0 )
1120                                 fileName = Path.ChangeExtension( fileName, ".dtx" );
1121
1122                         return fileName;
1123                 }
1124                 //-----------------
1125                 #endregion
1126                 #region [ 終了 ]
1127                 //-----------------
1128                 private void tシナリオ_終了()
1129                 {
1130                         // ウィンドウを閉じる。
1131
1132                         this.Close();
1133                 }
1134                 //-----------------
1135                 #endregion
1136                 #region [ 検索/置換 ]
1137                 //-----------------
1138                 private void tシナリオ_検索()
1139                 {
1140                         this.mgr選択モード管理者.t検索する();       // モードによらず、検索はすべて選択モード管理者が行う。
1141                 }
1142                 private void tシナリオ_置換()
1143                 {
1144                         this.mgr選択モード管理者.t置換する();       // モードによらず、置換はすべて選択モード管理者が行う。
1145                 }
1146                 //-----------------
1147                 #endregion
1148                 #region [ 小節長変更/小節の挿入/小節の削除 ]
1149                 //-----------------
1150                 private void tシナリオ_小節長を変更する( C小節 cs )
1151                 {
1152                         // 前処理。
1153
1154                         #region [ 小節長をユーザに入力させる。]
1155                         //-----------------
1156
1157                         // 小節長ダイアログを表示し、小節長を取得する。
1158
1159                         this.dlgチップパレット.t一時的に隠蔽する();
1160
1161                         var dlg = new C小節長変更ダイアログ( cs.n小節番号0to3599 );
1162                         dlg.f倍率 = cs.f小節長倍率;
1163                         dlg.b後続変更 = false;
1164
1165                         this.dlgチップパレット.t一時的な隠蔽を解除する();
1166
1167
1168                         // キャンセルされたらここで中断。
1169                         if( dlg.ShowDialog() != DialogResult.OK )
1170                                 return;
1171
1172                         //-----------------
1173                         #endregion
1174
1175
1176                         // 小節長を変更。
1177
1178                         //-----------------
1179                         int n変更開始小節番号 = cs.n小節番号0to3599;
1180                         int n変更終了小節番号 = ( dlg.b後続変更 ) ? this.mgr譜面管理者.n現在の最大の小節番号を返す() : cs.n小節番号0to3599;
1181
1182                         #region [ BEATレーンをすべてバックアップ(コピー)しておく。小節長変更でBEATチップが削除されると困るので。]
1183                         int laneBEAT = this.mgr譜面管理者.nレーン名に対応するレーン番号を返す( "BEAT" );
1184                         List<Cチップ> listBEATチップ = new List<Cチップ>();
1185                         foreach ( KeyValuePair<int, C小節> pair in this.mgr譜面管理者.dic小節 )
1186                         {
1187                                 C小節 c小節 = pair.Value;
1188                                 for ( int index = 0; index < c小節.listチップ.Count; index++ )
1189                                 {
1190                                         if ( c小節.listチップ[ index ].nレーン番号0to == laneBEAT )
1191                                         {
1192                                                 listBEATチップ.Add( c小節.listチップ[ index ] );
1193                                         }
1194                                 }
1195                         }
1196                         #endregion
1197
1198                         #region [ 小節長変更を実行する ]
1199                         for ( int n小節番号 = n変更開始小節番号; n小節番号 <= n変更終了小節番号; n小節番号++ )
1200                         {
1201                                 #region [ 指定した小節が存在しなければ、中断 ]
1202                                 C小節 c小節 = this.mgr譜面管理者.p小節を返す( n変更開始小節番号 );
1203                                 if ( c小節 == null )
1204                                 {
1205                                         return; // 中断
1206                                 }
1207                                 #endregion
1208
1209                                 int n旧Grid数 = (int) ( c小節.f小節長倍率 * CWholeNoteDivision.n分解能 + 0.5 );
1210                                 int n新Grid数 = (int) ( dlg.f倍率 * CWholeNoteDivision.n分解能 + 0.5 );
1211                                 int nGrid増減 = n旧Grid数 - n新Grid数;
1212
1213                                 this.t小節長を変更する_小節単位( n小節番号, dlg.f倍率 );
1214
1215                                 // そして、Gridの増減があった分だけ、コピーしたBEATチップのGridを増減する
1216                                 int nGrid_BAR = this.mgr譜面管理者.n譜面先頭からみた小節先頭の位置gridを返す( n変更開始小節番号 );
1217                                 for ( int index = 0; index < listBEATチップ.Count; index++ )
1218                                 {
1219                                         // Gridを増減するのは、小節長変更した小節以降のチップだけ。
1220                                         // 更に、小節長変更した小節上では、新しい小節長で溢れた分のチップだけGridを増減する。
1221                                         // (この条件で、Grid数が増えた場合も対応できている)
1222                                         if ( 
1223                                                 ( n小節番号 > n変更開始小節番号 ) ||
1224                                                 ( ( n小節番号 == n変更開始小節番号 ) && ( nGrid_BAR + n新Grid数 < listBEATチップ[ index ].n位置grid ) )
1225                                         )
1226                                         {
1227                                                 Cチップ cc = new Cチップ();
1228                                                 cc.tコピーfrom( listBEATチップ[ index ] );
1229                                                 cc.n位置grid += nGrid増減;
1230                                                 listBEATチップ[ index ] = cc;
1231                                         }
1232                                 }
1233
1234                         }
1235                         #endregion
1236                         //-----------------
1237         
1238                         this.mgrUndoRedo管理者.tトランザクション記録を開始する();
1239
1240                         #region [ BEATレーンのチップを全削除する ]
1241                         //this.mgr選択モード管理者.tレーン上の全チップを選択する( laneBEAT );
1242                         //this.tシナリオ・削除();
1243                         foreach ( KeyValuePair<int, C小節> pair in this.mgr譜面管理者.dic小節 )
1244                         {
1245                                 C小節 c小節 = pair.Value;
1246                                 for( int i = 0; i < c小節.listチップ.Count; i++ )
1247                                 {
1248                                         Cチップ cチップ = c小節.listチップ[ i ];
1249
1250                                         if( cチップ.nレーン番号0to == laneBEAT )
1251                                         {
1252                                                 #region [ UndoRedo リストにこの操作(チップ削除)を記録する。]
1253                                                 //-----------------
1254                                                 var cc = new Cチップ();
1255                                                 cc.tコピーfrom( cチップ );
1256                                         
1257                                                 var ur = new Cチップ配置用UndoRedo( c小節.n小節番号0to3599, cc );
1258
1259                                                 this.mgrUndoRedo管理者.tノードを追加する(
1260                                                         new CUndoRedoセル<Cチップ配置用UndoRedo>( 
1261                                                                 null, 
1262                                                                 new DGUndoを実行する<Cチップ配置用UndoRedo>( this.mgr譜面管理者.tチップ削除のUndo ), 
1263                                                                 new DGRedoを実行する<Cチップ配置用UndoRedo>( this.mgr譜面管理者.tチップ削除のRedo ),
1264                                                                 ur, ur ) );
1265                                                 //-----------------
1266                                                 #endregion
1267                 
1268                                                 // チップを小節のチップリストから削除する。
1269                                                 c小節.listチップ.RemoveAt( i );
1270
1271                                                 // リストが更新されたので、最初のチップから見直す。
1272                                                 i = -1;
1273                                         }
1274                                 }
1275                         }
1276                         #endregion
1277
1278                         #region [ コピーしておいた(そして、nGridを更新した))BEATチップを、BEATレーンに戻す ]
1279                         foreach ( Cチップ cチップ in listBEATチップ )
1280                         {
1281                                 this.mgr編集モード管理者.tBeatチップを配置する( cチップ.n位置grid, cチップ.n値_整数1to1295, cチップ.f値_浮動小数, cチップ.b裏 );
1282                         }
1283                         #endregion
1284
1285                         // 後処理。
1286                         this.b未保存 = true;
1287                         this.mgrUndoRedo管理者.tトランザクション記録を終了する();
1288                         listBEATチップ.Clear();
1289                         listBEATチップ = null;
1290
1291                         // 画面を再描画。
1292                         this.tUndoRedo用GUIの有効無効を設定する();
1293
1294                 }
1295                 public void t小節長を変更する_小節単位( int n小節番号, float f倍率 )
1296                 {
1297                         // 対象の小節を取得。
1298
1299                         #region [ 小節番号から小節オブジェクトを取得する。→ 指定された小節が存在しない場合はここで中断。]
1300                         //-----------------
1301                         
1302                         C小節 c小節 = this.mgr譜面管理者.p小節を返す( n小節番号 );
1303         
1304                         if( c小節 == null )
1305                                 return; // 中断
1306                         
1307                         //-----------------
1308                         #endregion
1309
1310
1311                         // 作業記録開始。
1312
1313                         this.mgrUndoRedo管理者.tトランザクション記録を開始する();
1314
1315                         #region [ UndoRedo リストにこの操作(小節長変更)を記録する。 ]
1316                         //-----------------
1317                         var ur変更前 = new C小節用UndoRedo( c小節.n小節番号0to3599, c小節.f小節長倍率 );
1318                         var ur変更後 = new C小節用UndoRedo( c小節.n小節番号0to3599, f倍率 );
1319
1320                         this.mgrUndoRedo管理者.tノードを追加する( 
1321                                 new CUndoRedoセル<C小節用UndoRedo>(
1322                                         null,
1323                                         new DGUndoを実行する<C小節用UndoRedo>( this.mgr譜面管理者.t小節長変更のUndo ),
1324                                         new DGRedoを実行する<C小節用UndoRedo>( this.mgr譜面管理者.t小節長変更のRedo ),
1325                                         ur変更前, ur変更後 ) );
1326                         //-----------------
1327                         #endregion
1328
1329
1330                         // 小節長倍率を変更。
1331
1332                         #region [ 小節長倍率を変更する。]
1333                         //-----------------
1334                         c小節.f小節長倍率 = f倍率;
1335                         //-----------------
1336                         #endregion
1337
1338                         #region [ 小節からはみ出したチップを削除する。チップの削除操作は Undo/Redo に記録する。]
1339
1340                         //-----------------
1341                         for( int i = 0; i < c小節.listチップ.Count; i++ )
1342                         {
1343                                 Cチップ cチップ = c小節.listチップ[ i ];
1344
1345                                 if( cチップ.n位置grid >= c小節.n小節長倍率を考慮した現在の小節の高さgrid )
1346                                 {
1347
1348                                         #region [ UndoRedo リストにこの操作(チップ削除)を記録する。]
1349                                         //-----------------
1350                                         var cc = new Cチップ();
1351                                         cc.tコピーfrom( cチップ );
1352                                         
1353                                         var ur = new Cチップ配置用UndoRedo( c小節.n小節番号0to3599, cc );
1354
1355                                         this.mgrUndoRedo管理者.tノードを追加する(
1356                                                 new CUndoRedoセル<Cチップ配置用UndoRedo>( 
1357                                                         null, 
1358                                                         new DGUndoを実行する<Cチップ配置用UndoRedo>( this.mgr譜面管理者.tチップ削除のUndo ), 
1359                                                         new DGRedoを実行する<Cチップ配置用UndoRedo>( this.mgr譜面管理者.tチップ削除のRedo ),
1360                                                         ur, ur ) );
1361                                         //-----------------
1362                                         #endregion
1363
1364                 
1365                                         // チップを小節のチップリストから削除する。
1366
1367                                         c小節.listチップ.RemoveAt( i );
1368
1369
1370                                         // リストが更新されたので、最初のチップから見直す。
1371                                         
1372                                         i = -1;
1373                                 }
1374                         }
1375                         //-----------------
1376                         #endregion
1377
1378
1379                         // 作業記録終了。
1380
1381                         this.mgrUndoRedo管理者.tトランザクション記録を終了する();
1382
1383
1384                         // 画面を再描画。
1385
1386                         this.tUndoRedo用GUIの有効無効を設定する();
1387                 }
1388                 private void tシナリオ_小節を挿入する( int n挿入位置の小節番号 )
1389                 {
1390                         // 作業を記録。
1391
1392                         #region [ UndoRedo リストにこの操作(小節挿入)を記録する。]
1393                         //-----------------
1394                         this.mgrUndoRedo管理者.tノードを追加する(
1395                                 new CUndoRedoセル<int>(
1396                                         null, 
1397                                         new DGUndoを実行する<int>( this.mgr譜面管理者.t小節挿入のUndo ),
1398                                         new DGRedoを実行する<int>( this.mgr譜面管理者.t小節挿入のRedo ),
1399                                         n挿入位置の小節番号, n挿入位置の小節番号 ) );
1400                         //-----------------
1401                         #endregion
1402
1403
1404                         // 小節を挿入。
1405                         
1406                         #region [ 挿入位置以降の小節を1つずつ後ろにずらす(小節番号を +1 していく)。 ]
1407                         //-----------------
1408                         for( int i = this.mgr譜面管理者.n現在の最大の小節番号を返す(); i >= n挿入位置の小節番号; i-- )
1409                         {
1410                                 // ずらす小節オブジェクトを取得する。
1411
1412                                 C小節 cずらす小節 = this.mgr譜面管理者.p小節を返す( i );
1413                                 if( cずらす小節 == null )
1414                                         continue;
1415
1416
1417                                 // 小節番号を+1する。
1418                                 
1419                                 this.mgr譜面管理者.dic小節.Remove( i );          // 小節番号は Dictionary のキー値であるため、番号が変われば再登録が必要。
1420                                 cずらす小節.n小節番号0to3599 = i + 1;
1421                                 this.mgr譜面管理者.dic小節.Add( cずらす小節.n小節番号0to3599, cずらす小節 );
1422                         }
1423                         //-----------------
1424                         #endregion
1425
1426                         #region [ 新しい小節を作成し、譜面の持つ小節リストに追加する。 ]
1427                         //-----------------
1428
1429                         // 小節を該当位置に追加する。
1430
1431                         this.mgr譜面管理者.dic小節.Add( n挿入位置の小節番号, new C小節( n挿入位置の小節番号 ) );
1432
1433         
1434                         // 譜面を再描画する。
1435
1436                         this.pictureBox譜面パネル.Refresh();
1437
1438                         //-----------------
1439                         #endregion
1440
1441
1442                         // 後処理。
1443
1444                         this.tUndoRedo用GUIの有効無効を設定する();
1445                         this.b未保存 = true;
1446                 }
1447                 private void tシナリオ_小節を削除する( int n削除位置の小節番号 )
1448                 {
1449                         // 作業記録開始。
1450
1451                         this.mgrUndoRedo管理者.tトランザクション記録を開始する();
1452
1453
1454                         // 小節を削除。
1455
1456                         #region [ 最大小節番号を取得する。]
1457                         //-----------------
1458                         int n最大小節番号 = this.mgr譜面管理者.n現在の最大の小節番号を返す();   // 小節を削除すると数が変わるので、削除前に取得する。
1459                         //-----------------
1460                         #endregion
1461                         #region [ 削除する小節オブジェクトを取得する。]
1462                         //-----------------
1463                         C小節 c削除する小節 = this.mgr譜面管理者.p小節を返す( n削除位置の小節番号 );
1464                         //-----------------
1465                         #endregion
1466
1467                         #region [ その小節が持っているチップを全て削除する。チップの削除作業は、Undo/Redoリストに記録する。]
1468                         //-----------------
1469                         
1470                         while( c削除する小節.listチップ.Count > 0 )
1471                         {
1472                                 #region [ UndoRedo リストにこの操作(チップ削除)を記録する。]
1473                                 //-----------------
1474                                 var cc = new Cチップ();
1475                                 cc.tコピーfrom( c削除する小節.listチップ[ 0 ] );
1476                                 var redo = new Cチップ配置用UndoRedo( c削除する小節.n小節番号0to3599, cc );
1477
1478                                 this.mgrUndoRedo管理者.tノードを追加する(
1479                                         new CUndoRedoセル<Cチップ配置用UndoRedo>(
1480                                                 null,
1481                                                 new DGUndoを実行する<Cチップ配置用UndoRedo>( this.mgr譜面管理者.tチップ削除のUndo ),
1482                                                 new DGRedoを実行する<Cチップ配置用UndoRedo>( this.mgr譜面管理者.tチップ削除のRedo ),
1483                                                 redo, redo ) );
1484                                 //-----------------
1485                                 #endregion
1486
1487                                 // 小節からチップを削除する。
1488
1489                                 c削除する小節.listチップ.RemoveAt( 0 );
1490                         }
1491                         
1492                         //-----------------
1493                         #endregion
1494
1495                         #region [ UndoRedo リストにこの操作(小節削除)を記録する。]
1496                         //-----------------
1497                         this.mgrUndoRedo管理者.tノードを追加する(
1498                                 new CUndoRedoセル<int>( 
1499                                         null, 
1500                                         new DGUndoを実行する<int>( this.mgr譜面管理者.t小節削除のUndo ),
1501                                         new DGRedoを実行する<int>( this.mgr譜面管理者.t小節削除のRedo ),
1502                                         n削除位置の小節番号, n削除位置の小節番号 ) );
1503                         //-----------------
1504                         #endregion
1505                         #region [ 該当小節を譜面の小節リストから削除する。]
1506                         //-----------------
1507                         this.mgr譜面管理者.dic小節.Remove( n削除位置の小節番号 );
1508                         //-----------------
1509                         #endregion
1510                         #region [ 削除した小節より後方にある小節を1つずつ前にずらす。(小節番号を -1 していく)]
1511                         //-----------------
1512
1513                         for( int i = n削除位置の小節番号 + 1; i <= n最大小節番号; i++ )
1514                         {
1515                                 // 小節オブジェクトを取得する。
1516
1517                                 C小節 cずらす小節 = this.mgr譜面管理者.p小節を返す( i );
1518                                 if( cずらす小節 == null )
1519                                         continue;
1520
1521                                 // 小節番号を-1する。
1522
1523                                 this.mgr譜面管理者.dic小節.Remove( i );          // 小節番号は Dictionary のキー値であるため、番号が変われば再登録が必要。
1524                                 cずらす小節.n小節番号0to3599--;
1525                                 this.mgr譜面管理者.dic小節.Add( cずらす小節.n小節番号0to3599, cずらす小節 );
1526                         }
1527
1528                         // 譜面内の小節が全部無くなったらさすがにまずいので、最低1個の小節は残す。
1529
1530                         if( this.mgr譜面管理者.dic小節.Count == 0 )
1531                                 this.mgr譜面管理者.dic小節.Add( 0, new C小節( 0 ) );
1532
1533                         //-----------------
1534                         #endregion
1535
1536
1537                         // 作業記録終了。
1538
1539                         this.mgrUndoRedo管理者.tトランザクション記録を終了する();
1540
1541         
1542                         // 後処理。
1543
1544                         this.tUndoRedo用GUIの有効無効を設定する();
1545                         this.pictureBox譜面パネル.Refresh();
1546                         this.b未保存 = true;
1547                 }
1548                 //-----------------
1549                 #endregion
1550                 #region [ 選択チップの切り取り/コピー/貼り付け/削除 ]
1551                 //-----------------
1552                 private void tシナリオ_切り取り()
1553                 {
1554                         // 事前チェック。
1555
1556                         #region [ 譜面にフォーカスが来てないなら何もしない。 ]
1557                         //-----------------
1558                         if( !this.pictureBox譜面パネル.Focused )
1559                                 return;
1560                         //-----------------
1561                         #endregion
1562
1563
1564                         // 切り取り。
1565
1566                         #region [ 切り取り = コピー + 削除 ]
1567                         //-----------------
1568                         this.tシナリオ_コピー();
1569                         this.tシナリオ_削除();
1570                         //-----------------
1571                         #endregion
1572                 }
1573                 private void tシナリオ_コピー()
1574                 {
1575                         // 事前チェック。
1576
1577                         #region [ 譜面にフォーカスが来てないなら何もしない。 ]
1578                         //-----------------
1579                         if( !this.pictureBox譜面パネル.Focused )
1580                                 return;
1581                         //-----------------
1582                         #endregion
1583
1584
1585                         // コピー。
1586
1587                         this.cbクリップボード.t現在選択されているチップをボードにコピーする();
1588
1589
1590                         // 画面を再描画。
1591
1592                         #region [ 画面を再描画する。]
1593                         //-----------------
1594                         this.t選択チップの有無に応じて編集用GUIの有効無効を設定する();
1595                         this.pictureBox譜面パネル.Refresh();
1596                         //-----------------
1597                         #endregion
1598                 }
1599                 private void tシナリオ_貼り付け( int n譜面先頭からの位置grid )
1600                 {
1601                         // 事前チェック。
1602
1603                         #region [ 譜面にフォーカスが来てないなら何もしない。 ]
1604                         //-----------------
1605                         if( !this.pictureBox譜面パネル.Focused )
1606                                 return;
1607                         //-----------------
1608                         #endregion
1609
1610
1611                         // 貼り付け。
1612
1613                         #region [ 貼り付け先の小節と貼り付け開始位置を取得する。]
1614                         //-----------------
1615                         C小節 c小節 = this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( n譜面先頭からの位置grid );
1616                         if( c小節 == null )
1617                                 return; // 中断
1618
1619                         int n小節先頭からの位置grid =
1620                                 n譜面先頭からの位置grid - this.mgr譜面管理者.n譜面先頭からみた小節先頭の位置gridを返す( c小節.n小節番号0to3599 );
1621                         //-----------------
1622                         #endregion
1623                         
1624                         #region [ クリップボードからチップを貼り付ける。]
1625                         //-----------------
1626                         this.cbクリップボード.tチップを指定位置から貼り付ける( c小節, n小節先頭からの位置grid );
1627                         //-----------------
1628                         #endregion
1629
1630
1631                         // 画面の再描画。
1632
1633                         #region [ 画面を再描画する。]
1634                         //-----------------
1635                         this.t選択チップの有無に応じて編集用GUIの有効無効を設定する();
1636                         this.pictureBox譜面パネル.Refresh();
1637                         //-----------------
1638                         #endregion
1639                 }
1640                 private void tシナリオ_削除()
1641                 {
1642                         // 事前チェック。
1643
1644                         #region [ 譜面にフォーカスが来てないなら何もしない。 ]
1645                         //-----------------
1646                         if( !this.pictureBox譜面パネル.Focused )
1647                                 return;
1648                         //-----------------
1649                         #endregion
1650
1651
1652                         // 操作記録開始。
1653
1654                         this.mgrUndoRedo管理者.tトランザクション記録を開始する();
1655
1656
1657                         // チップを削除。
1658
1659                         #region [ 譜面が持つすべての小節について、選択されているチップがあれば削除する。]
1660                         //-----------------
1661                         foreach( KeyValuePair<int, C小節> pair in this.mgr譜面管理者.dic小節 )
1662                         {
1663                                 C小節 c小節 = pair.Value;
1664
1665                                 bool b削除されたチップがある = false;
1666                                 bool b削除完了 = false;
1667                                 int laneBEAT  = this.mgr譜面管理者.nレーン名に対応するレーン番号を返す( "BEAT" );
1668                                 List<int> list削除処理済BEAT_index = new List<int>();
1669
1670                                 while( !b削除完了 )
1671                                 {
1672                                         #region [ 小節の持つチップのうち、選択されているチップがあれば削除してループする。なくなったら抜ける。]
1673                                         //-----------------
1674                                         
1675                                         b削除完了 = true;
1676
1677                                         // 小節が持つすべてのチップについて……
1678                                         foreach( Cチップ cチップ in c小節.listチップ )
1679                                         {
1680                                                 if( cチップ.b確定選択中 )
1681                                                 {
1682                                                         #region [ UndoRedo リストにこの操作(チップ削除)を記録する。]
1683                                                         //-----------------
1684                                                         var cc = new Cチップ();
1685                                                         cc.tコピーfrom( cチップ );
1686                                                         var redo = new Cチップ配置用UndoRedo( c小節.n小節番号0to3599, cc );
1687
1688                                                         this.mgrUndoRedo管理者.tノードを追加する(
1689                                                                 new CUndoRedoセル<Cチップ配置用UndoRedo>(
1690                                                                         null,
1691                                                                         new DGUndoを実行する<Cチップ配置用UndoRedo>( this.mgr譜面管理者.tチップ削除のUndo ),
1692                                                                         new DGRedoを実行する<Cチップ配置用UndoRedo>( this.mgr譜面管理者.tチップ削除のRedo ),
1693                                                                         redo, redo ) );
1694                                                         //-----------------
1695                                                         #endregion
1696
1697
1698                                                         #region [ チップオブジェクトを削除する。ただしBEATオブジェクトは削除禁止。表裏を反転するだけ。]
1699                                                         if ( cチップ.nレーン番号0to != laneBEAT )
1700                                                         {
1701                                                                 c小節.listチップ.Remove( cチップ );
1702
1703                                                                 // フラグを設定してループする。(foreachのlistを更新しているため)
1704                                                                 b削除完了 = false;          // まだ終わらんよ
1705                                                                 b削除されたチップがある = true;
1706                                                                 break;
1707                                                         }
1708                                                         else
1709                                                         {
1710                                                                 int p = c小節.listチップ.IndexOf( cチップ );
1711                                                                 if ( !list削除処理済BEAT_index.Contains( p ) )     // まだ裏表反転したことがないチップならば
1712                                                                 {
1713                                                                         cチップ.nチャンネル番号00toFF = ( cチップ.b裏 ) ? 0xF3 : 0xF8;            // 表裏反転
1714                                                                         cチップ.b裏 = !cチップ.b裏;
1715                                                                         c小節.listチップ[ p ] = cチップ;
1716                                                                         list削除処理済BEAT_index.Add( p );
1717
1718                                                                         // フラグを設定してループする。(foreachのlistを更新しているため)
1719                                                                         b削除完了 = false;          // まだ終わらんよ
1720                                                                         b削除されたチップがある = true;
1721                                                                         break;
1722                                                                 }
1723                                                         }
1724                                                         #endregion
1725                                                 }
1726                                         }
1727                                         //-----------------
1728                                         #endregion
1729                                 }
1730                                 list削除処理済BEAT_index.Clear();
1731                                 list削除処理済BEAT_index = null;
1732
1733                                 #region [ 1つでもチップを削除したなら、未保存フラグを立てる。 ]
1734                                 //-----------------
1735                                 if( b削除されたチップがある )
1736                                         this.b未保存 = true;
1737                                 //-----------------
1738                                 #endregion
1739                         }
1740                         //-----------------
1741                         #endregion
1742
1743
1744                         // 操作記録終了。
1745
1746                         this.mgrUndoRedo管理者.tトランザクション記録を終了する();
1747
1748
1749                         // 画面を再描画する。
1750
1751                         this.tUndoRedo用GUIの有効無効を設定する();
1752                         this.t選択チップの有無に応じて編集用GUIの有効無効を設定する();
1753                         this.pictureBox譜面パネル.Refresh();
1754                 }
1755
1756                 internal struct Cc小節cチップ総tick
1757                 {
1758                         internal C小節   pC小節;
1759                         internal Cチップ pCチップ;
1760                         internal long    lTotalGrid;
1761
1762
1763                         internal Cc小節cチップ総tick(in C小節 _pC小節, in Cチップ _pCチップ, long _lTotalGrid)
1764                         {
1765                                 pC小節     = _pC小節;
1766                                 pCチップ   = _pCチップ;
1767                                 lTotalGrid = _lTotalGrid;
1768                         }
1769                 }
1770
1771                 private void tシナリオ_等間隔に配置()
1772                 {
1773                         #region [ 譜面にフォーカスが来てないなら何もしない。 ]
1774                         //-----------------
1775                         if (!this.pictureBox譜面パネル.Focused)
1776                                 return;
1777                         //-----------------
1778                         #endregion
1779
1780                         #region [ 譜面が持つすべての小節について、選択されているチップを走査しlist化する。]
1781                         //-----------------
1782
1783                         List<Cc小節cチップ総tick> listc小節cチップ数総tick = new List<Cc小節cチップ総tick>();
1784
1785                         foreach (KeyValuePair<int, C小節> pair in  this.mgr譜面管理者.dic小節)
1786                         {
1787                                 C小節 c小節 = pair.Value;
1788
1789                                 #region [ 小節の持つチップのうち、選択されているチップがあればlistにコピー(参照渡し)する。]
1790                                 //-----------------
1791                                 foreach (Cチップ cチップ in c小節.listチップ)
1792                                 {
1793                                         if (cチップ.b確定選択中)
1794                                         {
1795                                                 #region [ listにコピーする。]
1796                                                 var cl = new Cc小節cチップ総tick(in c小節, in cチップ, this.mgr譜面管理者.n譜面先頭からみた小節先頭の位置gridを返す(c小節.n小節番号0to3599) + cチップ.n位置grid);
1797                                                 listc小節cチップ数総tick.Add(cl);
1798                                                 #endregion
1799                                         }
1800                                 }
1801                                 //-----------------
1802                                 #endregion
1803                         }
1804                         //-----------------
1805                         #endregion
1806
1807                         #region [ 選択されたチップの中で、uniqueなgridがいくつかあるか数える (念のためlistをlTotalGrid順でソートする) ]
1808                         long lastTotalGrid = -1;
1809                         int  uniqueCount   = 0;
1810                         listc小節cチップ数総tick.Sort
1811                                 ((a, b) =>
1812                                 {
1813                                         return (int)(a.lTotalGrid - b.lTotalGrid);
1814                                 }
1815                                 );
1816                         foreach ( var c in listc小節cチップ数総tick)
1817                         {
1818                                 if (c.lTotalGrid != lastTotalGrid)
1819                                 {
1820                                         uniqueCount++;
1821                                         lastTotalGrid = c.lTotalGrid;
1822                                 }
1823                         }
1824                         #endregion
1825
1826                         #region [ ユニークなgridが0,1,2個の場合は意味がないので抜ける]
1827                         if (lastTotalGrid < 3)
1828                         {
1829                                 listc小節cチップ数総tick?.Clear();
1830                                 listc小節cチップ数総tick = null;
1831                                 return;
1832                         }
1833                         #endregion
1834
1835
1836                         #region [ ユニークなgridが3以上なら、最初と最後のチップのgrid差を測る ]
1837                         long gridTotalDuration =
1838                                 listc小節cチップ数総tick[ listc小節cチップ数総tick.Count - 1].lTotalGrid -
1839                                 listc小節cチップ数総tick[0].lTotalGrid;
1840                         #endregion
1841
1842
1843                         #region [ grid差を(チップ数-1)で割り、等分割の間隔を求める ]
1844                         float gridEachDuration = (float)gridTotalDuration / (uniqueCount - 1);
1845                         #endregion
1846
1847                         #region [ 最初と最後以外のチップを等間隔になるよう再配置する (誤差が大きくならないように注意) ]
1848
1849                         this.mgr選択モード管理者.t移動開始処理(new MouseEventArgs(MouseButtons.None, 0, 0, 0, 0));
1850
1851                         float newTotalGrid = listc小節cチップ数総tick[0].lTotalGrid;
1852                         lastTotalGrid      = listc小節cチップ数総tick[0].lTotalGrid;
1853                         int count2         = 0;
1854                         foreach (var c in listc小節cチップ数総tick)
1855                         {
1856                                 if (c.lTotalGrid != lastTotalGrid)
1857                                 {
1858                                         lastTotalGrid = c.lTotalGrid;
1859                                         newTotalGrid += gridEachDuration;
1860                                         count2++;
1861                                 }
1862                                 else
1863                                 if (count2 == 0)
1864                                 {
1865                                         continue;                                               // 最初のgridは再配置不要
1866                                 }
1867
1868                                 if (count2 >= uniqueCount) break;       // 最後のgridも再配置不要のため、処理終了
1869
1870                                 this.mgr選択モード管理者.tチップを縦に移動する(
1871                                         c.pCチップ,
1872                                         (int)(newTotalGrid - c.lTotalGrid),
1873                                         c.pC小節);
1874                         }
1875                         this.mgr選択モード管理者.t移動終了処理(new MouseEventArgs(MouseButtons.None, 0, 0, 0, 0));
1876
1877                         listc小節cチップ数総tick?.Clear();
1878                         listc小節cチップ数総tick = null;
1879                         #endregion
1880
1881
1882                         #region [ 未保存フラグを立てる。 ]
1883                         //-----------------
1884                         this.b未保存 = true;
1885                         //-----------------
1886                         #endregion
1887
1888                         #region [ 画面を再描画する。]
1889                         this.tUndoRedo用GUIの有効無効を設定する();
1890                         this.t選択チップの有無に応じて編集用GUIの有効無効を設定する();
1891                         this.pictureBox譜面パネル.Refresh();
1892                         #endregion
1893                 }
1894                 //-----------------
1895                 #endregion
1896                 #region [ DTXViewer での再生・停止 ]
1897                 //-----------------
1898                 private void tシナリオ_Viewerで最初から再生する()
1899                 {
1900                         #region [ DTXViewer 用の一時ファイルを出力する。]
1901                         //-----------------
1902                         this.tViewer用の一時ファイルを出力する( false, this.b未保存 | !this.b前回BGMありで再生した | this.b再生速度を変更した | this.bDTXファイルを開いた );
1903                         this.b前回BGMありで再生した = true;
1904                         //-----------------
1905                         #endregion
1906
1907                         #region [ 再生開始オプション引数に一時ファイルを指定して DTXViewer プロセスを起動する。]
1908                         //-----------------
1909                         try
1910                         {
1911                                 string strDTXViewerのパス = this.strDTXCのあるフォルダ名 + this.appアプリ設定.ViewerInfo.Path;
1912
1913                                 #region [ DTXViewer が起動していなければ起動する。]
1914                                 //-----------------
1915                                 // DTXManiaGR.exeはコンパクトモードで起動する必要があるため、「一旦起動してから再生オプションを渡す」やり方はやめる
1916                                 // Process.Start( strDTXViewerのパス ).WaitForInputIdle( 20 * 1000 );        // 起動完了まで最大20秒待つ
1917                                 //-----------------
1918                                 #endregion
1919                                 
1920                                 #region [ 実行中の DTXViewer に再生オプションを渡す。 ]
1921                                 //-----------------
1922                                 Process.Start( strDTXViewerのパス,
1923                                         this.appアプリ設定.ViewerInfo.PlaySoundOption + this.appアプリ設定.ViewerInfo.PlayStartOption + " " +
1924                                         "\"" + this.strViewer演奏用一時ファイル名 + "\""
1925                                         ).WaitForInputIdle( 20 * 1000 );
1926                                 //-----------------
1927                                 #endregion
1928                         }
1929                         catch( Exception )
1930                         {
1931                                 #region [ 失敗ダイアログを表示する。]
1932                                 //-----------------
1933                                 MessageBox.Show(
1934                                         Resources.strプロセスの起動に失敗しましたMSG,
1935                                         Resources.strエラーダイアログのタイトル,
1936                                         MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1 );
1937                                 //-----------------
1938                                 #endregion
1939                         }
1940                         //-----------------
1941                         #endregion
1942                 }
1943                 private void tシナリオ_Viewerで現在位置から再生する()
1944                 {
1945                         #region [ DTXViewer 用の一時ファイルを出力する。]
1946                         //-----------------
1947                         this.tViewer用の一時ファイルを出力する( false, this.b未保存 | !this.b前回BGMありで再生した | this.b再生速度を変更した | this.bDTXファイルを開いた );
1948                         this.b前回BGMありで再生した = true;
1949                         //-----------------
1950                         #endregion
1951
1952                         try
1953                         {
1954                                 string strDTXViewerのパス = this.strDTXCのあるフォルダ名 + this.appアプリ設定.ViewerInfo.Path;
1955
1956                                 #region [ DTXViewer が起動していなければ起動する。]
1957                                 //-----------------
1958                                 // DTXManiaGR.exeはコンパクトモードで起動する必要があるため、「一旦起動してから再生オプションを渡す」やり方はやめる
1959                                 // Process.Start( strDTXViewerのパス ).WaitForInputIdle( 20 * 1000 );        // 起動完了まで最大20秒待つ
1960                                 //-----------------
1961                                 #endregion
1962
1963                                 #region [ 実行中の DTXViewer に再生オプションを渡す。 ]
1964                                 //-----------------
1965                                 
1966                                 C小節 c小節 =
1967                                         this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( this.mgr譜面管理者.n現在の譜面表示下辺の譜面先頭からの位置grid );
1968                                 
1969                                 Process.Start( strDTXViewerのパス,
1970                                         this.appアプリ設定.ViewerInfo.PlaySoundOption + this.appアプリ設定.ViewerInfo.PlayStartFromOption + c小節.n小節番号0to3599 + " " +
1971                                         "\"" + this.strViewer演奏用一時ファイル名 + "\""
1972                                         ).WaitForInputIdle( 20 * 1000 );
1973                                 
1974                                 //-----------------
1975                                 #endregion
1976                         }
1977                         catch( Exception )
1978                         {
1979                                 #region [ 失敗ダイアログを表示する。]
1980                                 //-----------------
1981                                 MessageBox.Show(
1982                                         Resources.strプロセスの起動に失敗しましたMSG,
1983                                         Resources.strエラーダイアログのタイトル, 
1984                                         MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1 );
1985                                 //-----------------
1986                                 #endregion
1987                         }
1988                 }
1989                 private void tシナリオ_Viewerで現在位置からBGMのみ再生する()
1990                 {
1991                         #region [ DTXViewer 用の一時ファイルを出力する。]
1992                         //-----------------
1993                         this.tViewer用の一時ファイルを出力する( true, this.b未保存 | this.b前回BGMありで再生した | this.b再生速度を変更した | this.bDTXファイルを開いた );
1994                         this.b前回BGMありで再生した = false;
1995                         //-----------------
1996                         #endregion
1997
1998                         try
1999                         {
2000                                 string strDTXViewerのパス = this.strDTXCのあるフォルダ名 + this.appアプリ設定.ViewerInfo.Path;
2001
2002                                 #region [ DTXViewer が起動していなければ起動する。]
2003                                 //-----------------
2004                                 // DTXManiaGR.exeはコンパクトモードで起動する必要があるため、「一旦起動してから再生オプションを渡す」やり方はやめる
2005                                 // Process.Start( strDTXViewerのパス ).WaitForInputIdle( 20 * 1000 );        // 起動完了まで最大20秒待つ
2006                                 //-----------------
2007                                 #endregion
2008
2009                                 #region [ 実行中の DTXViewer に再生オプションを渡す。 ]
2010                                 //-----------------
2011                                 C小節 c小節 = this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( this.mgr譜面管理者.n現在の譜面表示下辺の譜面先頭からの位置grid );
2012                                 Process.Start( strDTXViewerのパス,
2013                                         this.appアプリ設定.ViewerInfo.PlaySoundOption + this.appアプリ設定.ViewerInfo.PlayStartFromOption + c小節.n小節番号0to3599 + " " +
2014                                         "\"" + this.strViewer演奏用一時ファイル名 + "\""
2015                                         ).WaitForInputIdle( 20 * 1000 );
2016                                 //-----------------
2017                                 #endregion
2018                         }
2019                         catch( Exception )
2020                         {
2021                                 #region [ 失敗ダイアログを表示する。]
2022                                 //-----------------
2023                                 MessageBox.Show(
2024                                         Resources.strプロセスの起動に失敗しましたMSG,
2025                                         Resources.strエラーダイアログのタイトル,
2026                                         MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1 );
2027                                 //-----------------
2028                                 #endregion
2029                         }
2030                 }
2031                 private void tシナリオ_Viewerを再生停止する()
2032                 {
2033                         try
2034                         {
2035                                 string strViewerのパス = this.strDTXCのあるフォルダ名 + this.appアプリ設定.ViewerInfo.Path;
2036
2037                                 #region [ 実行中の DTXViewer に再生停止オプションを渡す。 ]
2038                                 //-----------------
2039
2040                                 // 停止のときは1回のプロセス起動で完結(BMSV仕様)
2041
2042                                 Process.Start( strViewerのパス, this.appアプリ設定.ViewerInfo.PlayStopOption );
2043
2044                                 //-----------------
2045                                 #endregion
2046
2047                         }
2048                         catch( Exception )
2049                         {
2050                                 #region [ 失敗ダイアログを表示する。]
2051                                 //-----------------
2052                                 MessageBox.Show(
2053                                         Resources.strプロセスの起動に失敗しましたMSG,
2054                                         Resources.strエラーダイアログのタイトル,
2055                                         MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1 );
2056                                 //-----------------
2057                                 #endregion
2058                         }
2059                 }
2060
2061                 private string strViewer演奏用一時ファイル名 = "";
2062                 private void tViewer用の一時ファイルを出力する( bool bBGMのみ出力, bool b前回から更新があった )
2063                 {
2064                         // 一時ファイル名を自動生成。
2065
2066                         // 前回から更新がなければ(連続して再生ボタンを押した、など)、前回の生成ファイルをそのまま返す。
2067                         // (初めての再生の場合は、tempファイル未生成のため、このまま生成フローを続ける。)
2068                         if ( !b前回から更新があった && File.Exists( Path.Combine( this.mgr譜面管理者.strPATH_WAV, this.strViewer演奏用一時ファイル名 ) ) )
2069                         {
2070                                 return;
2071                         }
2072
2073                         // 再生速度変更フラグをリセット。
2074                         b再生速度を変更した = false;
2075                         bDTXファイルを開いた = false;
2076
2077                         //this.strViewer演奏用一時ファイル名 = Path.GetTempFileName();                        //
2078                         this.strViewer演奏用一時ファイル名 = makeTempDTX.GetTempFileName();           // #24746 2011.4.1 yyagi add; a countermeasure for temp-flooding
2079                         
2080                         // 一時ファイルにDTXを出力。
2081
2082                         this.mgr譜面管理者.strPATH_WAV = this.str作業フォルダ名;
2083
2084                         try
2085                         {
2086                                 #region [ もし小数点にコンマを使うcultureなら、一時的に(小数点を使う)"en-GB"に切り替える。(DTXVはピリオドしか使えないため) ]
2087                                 string currentCultureEnglishName = CultureInfo.CurrentCulture.Name;
2088                                 bool bSwitchCulture = false;
2089                                 if (CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator == ",")
2090                                 {
2091                                         Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB", false);  // #24241, #24790 2011.4.8 yyagi: switch culture where the country uses period as the decimal point
2092                                         bSwitchCulture = true;                                                                                                  // I mistook here using CurrentUICulture. Use CurrentCulture to work correctly.
2093                                 }
2094                                 #endregion
2095                                 #region [ 一時ファイルにDTXを出力する。 ]
2096                                 //-----------------
2097                                 StreamWriter sw = new StreamWriter( this.strViewer演奏用一時ファイル名, false, Encoding.GetEncoding( 0x3a4 ) );
2098                                 new CDTX入出力( this ).tDTX出力( sw, bBGMのみ出力 );
2099                                 sw.Close();
2100                                 //-----------------
2101                                 #endregion
2102                                 #region [ cultureを元に戻す。 ]
2103                                 if (bSwitchCulture)
2104                                 {
2105                                         Thread.CurrentThread.CurrentCulture = new CultureInfo(currentCultureEnglishName, false);
2106                                 }
2107                                 #endregion
2108                         }
2109                         finally
2110                         {
2111                                 this.mgr譜面管理者.strPATH_WAV = "";
2112                         }
2113                 }
2114                 private void tViewer用の一時ファイルを削除する()
2115                 {
2116                         this.strViewer演奏用一時ファイル名 = "";              // #35351 2015.7.23 yyagi add; to fix viewer plyback correctly just after save.
2117                 }
2118                 //-----------------
2119                 #endregion
2120                 #region [ Undo / Redo ]
2121                 //-----------------
2122                 private void tシナリオ_Undoする()
2123                 {
2124                         // Undo を実行する。
2125
2126                         #region [ Undo する対象を Undo/Redo リストから取得する。]
2127                         //-----------------
2128         
2129                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す();
2130
2131                         if( oセル仮想 == null )
2132                                 return;         // なければ中断
2133                         
2134                         //-----------------
2135                         #endregion
2136                         
2137                         oセル仮想.tUndoを実行する();
2138
2139
2140                         // GUIを再描画する。
2141
2142                         #region [ GUI を再描画する。]
2143                         //-----------------
2144                         this.tUndoRedo用GUIの有効無効を設定する();
2145                         this.t選択チップの有無に応じて編集用GUIの有効無効を設定する();
2146                         this.pictureBox譜面パネル.Refresh();
2147                         //-----------------
2148                         #endregion
2149                 }
2150                 private void tシナリオ_Redoする()
2151                 {
2152                         // Redo を実行する。
2153
2154                         #region [ Redo する対象を Undo/Redo リストから取得する。]
2155                         //-----------------
2156
2157                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tRedoするノードを取得して返す();
2158
2159                         if( oセル仮想 == null )
2160                                 return; // なければ中断
2161
2162                         //-----------------
2163                         #endregion
2164
2165                         oセル仮想.tRedoを実行する();
2166
2167
2168                         // GUI を再描画する。
2169
2170                         #region [ GUI を再描画する。]
2171                         //-----------------
2172                         this.tUndoRedo用GUIの有効無効を設定する();
2173                         this.t選択チップの有無に応じて編集用GUIの有効無効を設定する();
2174                         this.pictureBox譜面パネル.Refresh();
2175                         //-----------------
2176                         #endregion
2177                 }
2178                 //-----------------
2179                 #endregion
2180
2181
2182                 // メソッド
2183
2184                 public enum Eタブ種別 : int
2185                 {
2186                         基本情報 = 0,
2187                         WAV = 1,
2188                         BMP = 2,
2189                         AVI = 3,
2190                         自由入力 = 4
2191                 }
2192
2193                 public void t選択モードにする()
2194                 {
2195                         this.toolStripButton選択モード.CheckState = CheckState.Checked;
2196                         this.toolStripButton編集モード.CheckState = CheckState.Unchecked;
2197                         this.toolStripMenuItem選択モード.CheckState = CheckState.Checked;
2198                         this.toolStripMenuItem編集モード.CheckState = CheckState.Unchecked;
2199                 }
2200                 public void t編集モードにする()
2201                 {
2202                         this.mgr選択モード管理者.t全チップの選択を解除する();
2203                         this.pictureBox譜面パネル.Refresh();
2204                         this.toolStripButton選択モード.CheckState = CheckState.Unchecked;
2205                         this.toolStripButton編集モード.CheckState = CheckState.Checked;
2206                         this.toolStripMenuItem選択モード.CheckState = CheckState.Unchecked;
2207                         this.toolStripMenuItem編集モード.CheckState = CheckState.Checked;
2208                 }
2209                 public void t選択チップの有無に応じて編集用GUIの有効無効を設定する()
2210                 {
2211                         bool b譜面上に選択チップがある = this.b選択チップがある;
2212                         bool bクリップボードに選択チップがある = ( this.cbクリップボード != null ) && ( this.cbクリップボード.nセル数 > 0 );
2213
2214
2215                         // 編集メニュー
2216
2217                         this.toolStripMenuItemコピー.Enabled = b譜面上に選択チップがある;
2218                         this.toolStripMenuItem切り取り.Enabled = b譜面上に選択チップがある;
2219                         this.toolStripMenuItem貼り付け.Enabled = bクリップボードに選択チップがある;
2220                         this.toolStripMenuItem削除.Enabled = b譜面上に選択チップがある;
2221
2222
2223                         // ツールバー
2224
2225                         this.toolStripButtonコピー.Enabled = b譜面上に選択チップがある;
2226                         this.toolStripButton切り取り.Enabled = b譜面上に選択チップがある;
2227                         this.toolStripButton貼り付け.Enabled = bクリップボードに選択チップがある;
2228                         this.toolStripButton削除.Enabled = b譜面上に選択チップがある;
2229
2230         
2231                         // 右メニュー
2232
2233                         this.toolStripMenuItem選択チップのコピー.Enabled = b譜面上に選択チップがある;
2234                         this.toolStripMenuItem選択チップの切り取り.Enabled = b譜面上に選択チップがある;
2235                         this.toolStripMenuItem選択チップの貼り付け.Enabled = bクリップボードに選択チップがある;
2236                         this.toolStripMenuItem選択チップの削除.Enabled = b譜面上に選択チップがある;
2237                 }
2238                 public void t選択モードのコンテクストメニューを表示する( int x, int y )
2239                 {
2240                         // メニューの左上隅座標を控えておく。
2241
2242                         this.pt選択モードのコンテクストメニューを開いたときのマウスの位置 = new Point( x, y );
2243                         
2244                         #region [ クリックされた箇所のレーン番号を取得する。]
2245                         //-----------------
2246                         int lane = this.mgr譜面管理者.nX座標dotが位置するレーン番号を返す( pt選択モードのコンテクストメニューを開いたときのマウスの位置.X );
2247                         string strLane = (lane < 0)? "" : this.mgr譜面管理者.listレーン[ lane ].strレーン名;
2248                         //-----------------
2249                         #endregion
2250
2251                         #region [ クリックされた箇所の小節番号を取得する。]
2252                         //-----------------
2253                         int n譜面先頭からの位置grid = this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( pt選択モードのコンテクストメニューを開いたときのマウスの位置.Y );
2254                         C小節 csクリックされた小節 = this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( n譜面先頭からの位置grid );
2255                         if ( csクリックされた小節 == null ) return;            // 小節が生成されていないところで右クリックした場合は何もしない(NullReferenceException回避)
2256                         int nPartNo = csクリックされた小節.n小節番号0to3599;
2257                         string strPartNo = C変換.str小節番号を文字列3桁に変換して返す( nPartNo );
2258                         //-----------------
2259                         #endregion
2260
2261                         #region [ コンテクストメニューの[選択]項目に、レーン名と小節番号の情報をを付与する。 ]
2262                         int indexMenuLaneSelect1 = this.contextMenuStrip譜面右メニュー.Items.IndexOfKey( "toolStripMenuItemレーン内のすべてのチップの選択1" );
2263                         int indexMenuLaneSelect2 = this.contextMenuStrip譜面右メニュー.Items.IndexOfKey( "toolStripMenuItemレーン内のすべてのチップの選択_特定小節以降2" );
2264                         int indexMenuPartSelect = this.contextMenuStrip譜面右メニュー.Items.IndexOfKey( "toolStripMenuItem小節内のすべてのチップの選択" );
2265
2266                         string strItemMenuLaneSelect = this.contextMenuStrip譜面右メニュー.Items[ indexMenuLaneSelect1 ].Text;
2267                         strItemMenuLaneSelect = System.Text.RegularExpressions.Regex.Replace(
2268                                 strItemMenuLaneSelect , @"\[(.*)\]", "[" + strLane + "]" );
2269                         this.contextMenuStrip譜面右メニュー.Items[ indexMenuLaneSelect1 ].Text = strItemMenuLaneSelect;
2270
2271                         strItemMenuLaneSelect = this.contextMenuStrip譜面右メニュー.Items[ indexMenuLaneSelect2 ].Text;
2272                         strItemMenuLaneSelect = System.Text.RegularExpressions.Regex.Replace(
2273                                 strItemMenuLaneSelect, @"\[(.*)\]", "[" + strLane + "]" );
2274                         this.contextMenuStrip譜面右メニュー.Items[ indexMenuLaneSelect2 ].Text = strItemMenuLaneSelect;
2275
2276                         string strItemMenuPartSelect = this.contextMenuStrip譜面右メニュー.Items[ indexMenuPartSelect ].Text;
2277                         strItemMenuPartSelect = System.Text.RegularExpressions.Regex.Replace(
2278                                 strItemMenuPartSelect, @"\[(.*)\]", "[" + strPartNo + "]" );
2279                         this.contextMenuStrip譜面右メニュー.Items[ indexMenuPartSelect ].Text = strItemMenuPartSelect;
2280                         #endregion
2281
2282                         // メニューを表示。
2283
2284                         this.contextMenuStrip譜面右メニュー.Show( this.pictureBox譜面パネル, x, y );
2285                 }
2286                 public void t最近使ったファイルをFileメニューへ追加する()
2287                 {
2288                         #region [ [ファイル] メニューから、最近使ったファイルの一覧をクリアする。]
2289                         //-----------------
2290                         for( int i = 0; i < this.toolStripMenuItemファイル.DropDownItems.Count; i++ )
2291                         {
2292                                 ToolStripItem item = this.toolStripMenuItemファイル.DropDownItems[ i ];
2293
2294                                 // ↓削除したくないサブメニューの一覧。これ以外のサブメニュー項目はすべて削除する。
2295                                 if( item != this.toolStripMenuItem新規 &&
2296                                         item != this.toolStripMenuItem開く &&
2297                                         item != this.toolStripMenuItem上書き保存 &&
2298                                         item != this.toolStripMenuItem名前を付けて保存 &&
2299                                         item != this.toolStripSeparator1 &&
2300                                         item != this.toolStripMenuItemMIDIImportFromFileMenu &&
2301                                         item != this.exportMIDIFileToolStripMenuItem &&
2302                                         item != this.toolStripMenuItem終了 )
2303                                 {
2304                                         this.toolStripMenuItemファイル.DropDownItems.Remove( item );
2305                                         i = -1; // 要素数が変わったので列挙しなおし
2306                                 }
2307                         }
2308                         //-----------------
2309                         #endregion
2310
2311                         #region [ 表示しないオプション設定であるか、履歴が0件ならここで終了する。]
2312                         //-----------------
2313                         if( !this.appアプリ設定.ShowRecentFiles || this.appアプリ設定.RecentUsedFile.Count == 0 )
2314                                 return;
2315                         //-----------------
2316                         #endregion
2317
2318                         #region [ アプリ設定が持つ履歴にそって、[ファイル] メニューにサブメニュー項目リストを追加する(ただし最大表示数まで)。 ]
2319                         //-----------------
2320
2321                         // [ファイル] のサブメニューリストに項目が1つでもある場合は、履歴サブメニュー項目の追加の前に「終了」の下にセパレータを入れる。手動で。
2322
2323                         bool bセパレータの追加がまだ = true;
2324
2325
2326                         // すべての「最近使ったファイル」について...
2327
2328                         for( int i = 0; i < this.appアプリ設定.RecentUsedFile.Count; i++ )
2329                         {
2330                                 #region [ 最大表示数を越えたらここで終了。 ]
2331                                 //-----------------
2332                                 if( i >= this.appアプリ設定.RecentFilesNum )
2333                                         return;
2334                                 //-----------------
2335                                 #endregion
2336
2337                                 #region [ ファイル名を、サブメニュー項目として [ファイル] メニューに追加する。 ]
2338                                 //-----------------
2339                                 string path = this.appアプリ設定.RecentUsedFile[ i ];
2340
2341                                 if( path.Length == 0 )
2342                                         continue;
2343
2344                                 #region [ セパレータの追加がまだなら追加する。]
2345                                 //-----------------
2346                                 if( bセパレータの追加がまだ )
2347                                 {
2348                                         var separator = new ToolStripSeparator();
2349                                         separator.Size = this.toolStripSeparator1.Size;
2350                                         this.toolStripMenuItemファイル.DropDownItems.Add( separator );
2351                                         bセパレータの追加がまだ = false;
2352                                 }
2353                                 //-----------------
2354                                 #endregion
2355
2356                                 #region [ ToolStripMenuItem を手動で作って [ファイル] のサブメニューリストに追加する。]
2357                                 //-----------------
2358                                 string strShotenPath = AdjustPathString( path );        // #35890 2016.1.3 yyagi; shorten "RecentFiles" text if needed
2359                                 var item2 = new ToolStripMenuItem() {
2360                                         Name = "最近使ったファイル" + i,
2361                                         Size = this.toolStripMenuItem終了.Size,
2362                                         Text = "&" + i + " " + strShotenPath,
2363                                         ToolTipText = path,
2364                                 };
2365                                 item2.Click += new EventHandler( this.toolStripMenuItem最近使ったファイル_Click );
2366                                 this.toolStripMenuItemファイル.DropDownItems.Add( item2 );
2367                                 //-----------------
2368                                 #endregion
2369
2370                                 #region [ 追加したファイルが既に存在していないなら項目を無効化(グレー表示)する。]
2371                                 //-----------------
2372                                 if( !File.Exists( path ) )
2373                                         item2.Enabled = false;
2374                                 //-----------------
2375                                 #endregion
2376
2377                                 //-----------------
2378                                 #endregion
2379                         }
2380                         //-----------------
2381                         #endregion
2382                 }
2383                 // 参考: http://gushwell.ldblog.jp/archives/50815731.html
2384                 private string AdjustPathString( string text )
2385                 {
2386                         int nTargetWidth = (int)(this.Width * 0.8f);
2387                         Bitmap bmp = new Bitmap(nTargetWidth, this.Height);
2388                         Graphics g = Graphics.FromImage( bmp );
2389                         var item = new ToolStripMenuItem();
2390                         SizeF size = g.MeasureString( text, item.Font );
2391 //Debug.WriteLine( "WinWidth"+ this.Width + ", now=" + size.Width + ", font=" + this.Font.ToString());
2392                         while ( nTargetWidth < size.Width )
2393                         {
2394                                 string text2 = ShortenPathString( text );
2395                                 if ( text == text2 )
2396                                         break;
2397                                 size = g.MeasureString( text2, this.Font );
2398                                 text = text2;
2399 //Debug.WriteLine( "winWidth" + this.Width + ", now=" + size.Width + ", font=" + this.Font.ToString() );
2400                         }
2401                         item.Dispose();
2402                         g.Dispose();
2403                         bmp.Dispose();
2404                         return text;
2405                 }
2406                 private string ShortenPathString( string text )
2407                 {
2408                         int nWidth = this.Width;
2409                         List<string> list = new List<string>(text.Split('\\'));
2410                         int i = list.Count / 2;
2411                 if ( list[i] != "..." )
2412                         {
2413                             list[i] = "...";
2414                 }
2415                         else
2416                         {
2417                     if ( list.Count % 2 == 0 && i > 1 )
2418                             list.RemoveAt(i - 1);
2419                             else if ( list.Count % 2 == 1 && i < list.Count - 2 )
2420                                     list.RemoveAt(i + 1);
2421                 }
2422                 StringBuilder sb = new StringBuilder(list[0]);
2423                     for ( int n = 1; n < list.Count; n++ ) {
2424                             sb.Append('\\').Append(list[n]);
2425                 }
2426 //Debug.WriteLine( "org:" + text );
2427 //Debug.WriteLine( "now:" + sb );
2428                         return sb.ToString();
2429             }
2430                 public void tWAV_BMP_AVIリストのカーソルを全部同じ行に合わせる( int nIndex番号0to1294 )
2431                 {
2432                         if( nIndex番号0to1294 >= 0 && nIndex番号0to1294 <= 1294 )
2433                         {
2434                                 this.mgrWAVリスト管理者.tItemを選択する( nIndex番号0to1294 );
2435                                 this.mgrBMPリスト管理者.tItemを選択する( nIndex番号0to1294 );
2436                                 this.mgrAVIリスト管理者.tItemを選択する( nIndex番号0to1294 );
2437
2438                                 this.n現在選択中のWAV_BMP_AVIリストの行番号0to1294 = nIndex番号0to1294;
2439                         }
2440                 }
2441                 public string strファイルの存在するディレクトリを絶対パスで返す( string strファイル )
2442                 {
2443                         string strファイルの絶対パス = strファイル;
2444
2445                         try
2446                         {
2447                                 // ファイルが絶対パスかどうかを判定する。(new Uri() は相対パスを指定されると例外が発生するので、それを利用する。)
2448
2449                                 new Uri( strファイル );
2450                         }
2451                         catch
2452                         {
2453                                 // 例外が発生したので相対パスとみなし、絶対パスに直す。
2454
2455                                 strファイルの絶対パス = Path.Combine( this.str作業フォルダ名, strファイル );
2456                         }
2457
2458                         // 正規化する。(\a\b\c\..\d を \a\b\d にする)
2459
2460                         FileInfo fi = new FileInfo( strファイルの絶対パス );
2461                         strファイルの絶対パス = fi.FullName;
2462
2463                         return strファイルの絶対パス;
2464                 }
2465                 public Point pt現在のマウス位置を譜面の可視領域相対の座標dotで返す()
2466                 {
2467                         Point p = new Point( Cursor.Position.X, Cursor.Position.Y );
2468                         return this.splitContainerタブと譜面を分割.Panel2.PointToClient( p );
2469                 }
2470                 public Size sz譜面の可視領域の大きさdotを返す()
2471                 {
2472                         return new Size( this.splitContainerタブと譜面を分割.Panel2.Width, this.pictureBox譜面パネル.Height );
2473                 }
2474                 public void tUndoRedo用GUIの有効無効を設定する()
2475                 {
2476                         this.toolStripMenuItemアンドゥ.Enabled = this.mgrUndoRedo管理者.nUndo可能な回数 > 0;
2477                         this.toolStripMenuItemリドゥ.Enabled = this.mgrUndoRedo管理者.nRedo可能な回数 > 0;
2478                         this.toolStripButtonアンドゥ.Enabled = this.mgrUndoRedo管理者.nUndo可能な回数 > 0;
2479                         this.toolStripButtonリドゥ.Enabled = this.mgrUndoRedo管理者.nRedo可能な回数 > 0;
2480                 }
2481                 public void tタブを選択する( Eタブ種別 eタブ種別 )
2482                 {
2483                         this.tabControl情報パネル.SelectedIndex = (int) eタブ種別;
2484                 }
2485
2486
2487                 // その他
2488
2489                 #region [ private ]
2490                 //-----------------
2491                 private bool _b未保存 = true;
2492                 private bool b前回BGMありで再生した = true;
2493                 private bool b再生速度を変更した = false;
2494                 private bool bDTXファイルを開いた = false;
2495                 private Point pt選択モードのコンテクストメニューを開いたときのマウスの位置;
2496                 private int n現在のガイド間隔4to64or0 = 16;             // 初期は16分間隔
2497                 private bool b選択チップがある
2498                 {
2499                         get
2500                         {
2501                                 foreach( KeyValuePair<int, C小節> pair in this.mgr譜面管理者.dic小節 )
2502                                 {
2503                                         foreach( Cチップ cチップ in pair.Value.listチップ )
2504                                         {
2505                                                 if( cチップ.b確定選択中 )
2506                                                         return true;
2507                                         }
2508                                 }
2509                                 return false;
2510                         }
2511                 }
2512
2513                 public void tDTXV演奏関連のボタンとメニューのEnabledの設定()
2514                 {
2515                         if( File.Exists( this.strDTXCのあるフォルダ名 + this.appアプリ設定.ViewerInfo.Path ) )
2516                         {
2517                                 // DTXViewer(DTXManiaGR) が存在するなら Enable
2518
2519                                 this.toolStripButton先頭から再生.Enabled = true;
2520                                 this.toolStripButton現在位置から再生.Enabled = true;
2521                                 this.toolStripButton現在位置からBGMのみ再生.Enabled = true;
2522                                 this.toolStripButton再生停止.Enabled = true;
2523                                 this.toolStripMenuItem先頭から再生.Enabled = true;
2524                                 this.toolStripMenuItem現在位置から再生.Enabled = true;
2525                                 this.toolStripMenuItem現在位置からBGMのみ再生.Enabled = true;
2526                                 this.toolStripMenuItem再生停止.Enabled = true;
2527                         }
2528                         else
2529                         {
2530                                 // DTXViewer(DTXManiaGR) が存在しないなら Disable
2531
2532                                 this.toolStripButton先頭から再生.Enabled = false;
2533                                 this.toolStripButton現在位置から再生.Enabled = false;
2534                                 this.toolStripButton現在位置からBGMのみ再生.Enabled = false;
2535                                 this.toolStripButton再生停止.Enabled = false;
2536                                 this.toolStripMenuItem先頭から再生.Enabled = false;
2537                                 this.toolStripMenuItem現在位置から再生.Enabled = false;
2538                                 this.toolStripMenuItem現在位置からBGMのみ再生.Enabled = false;
2539                                 this.toolStripMenuItem再生停止.Enabled = false;
2540                         }
2541                 }
2542                 private string tファイル選択ダイアログでファイルを選択し相対パスにして返す( string strタイトル, string strフィルタ, string str初期フォルダ )
2543                 {
2544                         string str相対ファイル名 = "";
2545
2546                         this.dlgチップパレット.t一時的に隠蔽する();
2547
2548                         var dialog = new OpenFileDialog() {
2549                                 Title = strタイトル,
2550                                 Filter = strフィルタ,
2551                                 FilterIndex = 1,
2552                                 InitialDirectory = str初期フォルダ,
2553                         };
2554                         if( dialog.ShowDialog() == DialogResult.OK )
2555                         {
2556                                 str相対ファイル名 = Cファイル選択_パス変換.str基点からの相対パスに変換して返す( dialog.FileName, this.str作業フォルダ名 );
2557                                 str相対ファイル名.Replace( '/', '\\' );
2558                         }
2559                         else
2560                                 str相対ファイル名 = "";
2561
2562                         this.dlgチップパレット.t一時的な隠蔽を解除する();
2563
2564                         return str相対ファイル名;
2565                 }
2566                 public DialogResult t未保存なら保存する()
2567                 {
2568                         var result = DialogResult.OK;
2569
2570                         if( this.b未保存 )
2571                         {
2572                                 // ダイアログで保存可否を確認。
2573
2574                                 this.dlgチップパレット.t一時的に隠蔽する();
2575                                 result = MessageBox.Show( Resources.str編集中のデータを保存しますかMSG, Resources.str確認ダイアログのタイトル, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1 );
2576                                 this.dlgチップパレット.t一時的な隠蔽を解除する();
2577                                 
2578
2579                                 // YES なら上書き保存。
2580
2581                                 if( result == DialogResult.Yes )
2582                                         this.tシナリオ_上書き保存();
2583
2584
2585                                 // 画面を再描画。
2586
2587                                 this.Refresh();
2588                         }
2589                         return result;
2590                 }
2591                 private void t次のプロパティ変更処理がUndoRedoリストに載らないようにする()
2592                 {
2593                         CUndoRedo管理.bUndoRedoした直後 = true;
2594                 }
2595                 private void t次のプロパティ変更処理がUndoRedoリストに載るようにする()
2596                 {
2597                         CUndoRedo管理.bUndoRedoした直後 = false;
2598                 }
2599
2600                 /// <summary>
2601                 /// <para>n分 … 4分間隔なら 4、8分間隔なら 8 など、フリー間隔なら 0 を指定する。</para>
2602                 /// </summary>
2603                 private void tガイド間隔を変更する( int n分 )
2604                 {
2605                         // 新しいガイド間隔を設定。
2606
2607                         #region [ 新しいガイド間隔を設定。 ]
2608                         //-----------------
2609                         
2610                         this.n現在のガイド間隔4to64or0 = n分;
2611
2612                         this.mgr譜面管理者.n現在のガイド幅grid =
2613                                 ( n分 == 0 ) ? 1 : ( C小節.n基準の高さgrid / n分 );
2614                         
2615                         //-----------------
2616                         #endregion
2617
2618
2619                         // ガイド間隔メニュー GUI を更新。
2620
2621                         #region [ 一度すべてのガイド間隔メニューのチェックをはずし、制定された分数のメニューのみチェックする。 ]
2622                         //-----------------
2623                         this.toolStripMenuItemガイド間隔4分.CheckState = CheckState.Unchecked;
2624                         this.toolStripMenuItemガイド間隔8分.CheckState = CheckState.Unchecked;
2625                         this.toolStripMenuItemガイド間隔12分.CheckState = CheckState.Unchecked;
2626                         this.toolStripMenuItemガイド間隔16分.CheckState = CheckState.Unchecked;
2627                         this.toolStripMenuItemガイド間隔24分.CheckState = CheckState.Unchecked;
2628                         this.toolStripMenuItemガイド間隔32分.CheckState = CheckState.Unchecked;
2629                         this.toolStripMenuItemガイド間隔48分.CheckState = CheckState.Unchecked;
2630                         this.toolStripMenuItemガイド間隔64分.CheckState = CheckState.Unchecked;
2631                         this.toolStripMenuItemガイド間隔フリー.CheckState = CheckState.Unchecked;
2632                         
2633                         switch( n分 )
2634                         {
2635                                 case 8:
2636                                         this.toolStripMenuItemガイド間隔8分.CheckState = CheckState.Checked;
2637                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 1;
2638                                         break;
2639
2640                                 case 12:
2641                                         this.toolStripMenuItemガイド間隔12分.CheckState = CheckState.Checked;
2642                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 2;
2643                                         break;
2644
2645                                 case 0:
2646                                         this.toolStripMenuItemガイド間隔フリー.CheckState = CheckState.Checked;
2647                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 8;
2648                                         break;
2649
2650                                 case 4:
2651                                         this.toolStripMenuItemガイド間隔4分.CheckState = CheckState.Checked;
2652                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 0;
2653                                         break;
2654
2655                                 case 0x10:
2656                                         this.toolStripMenuItemガイド間隔16分.CheckState = CheckState.Checked;
2657                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 3;
2658                                         break;
2659
2660                                 case 0x18:
2661                                         this.toolStripMenuItemガイド間隔24分.CheckState = CheckState.Checked;
2662                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 4;
2663                                         break;
2664
2665                                 case 0x20:
2666                                         this.toolStripMenuItemガイド間隔32分.CheckState = CheckState.Checked;
2667                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 5;
2668                                         break;
2669
2670                                 case 0x30:
2671                                         this.toolStripMenuItemガイド間隔48分.CheckState = CheckState.Checked;
2672                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 6;
2673                                         break;
2674
2675                                 case 0x40:
2676                                         this.toolStripMenuItemガイド間隔64分.CheckState = CheckState.Checked;
2677                                         this.toolStripComboBoxガイド間隔.SelectedIndex = 7;
2678                                         break;
2679                         }
2680                         //-----------------
2681                         #endregion
2682
2683
2684                         // 画面を再描画。
2685
2686                         #region [ 画面を再描画する。]
2687                         //-----------------
2688                         this.pictureBox譜面パネル.Invalidate();
2689                         //-----------------
2690                         #endregion
2691                 }
2692
2693
2694                 // GUI イベント
2695
2696                 #region [ GUIイベント:メインフォーム ]
2697                 //-----------------
2698                 private void Cメインフォーム_DragDrop( object sender, DragEventArgs e )
2699                 {
2700                         string[] data = (string[]) e.Data.GetData( DataFormats.FileDrop );
2701                         if( data.Length >= 1 )
2702                         {
2703                                 this.tシナリオ_DragDropされたファイルを開く( data );
2704                         }
2705                 }
2706                 private void Cメインフォーム_DragEnter( object sender, DragEventArgs e )
2707                 {
2708                         if( e.Data.GetDataPresent( DataFormats.FileDrop ) )
2709                         {
2710                                 e.Effect = DragDropEffects.Copy;
2711                         }
2712                         else
2713                         {
2714                                 e.Effect = DragDropEffects.None;
2715                         }
2716                 }
2717                 private void Cメインフォーム_FormClosing( object sender, FormClosingEventArgs e )
2718                 {
2719                         if( this.t未保存なら保存する() == DialogResult.Cancel )
2720                         {
2721                                 e.Cancel = true;
2722                         }
2723                         else
2724                         {
2725                                 this.tアプリ終了時に行う終了処理();
2726                         }
2727                 }
2728                 private void Cメインフォーム_Load( object sender, EventArgs e )
2729                 {
2730                         this.tアプリ起動時に一度だけ行う初期化処理();
2731                         // this.t譜面を初期化する();                                    // 2011.8.29 yyagi; removed this.t譜面を初期化する() because it has already done in this.tアプリ起動時に一度だけ行う初期化処理().
2732                 }
2733                 //-----------------
2734                 #endregion
2735                 #region [ GUIイベント:pictureBox譜面パネル、Panel2、スクロールバー関連 ]
2736                 //-----------------
2737                 private void pictureBox譜面パネル_MouseClick( object sender, MouseEventArgs e )
2738                 {
2739                         // フォーカスを得る。
2740
2741                         this.pictureBox譜面パネル.Focus();
2742
2743
2744                         // 選択・編集のいずれかの管理者へ処理を引き継ぐ。
2745
2746                         if( this.b選択モードである )
2747                         {
2748                                 this.mgr選択モード管理者.MouseClick( e );
2749                         }
2750                         else
2751                         {
2752                                 this.mgr編集モード管理者.MouseClick( e );
2753                         }
2754                 }
2755                 private void pictureBox譜面パネル_MouseDown( object sender, MouseEventArgs e )
2756                 {
2757                         if( this.b選択モードである )
2758                                 this.mgr選択モード管理者.MouseDown( e );
2759                 }
2760                 private void pictureBox譜面パネル_MouseEnter( object sender, EventArgs e )
2761                 {
2762                         #region [ オートフォーカスが有効の場合、譜面にマウスが入ったら譜面がフォーカスを得る。 ]
2763                         //-----------------
2764                         if( this.appアプリ設定.AutoFocus )
2765                                 this.pictureBox譜面パネル.Focus();
2766                         //-----------------
2767                         #endregion
2768                 }
2769                 private void pictureBox譜面パネル_MouseLeave( object sender, EventArgs e )
2770                 {
2771                         if( this.b編集モードである )
2772                                 this.mgr編集モード管理者.MouseLeave( e );
2773                 }
2774                 private void pictureBox譜面パネル_MouseMove( object sender, MouseEventArgs e )
2775                 {
2776                         // 選択・編集のいずれかの管理者へ処理を引き継ぐ。
2777
2778                         if( this.b選択モードである )
2779                         {
2780                                 this.mgr選択モード管理者.MouseMove( e );
2781                         }
2782                         else
2783                         {
2784                                 this.mgr編集モード管理者.MouseMove( e );
2785                         }
2786                 }
2787                 private void pictureBox譜面パネル_Paint( object sender, PaintEventArgs e )
2788                 {
2789                         if( this.mgr譜面管理者 == null )
2790                                 return;         // まだ初期化が終わってないうちに Paint が呼び出される場合がある。
2791
2792                         #region [ 小節数が変わってたら、スクロールバーの値域を調整する。]
2793                         //-----------------
2794                         int n全譜面の高さgrid = this.mgr譜面管理者.n全小節の高さgridの合計を返す();
2795
2796                         if( this.vScrollBar譜面用垂直スクロールバー.Maximum != n全譜面の高さgrid - 1 )        // 小節数が変わっている
2797                         {
2798                                 // 譜面の高さ(grid)がどれだけ変わったか?
2799
2800                                 int n増加分grid = ( n全譜面の高さgrid - 1 ) - this.vScrollBar譜面用垂直スクロールバー.Maximum;
2801
2802
2803                                 // スクロールバーを調整。
2804
2805                                 #region [ スクロールバーの状態を新しい譜面の高さに合わせる。]
2806                                 //-----------------
2807                                 this.vScrollBar譜面用垂直スクロールバー.Maximum = n全譜面の高さgrid - 1;
2808
2809                                 if( ( this.vScrollBar譜面用垂直スクロールバー.Value + n増加分grid ) < 0 )
2810                                 {
2811                                         this.vScrollBar譜面用垂直スクロールバー.Value = 0;
2812                                 }
2813                                 else
2814                                 {
2815                                         this.vScrollBar譜面用垂直スクロールバー.Value += n増加分grid;
2816                                 }
2817                                 //-----------------
2818                                 #endregion
2819
2820
2821                                 // 譜面表示下辺の位置を更新。
2822
2823                                 #region [ 譜面表示下辺の位置を更新する。 ]
2824                                 //-----------------
2825                                 this.mgr譜面管理者.n現在の譜面表示下辺の譜面先頭からの位置grid =
2826                                         ( ( this.vScrollBar譜面用垂直スクロールバー.Maximum - this.vScrollBar譜面用垂直スクロールバー.LargeChange ) + 1 ) - this.vScrollBar譜面用垂直スクロールバー.Value;
2827                                 //-----------------
2828                                 #endregion
2829                         }
2830                         //-----------------
2831                         #endregion
2832
2833                         #region [ 譜面を描画する。]
2834                         //-----------------
2835                         int nPicBoxの幅 = this.pictureBox譜面パネル.ClientSize.Width;
2836                         int nPanel2の幅 = this.splitContainerタブと譜面を分割.Panel2.Width;
2837
2838                         var rc可視領域 = new Rectangle() {
2839                                 X = -this.pictureBox譜面パネル.Location.X,
2840                                 Y = 0,
2841                                 Width = ( nPanel2の幅 > nPicBoxの幅 ) ? nPicBoxの幅 : nPanel2の幅,
2842                                 Height = this.pictureBox譜面パネル.ClientSize.Height,
2843                         };
2844
2845                         this.mgr譜面管理者.t譜面を描画する( e.Graphics, this.pictureBox譜面パネル.ClientSize, rc可視領域 );
2846                         //-----------------
2847                         #endregion
2848
2849                         #region [ 現在のモード管理者の Paint() を呼び出す。]
2850                         //-----------------
2851                         if( this.b選択モードである )
2852                         {
2853                                 if( this.mgr選択モード管理者 != null )
2854                                         this.mgr選択モード管理者.Paint( e );
2855                         }
2856                         else
2857                         {
2858                                 if( this.mgr編集モード管理者 != null )
2859                                         this.mgr編集モード管理者.Paint( e );
2860                         }
2861                         //-----------------
2862                         #endregion
2863                 }
2864                 private void pictureBox譜面パネル_PreviewKeyDown( object sender, PreviewKeyDownEventArgs e )
2865                 {
2866                         if( e.KeyCode == Keys.Prior )
2867                         {
2868                                 #region [ PageUp → 移動量に対応する grid だけ垂直つまみを移動させる。あとはこの移動で生じる ChangedValue イベントで処理。]
2869                                 //-----------------
2870                                 int n移動すべき数grid = -C小節.n基準の高さgrid;
2871                                 int n新しい位置 = this.vScrollBar譜面用垂直スクロールバー.Value + n移動すべき数grid;
2872                                 int n最小値 = this.vScrollBar譜面用垂直スクロールバー.Minimum;
2873                                 int n最大値 = ( this.vScrollBar譜面用垂直スクロールバー.Maximum + 1 ) - this.vScrollBar譜面用垂直スクロールバー.LargeChange;
2874
2875                                 if( n新しい位置 < n最小値 )
2876                                 {
2877                                         n新しい位置 = n最小値;
2878                                 }
2879                                 else if( n新しい位置 > n最大値 )
2880                                 {
2881                                         n新しい位置 = n最大値;
2882                                 }
2883
2884                                 this.vScrollBar譜面用垂直スクロールバー.Value = n新しい位置;
2885                                 //-----------------
2886                                 #endregion
2887                         }
2888                         else if( e.KeyCode == Keys.Next )
2889                         {
2890                                 #region [ PageDown → 移動量に対応する grid だけ垂直つまみを移動させる。あとはこの移動で生じる ChangedValue イベントで処理。]
2891                                 //-----------------
2892                                 int n移動すべき数grid = C小節.n基準の高さgrid;
2893                                 int n新しい位置 = this.vScrollBar譜面用垂直スクロールバー.Value + n移動すべき数grid;
2894                                 int n最小値 = this.vScrollBar譜面用垂直スクロールバー.Minimum;
2895                                 int n最大値 = ( this.vScrollBar譜面用垂直スクロールバー.Maximum + 1 ) - this.vScrollBar譜面用垂直スクロールバー.LargeChange;
2896
2897                                 if( n新しい位置 < n最小値 )
2898                                 {
2899                                         n新しい位置 = n最小値;
2900                                 }
2901                                 else if( n新しい位置 > n最大値 )
2902                                 {
2903                                         n新しい位置 = n最大値;
2904                                 }
2905
2906                                 this.vScrollBar譜面用垂直スクロールバー.Value = n新しい位置;
2907                                 //-----------------
2908                                 #endregion
2909                         }
2910                 }
2911
2912                 private void splitContainerタブと譜面を分割_MouseWheel( object sender, MouseEventArgs e )
2913                 {
2914                         if ( ( Control.ModifierKeys & Keys.Shift ) == Keys.Shift )
2915                         {
2916                                 #region [ Shiftを押しながらホイール操作すると、横スクロール。]
2917                                 if ( e.Delta == 0 )
2918                                         return;         // 移動量なし
2919
2920                                 // e.Delta は、スクロールバーを下へ動かしたいときに負、上へ動かしたいときに正となる。
2921
2922                                 int n移動すべき行数 = ( -e.Delta * SystemInformation.MouseWheelScrollLines ) / 120;
2923
2924                                 // 1行=1レーン とする。(が、実際には適当に設定しただけ。1レーンには設定していない)
2925
2926                                 int n移動すべき数grid = n移動すべき行数 * 16;
2927
2928
2929                                 // スクロールバーのつまみを移動。
2930
2931                                 int n新しい位置 = this.hScrollBar譜面用水平スクロールバー.Value + n移動すべき数grid;
2932                                 int n最小値 = this.hScrollBar譜面用水平スクロールバー.Minimum;
2933                                 int n最大値 = ( this.hScrollBar譜面用水平スクロールバー.Maximum + 1 ) - this.hScrollBar譜面用水平スクロールバー.LargeChange;
2934
2935                                 if ( n新しい位置 < n最小値 )
2936                                 {
2937                                         n新しい位置 = n最小値;
2938                                 }
2939                                 else if ( n新しい位置 > n最大値 )
2940                                 {
2941                                         n新しい位置 = n最大値;
2942                                 }
2943
2944                                 this.hScrollBar譜面用水平スクロールバー.Value = n新しい位置;
2945                                 //-----------------
2946                                 #endregion
2947                         }
2948                         else
2949                         {
2950                                 #region [ 移動量に対応する grid だけ垂直つまみを移動させる。あとはこの移動で生じる ChangedValue イベントで処理する。]
2951                                 //-----------------
2952                                 if ( e.Delta == 0 )
2953                                         return;         // 移動量なし
2954
2955
2956                                 // e.Delta は、スクロールバーを下へ動かしたいときに負、上へ動かしたいときに正となる。
2957
2958                                 int n移動すべき行数 = ( -e.Delta * SystemInformation.MouseWheelScrollLines ) / 120;
2959
2960
2961                                 // 1行=1拍(64/4=16グリッド)とする。
2962
2963                                 int n移動すべき数grid = n移動すべき行数 * 16;
2964
2965
2966                                 // スクロールバーのつまみを移動。
2967
2968                                 int n新しい位置 = this.vScrollBar譜面用垂直スクロールバー.Value + n移動すべき数grid;
2969                                 int n最小値 = this.vScrollBar譜面用垂直スクロールバー.Minimum;
2970                                 int n最大値 = ( this.vScrollBar譜面用垂直スクロールバー.Maximum + 1 ) - this.vScrollBar譜面用垂直スクロールバー.LargeChange;
2971
2972                                 if ( n新しい位置 < n最小値 )
2973                                 {
2974                                         n新しい位置 = n最小値;
2975                                 }
2976                                 else if ( n新しい位置 > n最大値 )
2977                                 {
2978                                         n新しい位置 = n最大値;
2979                                 }
2980
2981                                 this.vScrollBar譜面用垂直スクロールバー.Value = n新しい位置;
2982                                 //-----------------
2983                                 #endregion
2984                         }
2985                 }
2986                 private void splitContainerタブと譜面を分割_Panel2_SizeChanged( object sender, EventArgs e )
2987                 {
2988                         if( this.mgr譜面管理者 != null )   // 初期化前に呼び出されることがある。
2989                         {
2990                                 this.mgr譜面管理者.t水平スクロールバーと譜面パネル左右位置の調整();
2991                                 this.mgr譜面管理者.t垂直スクロールバーと譜面可視領域の上下位置の調整();
2992                         }
2993                 }
2994
2995                 private void hScrollBar譜面用水平スクロールバー_ValueChanged( object sender, EventArgs e )
2996                 {
2997                         if( this.mgr譜面管理者 != null )
2998                                 this.mgr譜面管理者.t水平スクロールバーと譜面パネル左右位置の調整();
2999                 }
3000                 private void vScrollBar譜面用垂直スクロールバー_ValueChanged( object sender, EventArgs e )
3001                 {
3002                         if( mgr譜面管理者 != null )
3003                                 this.mgr譜面管理者.t垂直スクロールバーと譜面可視領域の上下位置の調整();
3004                 }
3005                 //-----------------
3006                 #endregion
3007                 #region [ GUIイベント:譜面右メニュー関連 ]
3008                 //-----------------
3009                 private void toolStripMenuItem選択チップの切り取り_Click( object sender, EventArgs e )
3010                 {
3011                         this.tシナリオ_切り取り();
3012                 }
3013                 private void toolStripMenuItem選択チップのコピー_Click( object sender, EventArgs e )
3014                 {
3015                         this.tシナリオ_コピー();
3016                 }
3017                 private void toolStripMenuItem選択チップの貼り付け_Click( object sender, EventArgs e )
3018                 {
3019                         // クリックされた座標を取得。
3020
3021                         Point ptMenu = new Point( this.contextMenuStrip譜面右メニュー.Left, this.contextMenuStrip譜面右メニュー.Top );
3022                         Point ptMenuClient = this.contextMenuStrip譜面右メニュー.SourceControl.PointToClient( ptMenu );
3023
3024
3025                         // Y座標から位置gridを得て、そこへ貼り付ける。
3026
3027                         this.tシナリオ_貼り付け( this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( ptMenuClient.Y ) );
3028                 }
3029                 private void toolStripMenuItem選択チップの削除_Click( object sender, EventArgs e )
3030                 {
3031                         this.tシナリオ_削除();
3032                 }
3033
3034                 private void toolStripMenuItemすべてのチップの選択_Click( object sender, EventArgs e )
3035                 {
3036                         // 編集モードなら強制的に選択モードにする。
3037
3038                         if( this.b編集モードである )
3039                                 this.t選択モードにする();
3040
3041
3042                         // 全チップを選択。
3043
3044                         this.mgr選択モード管理者.t全チップを選択する();
3045                 }
3046                 private void toolStripMenuItemレーン内のすべてのチップの選択_Click( object sender, EventArgs e )
3047                 {
3048                         // 編集モードなら強制的に選択モードにする。
3049
3050                         if ( this.b編集モードである )
3051                                 this.t選択モードにする();
3052
3053                         // メニューが開かれたときのマウスの座標を取得。
3054                         // ※メニューは必ずマウス位置を左上にして表示されるとは限らないため、
3055                         //  メニューの表示位置からは取得しないこと。
3056
3057                         Point ptマウスの位置 = this.pt選択モードのコンテクストメニューを開いたときのマウスの位置;
3058
3059
3060                         // マウス位置に小節を挿入。
3061
3062                         #region [ クリックされた箇所のレーン番号を取得する。]
3063                         //-----------------
3064                         int lane = this.mgr譜面管理者.nX座標dotが位置するレーン番号を返す( ptマウスの位置.X );
3065                         if ( lane < 0 )
3066                                 return;         // クリックされた箇所にレーンがない
3067
3068                         //-----------------
3069                         #endregion
3070
3071                         this.mgr選択モード管理者.tレーン上の全チップを選択する( lane );
3072
3073                 }
3074                 private void toolStripMenuItemレーン内のすべてのチップの選択_特定小節以降_Click( object sender, EventArgs e )
3075                 {
3076                         // 編集モードなら強制的に選択モードにする。
3077
3078                         if ( this.b編集モードである )
3079                                 this.t選択モードにする();
3080
3081                         // メニューが開かれたときのマウスの座標を取得。
3082                         // ※メニューは必ずマウス位置を左上にして表示されるとは限らないため、
3083                         //  メニューの表示位置からは取得しないこと。
3084
3085                         Point ptマウスの位置 = this.pt選択モードのコンテクストメニューを開いたときのマウスの位置;
3086
3087                         #region [ クリックされた箇所のレーン番号を取得する。]
3088                         //-----------------
3089                         int lane = this.mgr譜面管理者.nX座標dotが位置するレーン番号を返す( ptマウスの位置.X );
3090                         if ( lane < 0 )
3091                                 return;         // クリックされた箇所にレーンがない
3092
3093                         //-----------------
3094                         #endregion
3095                         #region [ クリックされた箇所の小節を取得する。]
3096                         //-----------------
3097                         if ( this.mgr譜面管理者.nX座標dotが位置するレーン番号を返す( ptマウスの位置.X ) < 0 )
3098                                 return;         // クリックされた箇所にレーンがない
3099
3100                         int n譜面先頭からの位置grid = this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( ptマウスの位置.Y );
3101
3102                         C小節 csクリックされた小節 = this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( n譜面先頭からの位置grid );
3103                         //-----------------
3104                         #endregion
3105
3106                         this.mgr選択モード管理者.tレーン上の全チップを選択する( lane, csクリックされた小節.n小節番号0to3599 );
3107                 }
3108
3109                 private void toolStripMenuItem小節内のすべてのチップの選択_Click( object sender, EventArgs e )
3110                 {
3111                         // 編集モードなら強制的に選択モードにする。
3112
3113                         if ( this.b編集モードである )
3114                                 this.t選択モードにする();
3115
3116                         // メニューが開かれたときのマウスの座標を取得。
3117                         // ※メニューは必ずマウス位置を左上にして表示されるとは限らないため、
3118                         //  メニューの表示位置からは取得しないこと。
3119
3120                         Point ptマウスの位置 = this.pt選択モードのコンテクストメニューを開いたときのマウスの位置;
3121
3122                         #region [ クリックされた箇所の小節を取得する。]
3123                         //-----------------
3124                         if ( this.mgr譜面管理者.nX座標dotが位置するレーン番号を返す( ptマウスの位置.X ) < 0 )
3125                                 return;         // クリックされた箇所にレーンがない
3126
3127                         int n譜面先頭からの位置grid = this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( ptマウスの位置.Y );
3128                         C小節 csクリックされた小節 = this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( n譜面先頭からの位置grid );
3129                         //-----------------
3130                         #endregion
3131
3132                         this.mgr選択モード管理者.t小節上の全チップを選択する( csクリックされた小節.n小節番号0to3599 );
3133                 }
3134
3135                 private void toolStripMenuItem選択したチップを等間隔に配置_Click(object sender, EventArgs e)
3136                 {
3137                         this.tシナリオ_等間隔に配置();
3138                 }
3139                 private void toolStripMenuItem小節長変更_Click( object sender, EventArgs e )
3140                 {
3141                         // メニューが開かれたときのマウスの座標を取得。
3142                         // ※メニューは必ずマウス位置を左上にして表示されるとは限らないため、
3143                         //  メニューの表示位置からは取得しないこと。
3144
3145                         Point ptマウス位置 = this.pt選択モードのコンテクストメニューを開いたときのマウスの位置;
3146
3147
3148                         // 小節の小節長を変更。
3149
3150                         #region [ クリックされた小節を取得する。]
3151                         //-----------------
3152                         if( this.mgr譜面管理者.nX座標dotが位置するレーン番号を返す( ptマウス位置.X ) < 0 )
3153                                 return;         // クリックされた箇所にレーンがないなら無視。
3154
3155                         int n譜面先頭からの位置grid = this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( ptマウス位置.Y );
3156                         C小節 csクリックされた小節 =  this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( n譜面先頭からの位置grid );
3157                         //-----------------
3158                         #endregion
3159
3160                         #region [ 取得した小節の小節長を変更する。]
3161                         //-----------------
3162                         if( csクリックされた小節 != null )
3163                                 this.tシナリオ_小節長を変更する( csクリックされた小節 );
3164                         //-----------------
3165                         #endregion
3166                 }
3167                 private void toolStripMenuItem小節の挿入_Click( object sender, EventArgs e )
3168                 {
3169                         // メニューが開かれたときのマウスの座標を取得。
3170                         // ※メニューは必ずマウス位置を左上にして表示されるとは限らないため、
3171                         //  メニューの表示位置からは取得しないこと。
3172
3173                         Point ptマウスの位置 = this.pt選択モードのコンテクストメニューを開いたときのマウスの位置;
3174
3175
3176                         // マウス位置に小節を挿入。
3177
3178                         #region [ クリックされた箇所の小節を取得する。]
3179                         //-----------------
3180                         if( this.mgr譜面管理者.nX座標dotが位置するレーン番号を返す( ptマウスの位置.X ) < 0 )
3181                                 return;         // クリックされた箇所にレーンがない
3182
3183                         int n譜面先頭からの位置grid = this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( ptマウスの位置.Y );
3184                         C小節 csクリックされた小節 = this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( n譜面先頭からの位置grid );
3185                         //-----------------
3186                         #endregion
3187
3188                         #region [ 該当小節の下へ新しい小節を挿入する。]
3189                         //-----------------
3190                         if( csクリックされた小節 != null )
3191                                 this.tシナリオ_小節を挿入する( csクリックされた小節.n小節番号0to3599 );
3192                         //-----------------
3193                         #endregion
3194                 }
3195                 private void toolStripMenuItem小節の削除_Click( object sender, EventArgs e )
3196                 {
3197                         // メニューが開かれたときのマウスの座標を取得。
3198                         // ※メニューは必ずマウス位置を左上にして表示されるとは限らないため、
3199                         //  メニューの表示位置からは取得しないこと。
3200
3201                         Point ptマウス位置 = this.pt選択モードのコンテクストメニューを開いたときのマウスの位置;
3202
3203
3204                         // マウス位置にある小節を削除。
3205
3206                         #region [ クリックされた箇所の小節を取得する。 ]
3207                         //-----------------
3208                         if( this.mgr譜面管理者.nX座標dotが位置するレーン番号を返す( ptマウス位置.X ) < 0 )
3209                                 return;         // クリックされた箇所にレーンがないなら無視。
3210
3211                         int n譜面先頭からの位置grid = this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( ptマウス位置.Y );
3212                         C小節 cs削除する小節 = this.mgr譜面管理者.p譜面先頭からの位置gridを含む小節を返す( n譜面先頭からの位置grid );
3213                         //-----------------
3214                         #endregion
3215
3216                         #region [ 該当小節を削除する。]
3217                         //-----------------
3218                         if( cs削除する小節 != null )
3219                                 this.tシナリオ_小節を削除する( cs削除する小節.n小節番号0to3599 );
3220                         //-----------------
3221                         #endregion
3222                 }
3223                 //-----------------
3224                 #endregion
3225                 
3226                 #region [ GUIイベント:基本情報関連 ]
3227                 //-----------------
3228                 #region [ Title ]
3229                 private string textBox曲名_以前の値 = "";
3230                 private void textBox曲名_TextChanged( object sender, EventArgs e )
3231                 {
3232                         // Undo/Redo リストを修正する。
3233
3234                         #region [ Undo/Redo リストを修正。]
3235                         //-----------------
3236                         if( !CUndoRedo管理.bUndoRedoした直後 )
3237                         {
3238                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3239
3240                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBox曲名 ) )
3241                                 {
3242                                         // 既存のセルの値を更新。
3243
3244                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBox曲名.Text;
3245                                 }
3246                                 else
3247                                 {
3248                                         // 新しいセルを追加。
3249
3250                                         this.mgrUndoRedo管理者.tノードを追加する( 
3251                                                 new CUndoRedoセル<string>(
3252                                                         this.textBox曲名,
3253                                                         new DGUndoを実行する<string>( this.textBox曲名_Undo ),
3254                                                         new DGRedoを実行する<string>( this.textBox曲名_Redo ),
3255                                                         this.textBox曲名_以前の値, this.textBox曲名.Text ) );
3256
3257
3258                                         // Undo ボタンを有効にする。
3259
3260                                         this.tUndoRedo用GUIの有効無効を設定する();
3261                                 }
3262                         }
3263                         //-----------------
3264                         #endregion
3265
3266
3267                         // Undo 用に値を保管しておく。
3268
3269                         this.textBox曲名_以前の値 = this.textBox曲名.Text;
3270
3271
3272                         // 完了。
3273
3274                         CUndoRedo管理.bUndoRedoした直後 = false;
3275                         this.b未保存 = true;
3276                 }
3277                 private void textBox曲名_Leave( object sender, EventArgs e )
3278                 {
3279                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3280
3281                         if( oセル仮想 != null )
3282                                 oセル仮想.t所有権の放棄( this.textBox曲名 );
3283                 }
3284                 private void textBox曲名_Undo( string str変更前, string str変更後 )
3285                 {
3286                         // 変更前の値に戻す。
3287
3288                         this.tタブを選択する( Eタブ種別.基本情報 );
3289
3290                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3291                         this.textBox曲名.Text = str変更前;
3292
3293                         this.textBox曲名.Focus();
3294                 }
3295                 private void textBox曲名_Redo( string str変更前, string str変更後 )
3296                 {
3297                         // 変更後の値に戻す。
3298
3299                         this.tタブを選択する( Eタブ種別.基本情報 );
3300
3301                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3302                         this.textBox曲名.Text = str変更後;
3303
3304                         this.textBox曲名.Focus();
3305                 }
3306                 #endregion
3307                 #region [ Author ]
3308                 private string textBox製作者_以前の値 = "";
3309                 private void textBox製作者_TextChanged( object sender, EventArgs e )
3310                 {
3311                         // Undo/Redo リストを修正する。
3312
3313                         #region [ Undo/Redo リストを修正。]
3314                         //-----------------
3315                         if( !CUndoRedo管理.bUndoRedoした直後 )
3316                         {
3317                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3318
3319                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBox製作者 ) )
3320                                 {
3321                                         // 既存のセルの値を更新。
3322
3323                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBox製作者.Text;
3324                                 }
3325                                 else
3326                                 {
3327                                         // 新しいセルを追加。
3328
3329                                         this.mgrUndoRedo管理者.tノードを追加する(
3330                                                 new CUndoRedoセル<string>(
3331                                                         this.textBox製作者, 
3332                                                         new DGUndoを実行する<string>( this.textBox製作者_Undo ),
3333                                                         new DGRedoを実行する<string>( this.textBox製作者_Redo ),
3334                                                         this.textBox製作者_以前の値, this.textBox製作者.Text ) );
3335
3336
3337                                         // Undo ボタンを有効にする。
3338
3339                                         this.tUndoRedo用GUIの有効無効を設定する();
3340                                 }
3341                         }
3342                         //-----------------
3343                         #endregion
3344
3345
3346                         // Undo 用に値を保管しておく。
3347
3348                         this.textBox製作者_以前の値 = this.textBox製作者.Text;
3349
3350
3351                         // 完了。
3352
3353                         CUndoRedo管理.bUndoRedoした直後 = false;
3354                         this.b未保存 = true;
3355                 }
3356                 private void textBox製作者_Leave( object sender, EventArgs e )
3357                 {
3358                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3359                 
3360                         if( oセル仮想 != null )
3361                                 oセル仮想.t所有権の放棄( this.textBox製作者 );
3362                 }
3363                 private void textBox製作者_Undo( string str変更前, string str変更後 )
3364                 {
3365                         // 変更前の値に戻す。
3366
3367                         this.tタブを選択する( Eタブ種別.基本情報 );
3368
3369                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3370                         this.textBox製作者.Text = str変更前;
3371
3372                         this.textBox製作者.Focus();
3373                 }
3374                 private void textBox製作者_Redo( string str変更前, string str変更後 )
3375                 {
3376                         // 変更後の値に戻す。
3377
3378                         this.tタブを選択する( Eタブ種別.基本情報 );
3379
3380                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3381                         this.textBox製作者.Text = str変更後;
3382
3383                         this.textBox製作者.Focus();
3384                 }
3385                 #endregion
3386                 #region [ Comment ]
3387                 private string textBoxコメント_以前の値 = "";
3388                 private void textBoxコメント_TextChanged( object sender, EventArgs e )
3389                 {
3390                         // Undo/Redo リストを修正する。
3391
3392                         #region [ Undo/Redo リストを修正。]
3393                         //-----------------
3394                         if( !CUndoRedo管理.bUndoRedoした直後 )
3395                         {
3396                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3397
3398                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBoxコメント ) )
3399                                 {
3400                                         // 既存のセルの値を更新。
3401
3402                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBoxコメント.Text;
3403                                 }
3404                                 else
3405                                 {
3406                                         // 新しいセルを追加。
3407
3408                                         this.mgrUndoRedo管理者.tノードを追加する(
3409                                                 new CUndoRedoセル<string>( 
3410                                                         this.textBoxコメント, 
3411                                                         new DGUndoを実行する<string>( this.textBoxコメント_Undo ), 
3412                                                         new DGRedoを実行する<string>( this.textBoxコメント_Redo ),
3413                                                         this.textBoxコメント_以前の値, this.textBoxコメント.Text ) );
3414
3415                                         // Undo ボタンを有効にする。
3416
3417                                         this.tUndoRedo用GUIの有効無効を設定する();
3418                                 }
3419                         }
3420                         //-----------------
3421                         #endregion
3422
3423
3424                         // Undo 用に値を保管しておく。
3425
3426                         this.textBoxコメント_以前の値 = this.textBoxコメント.Text;
3427
3428
3429                         // 完了。
3430
3431                         CUndoRedo管理.bUndoRedoした直後 = false;
3432                         this.b未保存 = true;
3433                 }
3434                 private void textBoxコメント_Leave( object sender, EventArgs e )
3435                 {
3436                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3437                 
3438                         if( oセル仮想 != null )
3439                                 oセル仮想.t所有権の放棄( this.textBoxコメント );
3440                 }
3441                 private void textBoxコメント_Undo( string str変更前, string str変更後 )
3442                 {
3443                         // 変更前の値に戻す。
3444
3445                         this.tタブを選択する( Eタブ種別.基本情報 );
3446
3447                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3448                         this.textBoxコメント.Text = str変更前;
3449
3450                         this.textBoxコメント.Focus();
3451                 }
3452                 private void textBoxコメント_Redo( string str変更前, string str変更後 )
3453                 {
3454                         // 変更後の値に戻す。
3455
3456                         this.tタブを選択する( Eタブ種別.基本情報 );
3457
3458                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3459                         this.textBoxコメント.Text = str変更後;
3460
3461                         this.textBoxコメント.Focus();
3462                 }
3463                 #endregion
3464                 #region [ Genre ]
3465                 private string textBoxGenre_以前の値 = "";
3466                 private void textBoxGenre_TextChanged( object sender, EventArgs e )
3467                 {
3468                         // Undo/Redo リストを修正する。
3469
3470                         #region [ Undo/Redo リストを修正。]
3471                         //-----------------
3472                         if ( !CUndoRedo管理.bUndoRedoした直後 )
3473                         {
3474                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3475
3476                                 if ( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBoxGenre ) )
3477                                 {
3478                                         // 既存のセルの値を更新。
3479
3480                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBoxGenre.Text;
3481                                 }
3482                                 else
3483                                 {
3484                                         // 新しいセルを追加。
3485
3486                                         this.mgrUndoRedo管理者.tノードを追加する(
3487                                                 new CUndoRedoセル<string>(
3488                                                         this.textBoxGenre,
3489                                                         new DGUndoを実行する<string>( this.textBoxGenre_Undo ),
3490                                                         new DGRedoを実行する<string>( this.textBoxGenre_Redo ),
3491                                                         this.textBoxGenre_以前の値, this.textBoxGenre.Text ) );
3492
3493                                         // Undo ボタンを有効にする。
3494
3495                                         this.tUndoRedo用GUIの有効無効を設定する();
3496                                 }
3497                         }
3498                         //-----------------
3499                         #endregion
3500
3501
3502                         // Undo 用に値を保管しておく。
3503
3504                         this.textBoxGenre_以前の値 = this.textBoxGenre.Text;
3505
3506
3507                         // 完了。
3508
3509                         CUndoRedo管理.bUndoRedoした直後 = false;
3510                         this.b未保存 = true;
3511                 }
3512                 private void textBoxGenre_Leave( object sender, EventArgs e )
3513                 {
3514                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3515
3516                         if ( oセル仮想 != null )
3517                                 oセル仮想.t所有権の放棄( this.textBoxGenre );
3518                 }
3519                 private void textBoxGenre_Undo( string str変更前, string str変更後 )
3520                 {
3521                         // 変更前の値に戻す。
3522
3523                         this.tタブを選択する( Eタブ種別.基本情報 );
3524
3525                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3526                         this.textBoxGenre.Text = str変更前;
3527
3528                         this.textBoxGenre.Focus();
3529                 }
3530                 private void textBoxGenre_Redo( string str変更前, string str変更後 )
3531                 {
3532                         // 変更後の値に戻す。
3533
3534                         this.tタブを選択する( Eタブ種別.基本情報 );
3535
3536                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3537                         this.textBoxGenre.Text = str変更後;
3538
3539                         this.textBoxGenre.Focus();
3540                 }
3541                 #endregion
3542
3543                 #region [ BPM ]
3544                 private decimal numericUpDownBPM_以前の値 = 120.0M;
3545                 private void numericUpDownBPM_ValueChanged( object sender, EventArgs e )
3546                 {
3547                         // Undo/Redo リストを修正する。
3548
3549                         #region [ Undo/Redo リストの修正。]
3550                         //-----------------
3551                         if( !CUndoRedo管理.bUndoRedoした直後 )
3552                         {
3553                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3554
3555                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.numericUpDownBPM ) )
3556                                 {
3557                                         // 既存のセルの値を更新。
3558
3559                                         ( (CUndoRedoセル<decimal>) oセル仮想 ).変更後の値 = this.numericUpDownBPM.Value;
3560                                 }
3561                                 else
3562                                 {
3563                                         // 新しいセルを追加。
3564
3565                                         this.mgrUndoRedo管理者.tノードを追加する(
3566                                                 new CUndoRedoセル<decimal>(
3567                                                         this.numericUpDownBPM,
3568                                                         new DGUndoを実行する<decimal>( this.numericUpDownBPM_Undo ), 
3569                                                         new DGRedoを実行する<decimal>( this.numericUpDownBPM_Redo ),
3570                                                         this.numericUpDownBPM_以前の値, this.numericUpDownBPM.Value ) );
3571
3572
3573                                         // Undoボタンを有効にする。
3574
3575                                         this.tUndoRedo用GUIの有効無効を設定する();
3576                                 }
3577                         }
3578                         //-----------------
3579                         #endregion
3580
3581                         
3582                         // Undo 用に値を保管しておく。
3583
3584                         this.numericUpDownBPM_以前の値 = this.numericUpDownBPM.Value;
3585
3586
3587                         // 完了。
3588
3589                         CUndoRedo管理.bUndoRedoした直後 = false;
3590                         this.b未保存 = true;
3591                 }
3592                 private void numericUpDownBPM_Leave( object sender, EventArgs e )
3593                 {
3594                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3595                 
3596                         if( oセル仮想 != null )
3597                                 oセル仮想.t所有権の放棄( this.numericUpDownBPM );
3598                 }
3599                 private void numericUpDownBPM_Undo( decimal dec変更前, decimal dec変更後 )
3600                 {
3601                         // 変更前の値に戻す。
3602
3603                         this.tタブを選択する( Eタブ種別.基本情報 );
3604
3605                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3606                         this.numericUpDownBPM.Value = dec変更前;
3607
3608                         this.numericUpDownBPM.Focus();
3609                 }
3610                 private void numericUpDownBPM_Redo( decimal dec変更前, decimal dec変更後 )
3611                 {
3612                         // 変更後の値に戻す。
3613
3614                         this.tタブを選択する( Eタブ種別.基本情報 );
3615
3616                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3617                         this.numericUpDownBPM.Value = dec変更後;
3618
3619                         this.numericUpDownBPM.Focus();
3620                 }
3621                 #endregion
3622
3623                 #region [ DLEVEL ]
3624                 private int nDLEVEL_以前の値 = 50;
3625                 private void textBoxDLEVEL_TextChanged( object sender, EventArgs e )
3626                 {
3627                         // 何もしない。→ 数字以外が入力されていることもあるため、Leaveまで待つ。
3628                 }
3629                 private void textBoxDLEVEL_Leave( object sender, EventArgs e )
3630                 {
3631                         if( this.textBoxDLEVEL.Text.Length > 0 )
3632                         {
3633                                 // 数値チェック。
3634
3635                                 int n値;
3636                                 if( !int.TryParse( this.textBoxDLEVEL.Text, out n値 ) )
3637                                 {
3638                                         n値 = 0;
3639                                 }
3640                                 else if( n値 < 0 )
3641                                 {
3642                                         n値 = 0;
3643                                 }
3644                                 else if( n値 > 100 )
3645                                 {
3646                                         n値 = 100;
3647                                 }
3648
3649
3650                                 // 値を水平スクロールバーにも反映。
3651
3652                                 if( this.hScrollBarDLEVEL.Value != n値 )
3653                                 {
3654                                         this.t次のプロパティ変更処理がUndoRedoリストに載るようにする();
3655                                         this.hScrollBarDLEVEL.Value = n値;     // ここで hScrollBarDLEVEL_ValueChanged が発動 → UndoRedo処理はそちらで。
3656                                 }
3657                         }
3658                 }
3659                 private void hScrollBarDLEVEL_ValueChanged( object sender, EventArgs e )
3660                 {
3661                         // 値をテキストボックスにも反映。
3662
3663                         this.textBoxDLEVEL.Text = this.hScrollBarDLEVEL.Value.ToString();
3664
3665
3666                         // Undo/Redo リストを修正。
3667
3668                         #region [ Undo/Redo リストを修正する。]
3669                         //-----------------
3670                         if( !CUndoRedo管理.bUndoRedoした直後 )
3671                         {
3672                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3673
3674                                 if( oセル仮想 != null && oセル仮想.b所有権がある( this.hScrollBarDLEVEL ) )
3675                                 {
3676                                         // 既存のセルの値を更新。
3677
3678                                         ( (CUndoRedoセル<int>) oセル仮想 ).変更後の値 = this.hScrollBarDLEVEL.Value;
3679                                 }
3680                                 else
3681                                 {
3682                                         // 新しいセルを追加。
3683
3684                                         this.mgrUndoRedo管理者.tノードを追加する( 
3685                                                 new CUndoRedoセル<int>( 
3686                                                         this.hScrollBarDLEVEL,
3687                                                         new DGUndoを実行する<int>( this.nDLEVEL_Undo ),
3688                                                         new DGRedoを実行する<int>( this.nDLEVEL_Redo ), 
3689                                                         this.nDLEVEL_以前の値, this.hScrollBarDLEVEL.Value ) );
3690
3691
3692                                         // Undo ボタンを有効にする。
3693
3694                                         this.tUndoRedo用GUIの有効無効を設定する();
3695                                 }
3696                         }
3697                         //-----------------
3698                         #endregion
3699
3700                         
3701                         // Undo 用に値を保管しておく。
3702
3703                         this.nDLEVEL_以前の値 = this.hScrollBarDLEVEL.Value;
3704
3705
3706                         // 完了。
3707
3708                         CUndoRedo管理.bUndoRedoした直後 = false;
3709                         this.b未保存 = true;
3710                 }
3711                 private void nDLEVEL_Undo( int n変更前, int n変更後 )
3712                 {
3713                         // 変更前の値に戻す。
3714
3715                         this.tタブを選択する( Eタブ種別.基本情報 );
3716
3717                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3718                         this.textBoxDLEVEL.Text = n変更前.ToString();
3719
3720                         this.textBoxDLEVEL.Focus();
3721
3722
3723                         // 値を水平スクロールバーにも反映。
3724
3725                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3726                         this.hScrollBarDLEVEL.Value = n変更前;
3727                 }
3728                 private void nDLEVEL_Redo( int n変更前, int n変更後 )
3729                 {
3730                         // 変更後の値に戻す。
3731
3732                         this.tタブを選択する( Eタブ種別.基本情報 );
3733
3734                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3735                         this.textBoxDLEVEL.Text = n変更後.ToString();
3736
3737                         this.textBoxDLEVEL.Focus();
3738
3739
3740                         // 値を水平スクロールバーにも反映。
3741
3742                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3743                         this.hScrollBarDLEVEL.Value = n変更後;
3744                 }
3745                 #endregion
3746                 #region [ GLEVEL ]
3747                 private int nGLEVEL_以前の値;
3748                 private void textBoxGLEVEL_TextChanged( object sender, EventArgs e )
3749                 {
3750                         // 何もしない。→ 数字以外が入力されていることもあるため、Leaveまで待つ。
3751                 }
3752                 private void textBoxGLEVEL_Leave( object sender, EventArgs e )
3753                 {
3754                         if( this.textBoxGLEVEL.Text.Length > 0 )
3755                         {
3756                                 // 数値チェック。
3757
3758                                 int n値;
3759                                 if( !int.TryParse( this.textBoxGLEVEL.Text, out n値 ) )
3760                                 {
3761                                         n値 = 0;
3762                                 }
3763                                 else if( n値 < 0 )
3764                                 {
3765                                         n値 = 0;
3766                                 }
3767                                 else if( n値 > 100 )
3768                                 {
3769                                         n値 = 100;
3770                                 }
3771
3772
3773                                 // 値を水平スクロールバーにも反映。
3774
3775                                 if( this.hScrollBarGLEVEL.Value != n値 )
3776                                 {
3777                                         this.t次のプロパティ変更処理がUndoRedoリストに載るようにする();
3778                                         this.hScrollBarGLEVEL.Value = n値;             // ここで hScrollBarGLEVEL_ValueChanged が発動 → UndoRedo処理はそちらで。
3779                                 }
3780                         }
3781                 }
3782                 private void hScrollBarGLEVEL_ValueChanged( object sender, EventArgs e )
3783                 {
3784                         // 値をテキストボックスにも反映。
3785
3786                         this.textBoxGLEVEL.Text = this.hScrollBarGLEVEL.Value.ToString();
3787
3788                         // Undo/Redo リストを修正。
3789
3790                         #region [ Undo/Redo リストを修正する。]
3791                         //-----------------
3792                         if( !CUndoRedo管理.bUndoRedoした直後 )
3793                         {
3794                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3795
3796                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.hScrollBarGLEVEL ) )
3797                                 {
3798                                         // 既存のセルの値を更新。
3799
3800                                         ( (CUndoRedoセル<int>) oセル仮想 ).変更後の値 = this.hScrollBarGLEVEL.Value;
3801                                 }
3802                                 else
3803                                 {
3804                                         // 新しいセルを追加。
3805
3806                                         this.mgrUndoRedo管理者.tノードを追加する(
3807                                                 new CUndoRedoセル<int>(
3808                                                         this.hScrollBarGLEVEL,
3809                                                         new DGUndoを実行する<int>( this.nGLEVEL_Undo ),
3810                                                         new DGRedoを実行する<int>( this.nGLEVEL_Redo ),
3811                                                         this.nGLEVEL_以前の値, this.hScrollBarGLEVEL.Value ) );
3812
3813
3814                                         // Undo ボタンを有効にする。
3815                                         
3816                                         this.tUndoRedo用GUIの有効無効を設定する();
3817                                 }
3818                         }
3819                         //-----------------
3820                         #endregion
3821
3822
3823                         // Undo 用に値を保管しておく。
3824
3825                         this.nGLEVEL_以前の値 = this.hScrollBarGLEVEL.Value;
3826                         
3827                         
3828                         // 完了。
3829
3830                         CUndoRedo管理.bUndoRedoした直後 = false;
3831                         this.b未保存 = true;
3832                 }
3833                 private void nGLEVEL_Undo( int n変更前, int n変更後 )
3834                 {
3835                         // 変更前の値に戻す。
3836
3837                         this.tタブを選択する( Eタブ種別.基本情報 );
3838
3839                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3840                         this.textBoxGLEVEL.Text = n変更前.ToString();
3841
3842                         this.textBoxGLEVEL.Focus();
3843
3844
3845                         // 値を水平スクロールバーにも反映する。
3846
3847                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3848                         this.hScrollBarGLEVEL.Value = n変更前;
3849                 }
3850                 private void nGLEVEL_Redo( int n変更前, int n変更後 )
3851                 {
3852                         // 変更後の値に戻す。
3853
3854                         this.tタブを選択する( Eタブ種別.基本情報 );
3855
3856                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3857                         this.textBoxGLEVEL.Text = n変更後.ToString();
3858
3859                         this.textBoxGLEVEL.Focus();
3860
3861                         
3862                         // 値を水平スクロールバーにも反映する。
3863
3864                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3865                         this.hScrollBarGLEVEL.Value = n変更後;
3866                 }
3867                 #endregion
3868                 #region [ BLEVEL ]
3869                 private int nBLEVEL_以前の値;
3870                 private void textBoxBLEVEL_TextChanged( object sender, EventArgs e )
3871                 {
3872                         // 何もしない。→ 数字以外が入力されていることもあるため、Leaveまで待つ。
3873                 }
3874                 private void textBoxBLEVEL_Leave( object sender, EventArgs e )
3875                 {
3876                         if( this.textBoxBLEVEL.Text.Length > 0 )
3877                         {
3878                                 // 数値チェック。
3879
3880                                 int n値;
3881                                 if( !int.TryParse( this.textBoxBLEVEL.Text, out n値 ) )
3882                                 {
3883                                         n値 = 0;
3884                                 }
3885                                 else if( n値 < 0 )
3886                                 {
3887                                         n値 = 0;
3888                                 }
3889                                 else if( n値 > 100 )
3890                                 {
3891                                         n値 = 100;
3892                                 }
3893
3894
3895                                 // 値を水平スクロールバーにも反映。
3896
3897                                 if( this.hScrollBarBLEVEL.Value != n値 )
3898                                 {
3899                                         this.t次のプロパティ変更処理がUndoRedoリストに載るようにする();
3900                                         this.hScrollBarBLEVEL.Value = n値;             // ここで hScrollBarBLEVEL_ValueChanged が発動 → UndoRedo処理はそちらで。
3901                                 }
3902                         }
3903                 }
3904                 private void hScrollBarBLEVEL_ValueChanged( object sender, EventArgs e )
3905                 {
3906                         // 値をテキストボックスにも反映。
3907
3908                         this.textBoxBLEVEL.Text = this.hScrollBarBLEVEL.Value.ToString();
3909
3910
3911                         // Undo/Redo リストを修正。
3912
3913                         #region [ Undo/Redo リストを修正する。]
3914                         //-----------------
3915                         if( !CUndoRedo管理.bUndoRedoした直後 )
3916                         {
3917                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
3918
3919                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.hScrollBarBLEVEL ) )
3920                                 {
3921                                         // 既存のセルの値を更新。
3922                                         
3923                                         ( (CUndoRedoセル<int>) oセル仮想 ).変更後の値 = this.hScrollBarBLEVEL.Value;
3924                                 }
3925                                 else
3926                                 {
3927                                         // 新しいセルを追加。
3928
3929                                         this.mgrUndoRedo管理者.tノードを追加する( 
3930                                                 new CUndoRedoセル<int>(
3931                                                         this.hScrollBarBLEVEL,
3932                                                         new DGUndoを実行する<int>( this.nBLEVEL_Undo ),
3933                                                         new DGRedoを実行する<int>( this.nBLEVEL_Redo ),
3934                                                         this.nBLEVEL_以前の値, this.hScrollBarBLEVEL.Value ) );
3935
3936                 
3937                                         // Undo ボタンを有効にする。
3938
3939                                         this.tUndoRedo用GUIの有効無効を設定する();
3940                                 }
3941                         }
3942                         //-----------------
3943                         #endregion
3944
3945                         
3946                         // Undo 用に値を保管しておく。
3947
3948                         this.nBLEVEL_以前の値 = this.hScrollBarBLEVEL.Value;
3949
3950
3951                         // 完了。
3952
3953                         CUndoRedo管理.bUndoRedoした直後 = false;
3954                         this.b未保存 = true;
3955                 }
3956                 private void nBLEVEL_Undo( int n変更前, int n変更後 )
3957                 {
3958                         // 変更前の値に戻す。
3959
3960                         this.tタブを選択する( Eタブ種別.基本情報 );
3961
3962                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3963                         this.textBoxBLEVEL.Text = n変更前.ToString();
3964
3965                         this.textBoxBLEVEL.Focus();
3966
3967
3968                         // 値を水平スクロールバーにも反映。
3969
3970                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3971                         this.hScrollBarBLEVEL.Value = n変更前;
3972                 }
3973                 private void nBLEVEL_Redo( int n変更前, int n変更後 )
3974                 {
3975                         // 変更後の値に戻す。
3976
3977                         this.tタブを選択する( Eタブ種別.基本情報 );
3978
3979                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3980                         this.textBoxBLEVEL.Text = n変更後.ToString();
3981
3982                         this.textBoxBLEVEL.Focus();
3983
3984
3985                         // 値を水平スクロールバーにも反映。
3986
3987                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
3988                         this.hScrollBarBLEVEL.Value = n変更後;
3989                 }
3990                 #endregion
3991
3992                 #region [ PANEL ]
3993                 private string textBoxパネル_以前の値 = "";
3994                 private void textBoxパネル_TextChanged( object sender, EventArgs e )
3995                 {
3996                         // Undo/Redo リストを修正。
3997
3998                         #region [ Undo/Redo リストを修正する。]
3999                         //-----------------
4000                         if( !CUndoRedo管理.bUndoRedoした直後 )
4001                         {
4002                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4003
4004                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBoxパネル ) )
4005                                 {
4006                                         // 既存のセルの値を更新。
4007
4008                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBoxパネル.Text;
4009                                 }
4010                                 else
4011                                 {
4012                                         // 新しいセルを追加。
4013
4014                                         this.mgrUndoRedo管理者.tノードを追加する(
4015                                                 new CUndoRedoセル<string>(
4016                                                         this.textBoxパネル, 
4017                                                         new DGUndoを実行する<string>( this.textBoxパネル_Undo ),
4018                                                         new DGRedoを実行する<string>( this.textBoxパネル_Redo ), 
4019                                                         this.textBoxパネル_以前の値, this.textBoxパネル.Text ) );
4020
4021
4022                                         // Undoボタンを有効にする。
4023
4024                                         this.tUndoRedo用GUIの有効無効を設定する();
4025                                 }
4026                         }
4027                         //-----------------
4028                         #endregion
4029
4030
4031                         // Undo 用に値を保管しておく。
4032
4033                         this.textBoxパネル_以前の値 = this.textBoxパネル.Text;
4034
4035
4036                         // 完了。
4037
4038                         CUndoRedo管理.bUndoRedoした直後 = false;
4039                         this.b未保存 = true;
4040                 }
4041                 private void textBoxパネル_Leave( object sender, EventArgs e )
4042                 {
4043                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4044
4045                         if( oセル仮想 != null )
4046                                 oセル仮想.t所有権の放棄( this.textBoxパネル );
4047                 }
4048                 private void textBoxパネル_Undo( string str変更前, string str変更後 )
4049                 {
4050                         // 変更前の値に戻す。
4051
4052                         this.tタブを選択する( Eタブ種別.基本情報 );
4053
4054                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4055                         this.textBoxパネル.Text = str変更前;
4056
4057                         this.textBoxパネル.Focus();
4058                 }
4059                 private void textBoxパネル_Redo( string str変更前, string str変更後 )
4060                 {
4061                         // 変更後の値に戻す。
4062
4063                         this.tタブを選択する( Eタブ種別.基本情報 );
4064
4065                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4066                         this.textBoxパネル.Text = str変更後;
4067
4068                         this.textBoxパネル.Focus();
4069                 }
4070                 #endregion
4071                 #region [ PREVIEW ]
4072                 private string textBoxPREVIEW_以前の値 = "";
4073                 private void textBoxPREVIEW_TextChanged( object sender, EventArgs e )
4074                 {
4075                         // Undo/Redo リストを修正。
4076
4077                         #region [ Undo/Redo リストを修正する。]
4078                         //-----------------
4079                         if( !CUndoRedo管理.bUndoRedoした直後 )
4080                         {
4081                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4082
4083                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBoxPREVIEW ) )
4084                                 {
4085                                         // 既存のセルの値を更新。
4086
4087                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBoxPREVIEW.Text;
4088                                 }
4089                                 else
4090                                 {
4091                                         // 新しいセルを追加。
4092
4093                                         this.mgrUndoRedo管理者.tノードを追加する( 
4094                                                 new CUndoRedoセル<string>(
4095                                                         this.textBoxPREVIEW,
4096                                                         new DGUndoを実行する<string>( this.textBoxPREVIEW_Undo ),
4097                                                         new DGRedoを実行する<string>( this.textBoxPREVIEW_Redo ), 
4098                                                         this.textBoxPREVIEW_以前の値, this.textBoxPREVIEW.Text ) );
4099
4100                                         
4101                                         // Undo ボタンを有効にする。
4102
4103                                         this.tUndoRedo用GUIの有効無効を設定する();
4104                                 }
4105                         }
4106                         //-----------------
4107                         #endregion
4108
4109
4110                         // Undo 用に値を保管しておく。
4111
4112                         this.textBoxPREVIEW_以前の値 = this.textBoxPREVIEW.Text;
4113
4114
4115                         // 完了。
4116
4117                         CUndoRedo管理.bUndoRedoした直後 = false;
4118                         this.b未保存 = true;
4119                 }
4120                 private void textBoxPREVIEW_Leave( object sender, EventArgs e )
4121                 {
4122                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4123
4124                         if( oセル仮想 != null )
4125                                 oセル仮想.t所有権の放棄( this.textBoxPREVIEW );
4126                 }
4127                 private void textBoxPREVIEW_Undo( string str変更前, string str変更後 )
4128                 {
4129                         // 変更前の値に戻す。
4130
4131                         this.tタブを選択する( Eタブ種別.基本情報 );
4132
4133                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4134                         this.textBoxPREVIEW.Text = str変更前;
4135
4136                         this.textBoxPREVIEW.Focus();
4137                 }
4138                 private void textBoxPREVIEW_Redo( string str変更前, string str変更後 )
4139                 {
4140                         // 変更前の値に戻す。
4141
4142                         this.tタブを選択する( Eタブ種別.基本情報 );
4143
4144                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4145                         this.textBoxPREVIEW.Text = str変更後;
4146
4147                         this.textBoxPREVIEW.Focus();
4148                 }
4149                 #endregion
4150                 #region [ PREIMAGE ]
4151                 private string textBoxPREIMAGE_以前の値 = "";
4152                 private void textBoxPREIMAGE_TextChanged( object sender, EventArgs e )
4153                 {
4154                         // Undo/Redo リストを修正。
4155
4156                         #region [ Undo/Redo リストを修正する。]
4157                         //-----------------
4158                         if( !CUndoRedo管理.bUndoRedoした直後 )
4159                         {
4160                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4161
4162                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBoxPREIMAGE ) )
4163                                 {
4164                                         // 既存のセルの値を更新。
4165
4166                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBoxPREIMAGE.Text;
4167                                 }
4168                                 else
4169                                 {
4170                                         // 新規のセルを作成。
4171
4172                                         this.mgrUndoRedo管理者.tノードを追加する( 
4173                                                 new CUndoRedoセル<string>( 
4174                                                         this.textBoxPREIMAGE, 
4175                                                         new DGUndoを実行する<string>( this.textBoxPREIMAGE_Undo ), 
4176                                                         new DGRedoを実行する<string>( this.textBoxPREIMAGE_Redo ), 
4177                                                         this.textBoxPREIMAGE_以前の値, this.textBoxPREIMAGE.Text ) );
4178
4179
4180                                         // Undo ボタンを有効にする。
4181
4182                                         this.tUndoRedo用GUIの有効無効を設定する();
4183                                 }
4184                         }
4185                         //-----------------
4186                         #endregion
4187
4188
4189                         // Undo用に値を保管しておく。]
4190
4191                         this.textBoxPREIMAGE_以前の値 = this.textBoxPREIMAGE.Text;
4192                         
4193                         
4194                         // 完了。
4195
4196                         CUndoRedo管理.bUndoRedoした直後 = false;
4197                         this.b未保存 = true;
4198                 }
4199                 private void textBoxPREIMAGE_Leave( object sender, EventArgs e )
4200                 {
4201                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4202
4203                         if( oセル仮想 != null )
4204                                 oセル仮想.t所有権の放棄( this.textBoxPREIMAGE );
4205                 }
4206                 private void textBoxPREIMAGE_Undo( string str変更前, string str変更後 )
4207                 {
4208                         // 変更前の値に戻す。
4209
4210                         this.tタブを選択する( Eタブ種別.基本情報 );
4211
4212                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4213                         this.textBoxPREIMAGE.Text = str変更前;
4214
4215                         this.textBoxPREIMAGE.Focus();
4216                 }
4217                 private void textBoxPREIMAGE_Redo( string str変更前, string str変更後 )
4218                 {
4219                         // 変更後の値に戻す。
4220
4221                         this.tタブを選択する( Eタブ種別.基本情報 );
4222
4223                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4224                         this.textBoxPREIMAGE.Text = str変更後;
4225
4226                         this.textBoxPREIMAGE.Focus();
4227                 }
4228                 #endregion
4229                 #region [ STAGEFILE ]
4230                 private string textBoxSTAGEFILE_以前の値 = "";
4231                 private void textBoxSTAGEFILE_TextChanged( object sender, EventArgs e )
4232                 {
4233                         // Undo/Redo リストを修正。
4234
4235                         #region [ Undo/Redo リストを修正する。]
4236                         //-----------------
4237                         if( !CUndoRedo管理.bUndoRedoした直後 )
4238                         {
4239                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4240
4241                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBoxSTAGEFILE ) )
4242                                 {
4243                                         // 既存のセルの値を更新。
4244
4245                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBoxSTAGEFILE.Text;
4246                                 }
4247                                 else
4248                                 {
4249                                         // 新しいセルを追加。
4250
4251                                         this.mgrUndoRedo管理者.tノードを追加する( 
4252                                                 new CUndoRedoセル<string>(
4253                                                         this.textBoxSTAGEFILE,
4254                                                         new DGUndoを実行する<string>( this.textBoxSTAGEFILE_Undo ),
4255                                                         new DGRedoを実行する<string>( this.textBoxSTAGEFILE_Redo ), 
4256                                                         this.textBoxSTAGEFILE_以前の値, this.textBoxSTAGEFILE.Text ) );
4257
4258
4259                                         // Undo ボタンを有効にする。
4260
4261                                         this.tUndoRedo用GUIの有効無効を設定する();
4262                                 }
4263                         }
4264                         //-----------------
4265                         #endregion
4266
4267
4268                         // Undo 用に値を保管しておく。
4269
4270                         this.textBoxSTAGEFILE_以前の値 = this.textBoxSTAGEFILE.Text;
4271
4272
4273                         // 完了。
4274
4275                         CUndoRedo管理.bUndoRedoした直後 = false;
4276                         this.b未保存 = true;
4277                 }
4278                 private void textBoxSTAGEFILE_Leave( object sender, EventArgs e )
4279                 {
4280                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4281
4282                         if( oセル仮想 != null )
4283                                 oセル仮想.t所有権の放棄( this.textBoxSTAGEFILE );
4284                 }
4285                 private void textBoxSTAGEFILE_Undo( string str変更前, string str変更後 )
4286                 {
4287                         // 変更前の値に戻す。
4288
4289                         this.tタブを選択する( Eタブ種別.基本情報 );
4290
4291                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4292                         this.textBoxSTAGEFILE.Text = str変更前;
4293
4294                         this.textBoxSTAGEFILE.Focus();
4295                 }
4296                 private void textBoxSTAGEFILE_Redo( string str変更前, string str変更後 )
4297                 {
4298                         // 変更後の値に戻す。
4299
4300                         this.tタブを選択する( Eタブ種別.基本情報 );
4301
4302                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4303                         this.textBoxSTAGEFILE.Text = str変更後;
4304
4305                         this.textBoxSTAGEFILE.Focus();
4306                 }
4307                 #endregion
4308                 #region [ BACKGROUND ]
4309                 private string textBoxBACKGROUND_以前の値 = "";
4310                 private void textBoxBACKGROUND_TextChanged( object sender, EventArgs e )
4311                 {
4312                         // Undo/Redo リストを修正。
4313
4314                         #region [ Undo/Redo リストを修正する。]
4315                         //-----------------
4316                         if( !CUndoRedo管理.bUndoRedoした直後 )
4317                         {
4318                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4319
4320                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBoxBACKGROUND ) )
4321                                 {
4322                                         // 既存のセルの値を更新。
4323
4324                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBoxBACKGROUND.Text;
4325                                 }
4326                                 else
4327                                 {
4328                                         // 新しいセルを追加。
4329
4330                                         this.mgrUndoRedo管理者.tノードを追加する( 
4331                                                 new CUndoRedoセル<string>(
4332                                                         this.textBoxBACKGROUND,
4333                                                         new DGUndoを実行する<string>( this.textBoxBACKGROUND_Undo ),
4334                                                         new DGRedoを実行する<string>( this.textBoxBACKGROUND_Redo ), 
4335                                                         this.textBoxBACKGROUND_以前の値, this.textBoxBACKGROUND.Text ) );
4336
4337
4338                                         // Undo ボタンを有効にする。
4339
4340                                         this.tUndoRedo用GUIの有効無効を設定する();
4341                                 }
4342                         }
4343                         //-----------------
4344                         #endregion
4345
4346
4347                         // Undo 用の値を保管しておく。
4348
4349                         this.textBoxBACKGROUND_以前の値 = this.textBoxBACKGROUND.Text;
4350
4351
4352                         // 完了。
4353
4354                         CUndoRedo管理.bUndoRedoした直後 = false;
4355                         this.b未保存 = true;
4356                 }
4357                 private void textBoxBACKGROUND_Leave( object sender, EventArgs e )
4358                 {
4359                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4360
4361                         if( oセル仮想 != null )
4362                                 oセル仮想.t所有権の放棄( this.textBoxBACKGROUND );
4363                 }
4364                 private void textBoxBACKGROUND_Undo( string str変更前, string str変更後 )
4365                 {
4366                         // 変更前の値に戻す。
4367
4368                         this.tタブを選択する( Eタブ種別.基本情報 );
4369
4370                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4371                         this.textBoxBACKGROUND.Text = str変更前;
4372
4373                         this.textBoxBACKGROUND.Focus();
4374                 }
4375                 private void textBoxBACKGROUND_Redo( string str変更前, string str変更後 )
4376                 {
4377                         // 変更後の値に戻す。
4378
4379                         this.tタブを選択する( Eタブ種別.基本情報 );
4380
4381                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4382                         this.textBoxBACKGROUND.Text = str変更後;
4383
4384                         this.textBoxBACKGROUND.Focus();
4385                 }
4386                 #endregion
4387                 #region [ RESULTIMAGE ]
4388                 private string textBoxRESULTIMAGE_以前の値 = "";
4389                 private void textBoxRESULTIMAGE_TextChanged( object sender, EventArgs e )
4390                 {
4391                         // Undo/Redo リストを修正。
4392
4393                         #region [ Undo/Redo リストを修正する。]
4394                         //-----------------
4395                         if( !CUndoRedo管理.bUndoRedoした直後 )
4396                         {
4397                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4398
4399                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBoxRESULTIMAGE ) )
4400                                 {
4401                                         // 既存のセルの値を更新。
4402
4403                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBoxRESULTIMAGE.Text;
4404                                 }
4405                                 else
4406                                 {
4407                                         // 新しいセルを追加。
4408
4409                                         this.mgrUndoRedo管理者.tノードを追加する( 
4410                                                 new CUndoRedoセル<string>(
4411                                                         this.textBoxRESULTIMAGE,
4412                                                         new DGUndoを実行する<string>( this.textBoxRESULTIMAGE_Undo ),
4413                                                         new DGRedoを実行する<string>( this.textBoxRESULTIMAGE_Redo ), 
4414                                                         this.textBoxRESULTIMAGE_以前の値, this.textBoxRESULTIMAGE.Text ) );
4415
4416
4417                                         // Undo ボタンを有効にする。
4418
4419                                         this.tUndoRedo用GUIの有効無効を設定する();
4420                                 }
4421                         }
4422                         //-----------------
4423                         #endregion
4424
4425
4426                         // Undo 用に値を保管しておく。
4427
4428                         this.textBoxRESULTIMAGE_以前の値 = this.textBoxRESULTIMAGE.Text;
4429
4430
4431                         // 完了。
4432
4433                         CUndoRedo管理.bUndoRedoした直後 = false;
4434                         this.b未保存 = true;
4435                 }
4436                 private void textBoxRESULTIMAGE_Leave( object sender, EventArgs e )
4437                 {
4438                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4439                 
4440                         if( oセル仮想 != null )
4441                                 oセル仮想.t所有権の放棄( this.textBoxRESULTIMAGE );
4442                 }
4443                 private void textBoxRESULTIMAGE_Undo( string str変更前, string str変更後 )
4444                 {
4445                         // 変更前の値に戻す。
4446
4447                         this.tタブを選択する( Eタブ種別.基本情報 );
4448
4449                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4450                         this.textBoxRESULTIMAGE.Text = str変更前;
4451
4452                         this.textBoxRESULTIMAGE.Focus();
4453                 }
4454                 private void textBoxRESULTIMAGE_Redo( string str変更前, string str変更後 )
4455                 {
4456                         // 変更後の値に戻す。
4457
4458                         this.tタブを選択する( Eタブ種別.基本情報 );
4459
4460                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4461                         this.textBoxRESULTIMAGE.Text = str変更後;
4462
4463                         this.textBoxRESULTIMAGE.Focus();
4464                 }
4465                 #endregion
4466
4467                 #region [ PREVIEW参照ボタン ]
4468                 private void buttonPREVIEW参照_Click( object sender, EventArgs e )
4469                 {
4470                         string str初期フォルダ名 = this.str作業フォルダ名;
4471
4472                         if( this.textBoxPREVIEW.Text.Length > 0 )
4473                                 str初期フォルダ名 = this.strファイルの存在するディレクトリを絶対パスで返す( this.textBoxPREVIEW.Text );
4474
4475                         string strファイル名 = this.tファイル選択ダイアログでファイルを選択し相対パスにして返す(
4476                                 Resources.strプレビュー音ファイル選択ダイアログのタイトル, 
4477                                 Resources.strサウンドファイル選択ダイアログのフィルタ, 
4478                                 str初期フォルダ名 );
4479
4480                         if( strファイル名.Length > 0 )
4481                         {
4482                                 this.textBoxPREVIEW.Text = strファイル名;
4483                                 this.b未保存 = true;
4484                         }
4485                 }
4486                 #endregion
4487                 #region [ PREIMAGE参照ボタン ]
4488                 private void buttonPREIMAGE参照_Click( object sender, EventArgs e )
4489                 {
4490                         string str初期フォルダ名 = this.str作業フォルダ名;
4491
4492                         if( this.textBoxPREIMAGE.Text.Length > 0 )
4493                                 str初期フォルダ名 = this.strファイルの存在するディレクトリを絶対パスで返す( this.textBoxPREIMAGE.Text );
4494
4495                         string strファイル名 = this.tファイル選択ダイアログでファイルを選択し相対パスにして返す(
4496                                 Resources.strプレビュー画像ファイル選択ダイアログのタイトル, 
4497                                 Resources.str画像ファイル選択ダイアログのフィルタ,
4498                                 str初期フォルダ名 );
4499                         
4500                         if( strファイル名.Length > 0 )
4501                         {
4502                                 this.textBoxPREIMAGE.Text = strファイル名;
4503                                 this.b未保存 = true;
4504                         }
4505                 }
4506                 #endregion
4507                 #region [ STAGEFILE参照ボタン ]
4508                 private void buttonSTAGEFILE参照_Click( object sender, EventArgs e )
4509                 {
4510                         string str初期フォルダ名 = this.str作業フォルダ名;
4511
4512                         if( this.textBoxSTAGEFILE.Text.Length > 0 )
4513                                 str初期フォルダ名 = this.strファイルの存在するディレクトリを絶対パスで返す( this.textBoxSTAGEFILE.Text );
4514
4515                         string strファイル名 = this.tファイル選択ダイアログでファイルを選択し相対パスにして返す(
4516                                 Resources.strステージ画像ファイル選択ダイアログのタイトル,
4517                                 Resources.str画像ファイル選択ダイアログのフィルタ, 
4518                                 str初期フォルダ名 );
4519
4520                         if( strファイル名.Length > 0 )
4521                         {
4522                                 this.textBoxSTAGEFILE.Text = strファイル名;
4523                                 this.b未保存 = true;
4524                         }
4525                 }
4526                 #endregion
4527                 #region [ BACKGROUND参照ボタン ]
4528                 private void buttonBACKGROUND参照_Click( object sender, EventArgs e )
4529                 {
4530                         string str初期フォルダ名 = this.str作業フォルダ名;
4531
4532                         if( this.textBoxBACKGROUND.Text.Length > 0 )
4533                                 str初期フォルダ名 = this.strファイルの存在するディレクトリを絶対パスで返す( this.textBoxBACKGROUND.Text );
4534
4535                         string strファイル名 = this.tファイル選択ダイアログでファイルを選択し相対パスにして返す(
4536                                 Resources.str背景画像ファイル選択ダイアログのタイトル, 
4537                                 Resources.str画像ファイル選択ダイアログのフィルタ, 
4538                                 str初期フォルダ名 );
4539
4540                         if( strファイル名.Length > 0 )
4541                         {
4542                                 this.textBoxBACKGROUND.Text = strファイル名;
4543                                 this.b未保存 = true;
4544                         }
4545                 }
4546                 #endregion
4547                 #region [ RESULTIMAGE参照ボタン ]
4548                 private void buttonRESULTIMAGE参照_Click( object sender, EventArgs e )
4549                 {
4550                         string str初期フォルダ名 = this.str作業フォルダ名;
4551                         
4552                         if( this.textBoxRESULTIMAGE.Text.Length > 0 )
4553                                 str初期フォルダ名 = this.strファイルの存在するディレクトリを絶対パスで返す( this.textBoxRESULTIMAGE.Text );
4554
4555                         string strファイル名 = this.tファイル選択ダイアログでファイルを選択し相対パスにして返す(
4556                                 Resources.str結果画像ファイル選択ダイアログのタイトル,
4557                                 Resources.str画像ファイル選択ダイアログのフィルタ, 
4558                                 str初期フォルダ名 );
4559
4560                         if( strファイル名.Length > 0 )
4561                         {
4562                                 this.textBoxRESULTIMAGE.Text = strファイル名;
4563                                 this.b未保存 = true;
4564                         }
4565                 }
4566                 #endregion
4567                 #region [ Use 556 x 710 BGA/AVI ]
4568                 private bool check556x710BGAAVI_以前の値 = false;
4569                 private void check556x710BGAAVI_CheckedChanged(object sender, EventArgs e)
4570                 {
4571                         // Undo/Redo リストを修正する。
4572
4573                         #region [ Undo/Redo リストを修正。]
4574                         //-----------------
4575                         if (!CUndoRedo管理.bUndoRedoした直後)
4576                         {
4577                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4578
4579                                 if ((oセル仮想 != null) && oセル仮想.b所有権がある(this.check556x710BGAAVI))
4580                                 {
4581                                         // 既存のセルの値を更新。
4582
4583                                         ((CUndoRedoセル<bool>)oセル仮想).変更後の値 = this.check556x710BGAAVI.Checked;
4584                                 }
4585                                 else
4586                                 {
4587                                         // 新しいセルを追加。
4588
4589                                         this.mgrUndoRedo管理者.tノードを追加する(
4590                                                 new CUndoRedoセル<bool>(
4591                                                         this.check556x710BGAAVI.Checked,
4592                                                         new DGUndoを実行する<bool>(this.check556x710BGAAVI_Undo),
4593                                                         new DGRedoを実行する<bool>(this.check556x710BGAAVI_Redo),
4594                                                         this.check556x710BGAAVI_以前の値, this.check556x710BGAAVI.Checked));
4595
4596                                         // Undo ボタンを有効にする。
4597
4598                                         this.tUndoRedo用GUIの有効無効を設定する();
4599                                 }
4600                         }
4601                         //-----------------
4602                         #endregion
4603
4604
4605                         // Undo 用に値を保管しておく。
4606
4607                         this.check556x710BGAAVI_以前の値 = this.check556x710BGAAVI.Checked;
4608                         
4609
4610                         // 完了。
4611
4612                         CUndoRedo管理.bUndoRedoした直後 = false;
4613                         this.b未保存 = true;
4614                 }
4615                 private void check556x710BGAAVI_Leave(object sender, EventArgs e)
4616                 {
4617                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
4618
4619                         if (oセル仮想 != null)
4620                                 oセル仮想.t所有権の放棄(this.check556x710BGAAVI);
4621                 }
4622                 private void check556x710BGAAVI_Undo(bool b変更前, bool b変更後)
4623                 {
4624                         // 変更前の値に戻す。
4625
4626                         this.tタブを選択する(Eタブ種別.基本情報);
4627
4628                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4629                         this.check556x710BGAAVI.Checked = b変更前;
4630
4631                         this.check556x710BGAAVI.Focus();
4632                 }
4633                 private void check556x710BGAAVI_Redo(bool b変更前, bool b変更後)
4634                 {
4635                         // 変更後の値に戻す。
4636
4637                         this.tタブを選択する(Eタブ種別.基本情報);
4638
4639                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
4640                         this.check556x710BGAAVI.Checked = b変更後;
4641
4642                         this.check556x710BGAAVI.Focus();
4643                 }
4644                 #endregion
4645                 //-----------------
4646                 #endregion
4647                 #region [ GUIイベント:WAVリスト関連 ]
4648                 //-----------------
4649                 private void listViewWAVリスト_Click( object sender, EventArgs e )
4650                 {
4651                         #region [ プレビュー音を再生する。]
4652                         //-----------------
4653                         if( this.listViewWAVリスト.SelectedIndices.Count > 0 && this.toolStripButtonWAVリストプレビュースイッチ.Checked )
4654                         {
4655                                 ListViewItem item = this.listViewWAVリスト.Items[ this.listViewWAVリスト.SelectedIndices[ 0 ] ];
4656                                 this.mgrWAVリスト管理者.tプレビュー音を再生する( C変換.n36進数2桁の文字列を数値に変換して返す( item.SubItems[ 1 ].Text ) );
4657                         }
4658                         //-----------------
4659                         #endregion
4660                 }
4661                 private void listViewWAVリスト_DoubleClick( object sender, EventArgs e )
4662                 {
4663                         #region [ サウンドプロパティを開いて編集する。]
4664                         //-----------------
4665                         if( this.mgrWAVリスト管理者.n現在選択中のItem番号0to1294 < 0 )
4666                                 return;         // 選択されていない
4667
4668                         this.mgrWAVリスト管理者.tサウンドプロパティを開いて編集する( this.mgrWAVリスト管理者.n現在選択中のItem番号0to1294 + 1, this.str作業フォルダ名 );
4669                         //-----------------
4670                         #endregion
4671                 }
4672                 private void listViewWAVリスト_ItemDrag( object sender, ItemDragEventArgs e )
4673                 {
4674                         #region [ CWAVデータをDragDrop用データに格納し、DoDragDrop()を呼び出す。]
4675                         //-----------------
4676                         var item = (ListViewItem) e.Item;
4677
4678                         var data = new Cチップパレット向けDragDropデータ() {
4679                                 n種類 = 0,
4680                                 strラベル名 = item.SubItems[ 0 ].Text,
4681                                 n番号1to1295 = C変換.n36進数2桁の文字列を数値に変換して返す( item.SubItems[ 1 ].Text ),
4682                                 strファイル名 = item.SubItems[ 2 ].Text,
4683                                 col文字色 = item.ForeColor,
4684                                 col背景色 = item.BackColor,
4685                         };
4686
4687                         this.DoDragDrop( data, DragDropEffects.Copy );
4688
4689                         //-----------------
4690                         #endregion
4691                 }
4692                 private void listViewWAVリスト_KeyPress( object sender, KeyPressEventArgs e )
4693                 {
4694                         #region [ ENTER が押下されたら、サウンドプロパティを開いて編集する。]
4695                         //-----------------
4696                         if( e.KeyChar == (char) Keys.Return )
4697                         {
4698                                 if( this.mgrWAVリスト管理者.n現在選択中のItem番号0to1294 < 0 )
4699                                         return;         // 選択されていない
4700
4701                                 this.mgrWAVリスト管理者.tサウンドプロパティを開いて編集する( this.mgrWAVリスト管理者.n現在選択中のItem番号0to1294 + 1, this.str作業フォルダ名 );
4702                         }
4703                         //-----------------
4704                         #endregion
4705                 }
4706                 private void listViewWAVリスト_MouseEnter( object sender, EventArgs e )
4707                 {
4708                         #region [ WAVリストにフォーカスを移動する。]
4709                         //-----------------
4710                         if( this.appアプリ設定.AutoFocus )
4711                                 this.mgrWAVリスト管理者.tWAVリストにフォーカスを当てる();
4712                         //-----------------
4713                         #endregion
4714                 }
4715                 private void listViewWAVリスト_RetrieveVirtualItem( object sender, RetrieveVirtualItemEventArgs e )
4716                 {
4717                         e.Item = this.mgrWAVリスト管理者.tCWAVとListViewItemを生成して返す( e.ItemIndex + 1 );
4718                 }
4719                 private void listViewWAVリスト_SelectedIndexChanged( object sender, EventArgs e )
4720                 {
4721                         #region [ WAV, BMP, AVI のカーソルを、選択された行に全部合わせる。]
4722                         //-----------------
4723                         if( this.listViewWAVリスト.SelectedIndices.Count > 0 )
4724                                 this.tWAV_BMP_AVIリストのカーソルを全部同じ行に合わせる( this.listViewWAVリスト.SelectedIndices[ 0 ] );
4725                         //-----------------
4726                         #endregion
4727                 }
4728
4729                 private void toolStripButtonWAVリストプレビュースイッチ_CheckStateChanged( object sender, EventArgs e )
4730                 {
4731                         #region [ 再生ボタンと停止ボタンの有効・無効を設定する。]
4732                         //-----------------
4733                         bool b再生有効 = ( this.toolStripButtonWAVリストプレビュースイッチ.CheckState == CheckState.Checked ) ? true : false;
4734                         this.toolStripButtonWAVリストプレビュー再生開始.Enabled = b再生有効;
4735                         this.toolStripButtonWAVリストプレビュー再生停止.Enabled = b再生有効;
4736                         //-----------------
4737                         #endregion
4738
4739                         #region [ 無効かつ再生中ならプレビュー音を停止する。]
4740                         //-----------------
4741                         if( !b再生有効 )
4742                                 this.mgrWAVリスト管理者.tプレビュー音を停止する();
4743                         //-----------------
4744                         #endregion
4745                 }
4746                 private void toolStripButtonWAVリストプレビュー再生開始_Click( object sender, EventArgs e )
4747                 {
4748                         #region [ 現在選択中のWAVのプレビュー音を再生する。]
4749                         //-----------------
4750                         if( this.listViewWAVリスト.SelectedIndices.Count <= 0 )
4751                                 return; // 選択されてない
4752
4753                         bool b再生有効 = ( this.toolStripButtonWAVリストプレビュースイッチ.CheckState == CheckState.Checked ) ? true : false;
4754
4755             if (b再生有効)
4756                         {
4757                                 int nWAV番号1to1295 = this.mgrWAVリスト管理者.n現在選択中のItem番号0to1294 + 1;
4758                                 this.mgrWAVリスト管理者.tプレビュー音を再生する( nWAV番号1to1295 );
4759                         }
4760                         //-----------------
4761                         #endregion
4762                 }
4763                 private void toolStripButtonWAVリストプレビュー再生停止_Click( object sender, EventArgs e )
4764                 {
4765                         this.mgrWAVリスト管理者.tプレビュー音を停止する();
4766                 }
4767                 private void toolStripButtonWAVリスト上移動_Click( object sender, EventArgs e )
4768                 {
4769                         #region [ 上の行とWAVを交換する。]
4770                         //-----------------
4771                         if( this.listViewWAVリスト.SelectedIndices.Count <= 0 )
4772                                 return; // 選択されていない
4773
4774                         int n選択されたItem番号0to1294 = this.listViewWAVリスト.SelectedIndices[ 0 ];
4775
4776                         if( n選択されたItem番号0to1294 == 0 )
4777                                 return; // 最上行なので無視
4778
4779                         this.mgrWAVリスト管理者.tItemを交換する( n選択されたItem番号0to1294, n選択されたItem番号0to1294 - 1 );
4780                         //-----------------
4781                         #endregion
4782                 }
4783                 private void toolStripButtonWAVリスト下移動_Click( object sender, EventArgs e )
4784                 {
4785                         if( this.listViewWAVリスト.SelectedIndices.Count <= 0 )
4786                                 return; // 選択されていない
4787
4788                         int n選択されたItem番号0to1294 = this.listViewWAVリスト.SelectedIndices[ 0 ];
4789
4790                         if( n選択されたItem番号0to1294 >= 1294 )
4791                                 return; // 最下行なので無視
4792
4793                         this.mgrWAVリスト管理者.tItemを交換する( n選択されたItem番号0to1294, n選択されたItem番号0to1294 + 1 );
4794                 }
4795                 //-----------------
4796                 #endregion
4797                 #region [ GUIイベント:BMPリスト関連 ]
4798                 //-----------------
4799                 private void listViewBMPリスト_Click( object sender, EventArgs e )
4800                 {
4801                         // 何もしない
4802                 }
4803                 private void listViewBMPリスト_DoubleClick( object sender, EventArgs e )
4804                 {
4805                         #region [ 画像プロパティを開いて編集する。]
4806                         //-----------------
4807                         if( this.mgrBMPリスト管理者.n現在選択中のItem番号0to1294 < 0 )
4808                                 return;         // 選択されていない
4809
4810                         this.mgrBMPリスト管理者.t画像プロパティを開いて編集する( this.mgrBMPリスト管理者.n現在選択中のItem番号0to1294 + 1, this.str作業フォルダ名 );
4811                         //-----------------
4812                         #endregion
4813                 }
4814                 private void listViewBMPリスト_ItemDrag( object sender, ItemDragEventArgs e )
4815                 {
4816                         #region [ CBMPデータをDragDrop用データに格納し、DoDragDrop()を呼び出す。]
4817                         //-----------------
4818                         var item = (ListViewItem) e.Item;
4819
4820                         var data = new Cチップパレット向けDragDropデータ() {
4821                                 n種類 = 1,
4822                                 strラベル名 = item.SubItems[ 1 ].Text,
4823                                 n番号1to1295 = C変換.n36進数2桁の文字列を数値に変換して返す( item.SubItems[ 2 ].Text ),
4824                                 strファイル名 = item.SubItems[ 3 ].Text,
4825                                 col文字色 = item.ForeColor,
4826                                 col背景色 = item.BackColor,
4827                         };
4828
4829                         this.DoDragDrop( data, DragDropEffects.Copy );
4830                         //-----------------
4831                         #endregion
4832                 }
4833                 private void listViewBMPリスト_KeyPress( object sender, KeyPressEventArgs e )
4834                 {
4835                         #region [ ENTER が押下されたら、画像プロパティを開いて編集する。]
4836                         //-----------------
4837                         if( e.KeyChar == (char) Keys.Return )
4838                         {
4839                                 if( this.mgrBMPリスト管理者.n現在選択中のItem番号0to1294 < 0 )
4840                                         return;         // 選択されていない
4841
4842                                 this.mgrBMPリスト管理者.t画像プロパティを開いて編集する( this.mgrBMPリスト管理者.n現在選択中のItem番号0to1294 + 1, this.str作業フォルダ名 );
4843                         }
4844                         //-----------------
4845                         #endregion
4846                 }
4847                 private void listViewBMPリスト_MouseEnter( object sender, EventArgs e )
4848                 {
4849                         #region [ BMPリストにフォーカスを移動する。]
4850                         //-----------------
4851                         if( this.appアプリ設定.AutoFocus )
4852                                 this.mgrBMPリスト管理者.tBMPリストにフォーカスを当てる();
4853                         //-----------------
4854                         #endregion
4855                 }
4856                 private void listViewBMPリスト_RetrieveVirtualItem( object sender, RetrieveVirtualItemEventArgs e )
4857                 {
4858                         e.Item = this.mgrBMPリスト管理者.tCBMPとListViewItemを生成して返す( e.ItemIndex + 1 );
4859                 }
4860                 private void listViewBMPリスト_SelectedIndexChanged( object sender, EventArgs e )
4861                 {
4862                         #region [ WAV, BMP, AVI のカーソルを、選択された行に全部合わせる。]
4863                         //-----------------
4864                         if( this.listViewBMPリスト.SelectedIndices.Count > 0 )
4865                                 this.tWAV_BMP_AVIリストのカーソルを全部同じ行に合わせる( this.listViewBMPリスト.SelectedIndices[ 0 ] );
4866                         //-----------------
4867                         #endregion
4868                 }
4869
4870                 private void toolStripButtonBMPリスト上移動_Click( object sender, EventArgs e )
4871                 {
4872                         #region [ 上の行とBMPを交換する。]
4873                         //-----------------
4874                         if( this.listViewBMPリスト.SelectedIndices.Count <= 0 )
4875                                 return; // 選択されていない
4876
4877                         int n選択されたItem番号0to1294 = this.listViewBMPリスト.SelectedIndices[ 0 ];
4878
4879                         if( n選択されたItem番号0to1294 != 0 )
4880                                 this.mgrBMPリスト管理者.tItemを交換する( n選択されたItem番号0to1294, n選択されたItem番号0to1294 - 1 );
4881                         //-----------------
4882                         #endregion
4883                 }
4884                 private void toolStripButtonBMPリスト下移動_Click( object sender, EventArgs e )
4885                 {
4886                         #region [ 下の行とBMPを交換する。]
4887                         //-----------------
4888                         if( this.listViewBMPリスト.SelectedIndices.Count <= 0 )
4889                                 return; // 選択されていない
4890
4891                         int n選択されたItem番号0to1294 = this.listViewBMPリスト.SelectedIndices[ 0 ];
4892
4893                         if( n選択されたItem番号0to1294 >= 1294 )
4894                                 return; // 最下行なので無視
4895
4896                         this.mgrBMPリスト管理者.tItemを交換する( n選択されたItem番号0to1294, n選択されたItem番号0to1294 + 1 );
4897                         //-----------------
4898                         #endregion
4899                 }
4900                 //-----------------
4901                 #endregion
4902                 #region [ GUIイベント:AVIリスト関連 ]
4903                 //-----------------
4904                 private void listViewAVIリスト_Click( object sender, EventArgs e )
4905                 {
4906                         // 何もしない
4907                 }
4908                 private void listViewAVIリスト_DoubleClick( object sender, EventArgs e )
4909                 {
4910                         #region [ 動画プロパティを開いて編集する。]
4911                         //-----------------
4912                         if( this.mgrAVIリスト管理者.n現在選択中のItem番号0to1294 < 0 )
4913                                 return; // 選択されていない
4914
4915                         this.mgrAVIリスト管理者.t動画プロパティを開いて編集する( this.mgrAVIリスト管理者.n現在選択中のItem番号0to1294 + 1, this.str作業フォルダ名 );
4916                         //-----------------
4917                         #endregion
4918                 }
4919                 private void listViewAVIリスト_ItemDrag( object sender, ItemDragEventArgs e )
4920                 {
4921                         #region [ CAVIデータをDragDrop用データに格納してDoDragDrop()を呼び出す。]
4922                         //-----------------
4923                         var item = (ListViewItem) e.Item;
4924
4925                         var data = new Cチップパレット向けDragDropデータ() {
4926                                 n種類 = 2,
4927                                 strラベル名 = item.SubItems[ 0 ].Text,
4928                                 n番号1to1295 = C変換.n36進数2桁の文字列を数値に変換して返す( item.SubItems[ 1 ].Text ),
4929                                 strファイル名 = item.SubItems[ 2 ].Text,
4930                                 col文字色 = item.ForeColor,
4931                                 col背景色 = item.BackColor,
4932                         };
4933
4934                         this.DoDragDrop( data, DragDropEffects.Copy );
4935                         //-----------------
4936                         #endregion
4937                 }
4938                 private void listViewAVIリスト_KeyPress( object sender, KeyPressEventArgs e )
4939                 {
4940                         #region [ ENTER が押下されたら、動画プロパティを開いて編集する。]
4941                         //-----------------
4942                         if( e.KeyChar == (char) Keys.Return ) 
4943                         {
4944                                 if( this.mgrAVIリスト管理者.n現在選択中のItem番号0to1294 < 0 )
4945                                         return;         // 選択されてない
4946
4947                                 this.mgrAVIリスト管理者.t動画プロパティを開いて編集する( this.mgrAVIリスト管理者.n現在選択中のItem番号0to1294 + 1, this.str作業フォルダ名 );
4948                         }
4949                         //-----------------
4950                         #endregion
4951                 }
4952                 private void listViewAVIリスト_MouseEnter( object sender, EventArgs e )
4953                 {
4954                         #region [ AVIリストにフォーカスを移動する。]
4955                         //-----------------
4956                         if( this.appアプリ設定.AutoFocus )
4957                                 this.mgrAVIリスト管理者.tAVIリストにフォーカスを当てる();
4958                         //-----------------
4959                         #endregion
4960                 }
4961                 private void listViewAVIリスト_RetrieveVirtualItem( object sender, RetrieveVirtualItemEventArgs e )
4962                 {
4963                         e.Item = this.mgrAVIリスト管理者.tCAVIとListViewItemを生成して返す( e.ItemIndex + 1 );
4964                 }
4965                 private void listViewAVIリスト_SelectedIndexChanged( object sender, EventArgs e )
4966                 {
4967                         #region [ WAV, BMP, AVI のカーソルを、選択された行に全部合わせる。]
4968                         //-----------------
4969                         if( this.listViewAVIリスト.SelectedIndices.Count > 0 )
4970                                 this.tWAV_BMP_AVIリストのカーソルを全部同じ行に合わせる( this.listViewAVIリスト.SelectedIndices[ 0 ] );
4971                         //-----------------
4972                         #endregion
4973                 }
4974
4975                 private void toolStripButtonAVIリスト上移動_Click( object sender, EventArgs e )
4976                 {
4977                         #region [ 上の行とAVIを交換する。]
4978                         //-----------------
4979                         if( this.listViewAVIリスト.SelectedIndices.Count <= 0 )
4980                                 return; // 選択されていない
4981
4982                         int n選択されたItem番号0to1294 = this.listViewAVIリスト.SelectedIndices[ 0 ];
4983
4984                         if( n選択されたItem番号0to1294 == 0 )
4985                                 return; // 最上行なので無視
4986
4987                         this.mgrAVIリスト管理者.tItemを交換する( n選択されたItem番号0to1294, n選択されたItem番号0to1294 - 1 );
4988                         //-----------------
4989                         #endregion
4990                 }
4991                 private void toolStripButtonAVIリスト下移動_Click( object sender, EventArgs e )
4992                 {
4993                         #region [ 下の行とAVIを交換する。]
4994                         //-----------------
4995                         if( this.listViewAVIリスト.SelectedIndices.Count <= 0 )
4996                                 return; // 選択されていない
4997
4998                         int n選択されたItem番号0to1294 = this.listViewAVIリスト.SelectedIndices[ 0 ];
4999
5000                         if( n選択されたItem番号0to1294 >= 1294 )
5001                                 return; // 最下行なので無視
5002
5003                         this.mgrAVIリスト管理者.tItemを交換する( n選択されたItem番号0to1294, n選択されたItem番号0to1294 + 1 );
5004                         //-----------------
5005                         #endregion
5006                 }
5007                 //-----------------
5008                 #endregion
5009                 #region [ GUIイベント:自由入力関連 ]
5010                 //-----------------
5011                 private string textBox自由入力欄_以前の値 = "";
5012                 private void textBox自由入力欄_TextChanged( object sender, EventArgs e )
5013                 {
5014                         // Undo/Redo リストを修正。
5015
5016                         #region [ Undo/Redo リストを修正する。]
5017                         //-----------------
5018                         if( !CUndoRedo管理.bUndoRedoした直後 )
5019                         {
5020                                 CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
5021
5022                                 if( ( oセル仮想 != null ) && oセル仮想.b所有権がある( this.textBox自由入力欄 ) )
5023                                 {
5024                                         // 既存のセルの値を更新。
5025
5026                                         ( (CUndoRedoセル<string>) oセル仮想 ).変更後の値 = this.textBox自由入力欄.Text;
5027                                 }
5028                                 else
5029                                 {
5030                                         // 新しいセルを追加。
5031
5032                                         this.mgrUndoRedo管理者.tノードを追加する(
5033                                                 new CUndoRedoセル<string>(
5034                                                         this.textBox自由入力欄, 
5035                                                         new DGUndoを実行する<string>( this.textBox自由入力欄_Undo ),
5036                                                         new DGRedoを実行する<string>( this.textBox自由入力欄_Redo ),
5037                                                         this.textBox自由入力欄_以前の値, this.textBox自由入力欄.Text ) );
5038
5039
5040                                         // Undoボタンを有効にする。
5041
5042                                         this.tUndoRedo用GUIの有効無効を設定する();
5043                                 }
5044                         }
5045                         //-----------------
5046                         #endregion
5047
5048
5049                         // Undo 用に値を保管しておく。
5050
5051                         this.textBox自由入力欄_以前の値 = this.textBox自由入力欄.Text;
5052
5053
5054                         // 完了。
5055
5056                         CUndoRedo管理.bUndoRedoした直後 = false;
5057                         this.b未保存 = true;
5058                 }
5059                 private void textBox自由入力欄_Leave( object sender, EventArgs e )
5060                 {
5061                         CUndoRedoセル仮想 oセル仮想 = this.mgrUndoRedo管理者.tUndoするノードを取得して返す_見るだけ();
5062
5063                         if( oセル仮想 != null )
5064                                 oセル仮想.t所有権の放棄( this.textBox自由入力欄 );
5065                 }
5066                 private void textBox自由入力欄_Undo( string str変更前, string str変更後 )
5067                 {
5068                         // 変更前の値に戻す。
5069
5070                         this.tタブを選択する( Eタブ種別.自由入力 );
5071
5072                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
5073                         this.textBox自由入力欄.Text = str変更前;
5074
5075                         this.textBox自由入力欄.Focus();
5076                 }
5077                 private void textBox自由入力欄_Redo( string str変更前, string str変更後 )
5078                 {
5079                         // 変更後の値に戻す。
5080
5081                         this.tタブを選択する( Eタブ種別.自由入力 );
5082
5083                         this.t次のプロパティ変更処理がUndoRedoリストに載らないようにする();
5084                         this.textBox自由入力欄.Text = str変更後;
5085
5086                         this.textBox自由入力欄.Focus();
5087                 }
5088                 //-----------------
5089                 #endregion
5090         
5091                 #region [ GUIイベント:メニューバー [ファイル] ]
5092                 //-----------------
5093                 private void toolStripMenuItem新規_Click( object sender, EventArgs e )
5094                 {
5095                         this.tシナリオ_新規作成();
5096                 }
5097                 private void toolStripMenuItem開く_Click( object sender, EventArgs e )
5098                 {
5099                         this.tシナリオ_開く();
5100                 }
5101                 private void toolStripMenuItem上書き保存_Click( object sender, EventArgs e )
5102                 {
5103                         this.tシナリオ_上書き保存();
5104                 }
5105                 private void toolStripMenuItem名前を付けて保存_Click( object sender, EventArgs e )
5106                 {
5107                         this.tシナリオ_名前をつけて保存();
5108                 }
5109                 private void exportMIDIFileToolStripMenuItem_Click_1(object sender, EventArgs e)
5110                 {
5111                         this.mgrMIDIExportManager.tOpenMIDIExportManagerFromMenu();
5112                         this.mgr譜面管理者.tRefreshDisplayLanes();   // レーンの表示/非表示切り替えに備えて追加
5113                 }
5114
5115                 private void toolStripMenuItem終了_Click( object sender, EventArgs e )
5116                 {
5117                         this.tシナリオ_終了();
5118                 }
5119                 private void toolStripMenuItem最近使ったファイル_Click( object sender, EventArgs e )
5120                 {
5121                         // ※このイベントハンドラに対応する「toolStripMenuItem最近使ったファイル」というアイテムはデザイナにはないので注意。
5122                         //   this.t最近使ったファイルをFileメニューへ追加する() の中で、手動で作って追加したアイテムに対するハンドラである。
5123
5124                         if( this.t未保存なら保存する() == DialogResult.Cancel )
5125                                 return;
5126
5127                         this.t演奏ファイルを開いて読み込む( ( (ToolStripMenuItem) sender ).ToolTipText );
5128                 }
5129                 //-----------------
5130                 #endregion
5131                 #region [ GUIイベント:メニューバー [編集] ]
5132                 //-----------------
5133                 private void toolStripMenuItemアンドゥ_Click( object sender, EventArgs e )
5134                 {
5135                         this.tシナリオ_Undoする();
5136                 }
5137                 private void toolStripMenuItemリドゥ_Click( object sender, EventArgs e )
5138                 {
5139                         this.tシナリオ_Redoする();
5140                 }
5141                 private void toolStripMenuItem切り取り_Click( object sender, EventArgs e )
5142                 {
5143                         this.tシナリオ_切り取り();
5144                 }
5145                 private void toolStripMenuItemコピー_Click( object sender, EventArgs e )
5146                 {
5147                         this.tシナリオ_コピー();
5148                 }
5149                 private void toolStripMenuItem貼り付け_Click( object sender, EventArgs e )
5150                 {
5151                         // マウスが譜面上にあるならそこから貼り付ける。
5152
5153                         Point ptマウス位置 = this.pt現在のマウス位置を譜面の可視領域相対の座標dotで返す();
5154                         Size sz譜面の可視サイズ = this.sz譜面の可視領域の大きさdotを返す();
5155
5156         
5157                         if( ( ( ptマウス位置.X < 0 ) || ( ptマウス位置.Y < 0 ) ) || ( ( ptマウス位置.X > sz譜面の可視サイズ.Width ) || ( ptマウス位置.Y > sz譜面の可視サイズ.Height ) ) )
5158                         {
5159                                 // マウスが譜面上になかった → 表示領域下辺から貼り付ける
5160
5161                                 this.tシナリオ_貼り付け( this.mgr譜面管理者.n現在の譜面表示下辺の譜面先頭からの位置grid );
5162                         }
5163                         else
5164                         {
5165                                 // マウスが譜面上にあった
5166
5167                                 this.tシナリオ_貼り付け( this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( ptマウス位置.Y ) );
5168                         }
5169                 }
5170                 private void toolStripMenuItem削除_Click( object sender, EventArgs e )
5171                 {
5172                         this.tシナリオ_削除();
5173                 }
5174                 private void toolStripMenuItemすべて選択_Click( object sender, EventArgs e )
5175                 {
5176                         // 編集モードなら強制的に選択モードにする。
5177
5178                         if( this.b編集モードである )
5179                                 this.t選択モードにする();
5180
5181
5182                         // 全チップを選択する。
5183
5184                         this.mgr選択モード管理者.t全チップを選択する();
5185                 }
5186                 private void toolStripMenuItem選択モード_Click( object sender, EventArgs e )
5187                 {
5188                         this.t選択モードにする();
5189                 }
5190                 private void toolStripMenuItem編集モード_Click( object sender, EventArgs e )
5191                 {
5192                         this.t編集モードにする();
5193                 }
5194                 private void toolStripMenuItemモード切替_Click( object sender, EventArgs e )
5195                 {
5196                         if( this.b選択モードである )
5197                         {
5198                                 this.t編集モードにする();
5199                         }
5200                         else
5201                         {
5202                                 this.t選択モードにする();
5203                         }
5204                 }
5205                 private void toolStripMenuItem検索_Click( object sender, EventArgs e )
5206                 {
5207                         this.tシナリオ_検索();
5208                 }
5209                 private void toolStripMenuItem置換_Click( object sender, EventArgs e )
5210                 {
5211                         this.tシナリオ_置換();
5212                 }
5213                 //-----------------
5214                 #endregion
5215                 #region [ GUIイベント:メニューバー [表示] ]
5216                 //-----------------
5217                 private void toolStripMenuItemチップパレット_Click( object sender, EventArgs e )
5218                 {
5219                         if( this.toolStripMenuItemチップパレット.CheckState == CheckState.Checked )
5220                         {
5221                                 this.dlgチップパレット.t表示する();
5222                         }
5223                         else
5224                         {
5225                                 this.dlgチップパレット.t隠す();
5226                         }
5227                 }
5228                 private void toolStripMenuItemガイド間隔4分_Click( object sender, EventArgs e )
5229                 {
5230                         this.tガイド間隔を変更する( 4 );
5231                 }
5232                 private void toolStripMenuItemガイド間隔8分_Click( object sender, EventArgs e )
5233                 {
5234                         this.tガイド間隔を変更する( 8 );
5235                 }
5236                 private void toolStripMenuItemガイド間隔12分_Click( object sender, EventArgs e )
5237                 {
5238                         this.tガイド間隔を変更する( 12 );
5239                 }
5240                 private void toolStripMenuItemガイド間隔16分_Click( object sender, EventArgs e )
5241                 {
5242                         this.tガイド間隔を変更する( 0x10 );
5243                 }
5244                 private void toolStripMenuItemガイド間隔24分_Click( object sender, EventArgs e )
5245                 {
5246                         this.tガイド間隔を変更する( 0x18 );
5247                 }
5248                 private void toolStripMenuItemガイド間隔32分_Click( object sender, EventArgs e )
5249                 {
5250                         this.tガイド間隔を変更する( 0x20 );
5251                 }
5252                 private void toolStripMenuItemガイド間隔48分_Click( object sender, EventArgs e )
5253                 {
5254                         this.tガイド間隔を変更する( 0x30 );
5255                 }
5256                 private void toolStripMenuItemガイド間隔64分_Click( object sender, EventArgs e )
5257                 {
5258                         this.tガイド間隔を変更する( 0x40 );
5259                 }
5260                 private void toolStripMenuItemガイド間隔フリー_Click( object sender, EventArgs e )
5261                 {
5262                         this.tガイド間隔を変更する( 0 );
5263                 }
5264                 private void toolStripMenuItemガイド間隔拡大_Click( object sender, EventArgs e )
5265                 {
5266                         switch( this.n現在のガイド間隔4to64or0 )
5267                         {
5268                                 case 4: break;
5269                                 case 8: this.tガイド間隔を変更する( 4 ); break;
5270                                 case 12: this.tガイド間隔を変更する( 8 ); break;
5271                                 case 16: this.tガイド間隔を変更する( 12 ); break;
5272                                 case 24: this.tガイド間隔を変更する( 16 ); break;
5273                                 case 32: this.tガイド間隔を変更する( 24 ); break;
5274                                 case 48: this.tガイド間隔を変更する( 32 ); break;
5275                                 case 64: this.tガイド間隔を変更する( 48 ); break;
5276                                 case 0: this.tガイド間隔を変更する( 64 ); break;
5277                         }
5278                 }
5279                 private void toolStripMenuItemガイド間隔縮小_Click( object sender, EventArgs e )
5280                 {
5281                         switch( this.n現在のガイド間隔4to64or0 )
5282                         {
5283                                 case 4: this.tガイド間隔を変更する( 8 ); break;
5284                                 case 8: this.tガイド間隔を変更する( 12 ); break;
5285                                 case 12: this.tガイド間隔を変更する( 16 ); break;
5286                                 case 16: this.tガイド間隔を変更する( 24 ); break;
5287                                 case 24: this.tガイド間隔を変更する( 32 ); break;
5288                                 case 32: this.tガイド間隔を変更する( 48 ); break;
5289                                 case 48: this.tガイド間隔を変更する( 64 ); break;
5290                                 case 64: this.tガイド間隔を変更する( 0 ); break;
5291                                 case 0: break;
5292                         }
5293                 }
5294                 //-----------------
5295                 #endregion
5296                 #region [ GUIイベント:メニューバー [再生] ]
5297                 //-----------------
5298                 private void toolStripMenuItem先頭から再生_Click( object sender, EventArgs e )
5299                 {
5300                         this.tシナリオ_Viewerで最初から再生する();
5301                 }
5302                 private void toolStripMenuItem現在位置から再生_Click( object sender, EventArgs e )
5303                 {
5304                         this.tシナリオ_Viewerで現在位置から再生する();
5305                 }
5306                 private void toolStripMenuItem現在位置からBGMのみ再生_Click( object sender, EventArgs e )
5307                 {
5308                         this.tシナリオ_Viewerで現在位置からBGMのみ再生する();
5309                 }
5310                 private void toolStripMenuItem再生停止_Click( object sender, EventArgs e )
5311                 {
5312                         this.tシナリオ_Viewerを再生停止する();
5313                 }
5314                 //-----------------
5315                 #endregion
5316                 #region [ GUIイベント:メニューバー [ツール] ]
5317                 //-----------------
5318                 private void toolStripMenuItemオプション_Click( object sender, EventArgs e )
5319                 {
5320                         this.mgrオプション管理者.tオプションダイアログを開いて編集し結果をアプリ設定に格納する();
5321                         this.mgr譜面管理者.tRefreshDisplayLanes(); // レーンの表示/非表示切り替えに備えて追加
5322                 }
5323                 private void toolStripMenuItemMIDIImport_Click( object sender, EventArgs e)
5324         {
5325             this.mgrMIDIインポート管理者.tMIDIインポート管理をインポートメニューから開く();
5326             this.mgr譜面管理者.tRefreshDisplayLanes();     // レーンの表示/非表示切り替えに備えて追加
5327         }
5328                 private void exportMIDIFileToolStripMenuItem_Click(object sender, EventArgs e)
5329                 {
5330                         this.mgrMIDIExportManager.tOpenMIDIExportManagerFromMenu();
5331                         this.mgr譜面管理者.tRefreshDisplayLanes();   // レーンの表示/非表示切り替えに備えて追加
5332
5333                 }
5334                 //-----------------
5335                 #endregion
5336                 #region [ GUIイベント:メニューバー [ヘルプ] ]
5337                 //-----------------
5338                 private void toolStripMenuItemDTXCreaterマニュアル_Click( object sender, EventArgs e )
5339                 {
5340                         try
5341                         {
5342                                 // マニュアルサイトをブラウザで開く。
5343                                 string strURL = (CultureInfo.CurrentUICulture.Name == "ja-JP")?
5344                                         "https://osdn.net/projects/dtxmania/wiki/faq_index#h2-DTX.E3.83.87.E3.83.BC.E3.82.BF.E5.88.B6.E4.BD.9C.E8.80.85.E5.90.91.E3.81.91.E3.81.AE.E3.82.88.E3.81.8F.E3.81.82.E3.82.8B.E8.B3.AA.E5.95.8F"
5345                                 :       "https://osdn.net/projects/dtxmania/wiki/faq_index_e#h2-For.20DTX.20data.20Manipulators";
5346                                 Process.Start(strURL);
5347                         }
5348                         catch
5349                         {
5350                                 //this.toolStripMenuItemDTXCreaterマニュアル.Enabled = false;
5351                         }
5352                 }
5353                 private void toolStripMenuItemバージョン_Click( object sender, EventArgs e )
5354                 {
5355                         this.dlgチップパレット.t一時的に隠蔽する();
5356
5357                         Cバージョン情報 cバージョン情報 = new Cバージョン情報();
5358                         cバージョン情報.ShowDialog();
5359                         cバージョン情報.Dispose();
5360                         
5361                         this.dlgチップパレット.t一時的な隠蔽を解除する();
5362                 }
5363                 //-----------------
5364                 #endregion
5365
5366                 #region [ GUIイベント:ツールバー ]
5367                 //-----------------
5368                 private void toolStripButton新規作成_Click( object sender, EventArgs e )
5369                 {
5370                         this.tシナリオ_新規作成();
5371                 }
5372                 private void toolStripButton開く_Click( object sender, EventArgs e )
5373                 {
5374                         this.tシナリオ_開く();
5375                 }
5376                 private void toolStripButton上書き保存_Click( object sender, EventArgs e )
5377                 {
5378                         this.tシナリオ_上書き保存();
5379                 }
5380                 private void toolStripButton切り取り_Click( object sender, EventArgs e )
5381                 {
5382                         this.tシナリオ_切り取り();
5383                 }
5384                 private void toolStripButtonコピー_Click( object sender, EventArgs e )
5385                 {
5386                         this.tシナリオ_コピー();
5387                 }
5388                 private void toolStripButton貼り付け_Click( object sender, EventArgs e )
5389                 {
5390                         // マウスが譜面上にあるならそこから貼り付ける。
5391
5392                         Point ptマウスの位置 = this.pt現在のマウス位置を譜面の可視領域相対の座標dotで返す();
5393                         Size sz譜面の可視サイズ = this.sz譜面の可視領域の大きさdotを返す();
5394
5395
5396                         if( ( ( ptマウスの位置.X < 0 ) || ( ptマウスの位置.Y < 0 ) ) || ( ( ptマウスの位置.X > sz譜面の可視サイズ.Width ) || ( ptマウスの位置.Y > sz譜面の可視サイズ.Height ) ) )
5397                         {
5398                                 // マウスが譜面上になかった → 表示領域下辺から貼り付ける
5399
5400                                 this.tシナリオ_貼り付け( this.mgr譜面管理者.n現在の譜面表示下辺の譜面先頭からの位置grid );
5401                         }
5402                         else
5403                         {
5404                                 // マウスが譜面上にあった
5405
5406                                 this.tシナリオ_貼り付け( this.mgr譜面管理者.nY座標dotが位置するgridを返す_ガイド幅単位( ptマウスの位置.Y ) );
5407                         }
5408                 }
5409                 private void toolStripButton削除_Click( object sender, EventArgs e )
5410                 {
5411                         this.tシナリオ_削除();
5412                 }
5413                 private void toolStripButtonアンドゥ_Click( object sender, EventArgs e )
5414                 {
5415                         this.tシナリオ_Undoする();
5416                 }
5417                 private void toolStripButtonリドゥ_Click( object sender, EventArgs e )
5418                 {
5419                         this.tシナリオ_Redoする();
5420                 }
5421                 private void toolStripButtonチップパレット_Click( object sender, EventArgs e )
5422                 {
5423                         if( this.toolStripButtonチップパレット.CheckState == CheckState.Checked )
5424                         {
5425                                 this.dlgチップパレット.t表示する();
5426                         }
5427                         else
5428                         {
5429                                 this.dlgチップパレット.t隠す();
5430                         }
5431                 }
5432                 private void toolStripComboBox譜面拡大率_SelectedIndexChanged( object sender, EventArgs e )
5433                 {
5434                         C小節.n基準の高さdot = CWholeNoteDivision.n分解能_表示用 * ( this.toolStripComboBox譜面拡大率.SelectedIndex + 1 );
5435                         
5436                         this.pictureBox譜面パネル.Refresh();
5437                 }
5438                 private void toolStripComboBoxガイド間隔_SelectedIndexChanged( object sender, EventArgs e )
5439                 {
5440                         switch( this.toolStripComboBoxガイド間隔.SelectedIndex )
5441                         {
5442                                 case 0:
5443                                         this.tガイド間隔を変更する( 4 );
5444                                         return;
5445
5446                                 case 1:
5447                                         this.tガイド間隔を変更する( 8 );
5448                                         return;
5449
5450                                 case 2:
5451                                         this.tガイド間隔を変更する( 12 );
5452                                         return;
5453
5454                                 case 3:
5455                                         this.tガイド間隔を変更する( 16 );
5456                                         return;
5457
5458                                 case 4:
5459                                         this.tガイド間隔を変更する( 24 );
5460                                         return;
5461
5462                                 case 5:
5463                                         this.tガイド間隔を変更する( 32 );
5464                                         return;
5465
5466                                 case 6:
5467                                         this.tガイド間隔を変更する( 48 );
5468                                         return;
5469
5470                                 case 7:
5471                                         this.tガイド間隔を変更する( 64 );
5472                                         return;
5473
5474                                 case 8:
5475                                         this.tガイド間隔を変更する( 0 );
5476                                         return;
5477                         }
5478                 }
5479                 private void toolStripButton選択モード_Click( object sender, EventArgs e )
5480                 {
5481                         this.t選択モードにする();
5482                 }
5483                 private void toolStripButton編集モード_Click( object sender, EventArgs e )
5484                 {
5485                         this.t編集モードにする();
5486                 }
5487                 private void toolStripButton先頭から再生_Click( object sender, EventArgs e )
5488                 {
5489                         this.tシナリオ_Viewerで最初から再生する();
5490                 }
5491                 private void toolStripButton現在位置から再生_Click( object sender, EventArgs e )
5492                 {
5493                         this.tシナリオ_Viewerで現在位置から再生する();
5494                 }
5495                 private void toolStripButton現在位置からBGMのみ再生_Click( object sender, EventArgs e )
5496                 {
5497                         this.tシナリオ_Viewerで現在位置からBGMのみ再生する();
5498                 }
5499                 private void toolStripButton再生停止_Click( object sender, EventArgs e )
5500                 {
5501                         this.tシナリオ_Viewerを再生停止する();
5502                 }
5503
5504                 //private void ToolStripMenuItemBeatChipsGeneration_Click( object sender, EventArgs e )                 // Beat Detections
5505                 //{
5506                 //    GenarateBeatChip_Main();
5507                 //}
5508
5509
5510                 // 2度続けて実行するとチップが増えておかしくなる?要調査。
5511                 private void GenarateBeatChip_Main()
5512                 {
5513                         string filename = "";
5514
5515                         #region [ BGM, BPM, BEATレーンのレーン番号を取得 ]
5516                         int laneBGM = this.mgr譜面管理者.nレーン名に対応するレーン番号を返す( "BGM" );
5517                         int laneBPM = this.mgr譜面管理者.nレーン名に対応するレーン番号を返す( "BPM" );
5518                         int laneBEAT = this.mgr譜面管理者.nレーン名に対応するレーン番号を返す( "BEAT" );
5519                         #endregion
5520
5521                         #region [ BGMレーンにあるチップを抽出して、beat検出する対象のサウンドファイルを決める ]
5522                         // とりあえずBGMチップは1個しかない前提で進める。追々、複数のBGMチップでも動作するようにはしたい。
5523                         #region [ BGMチップ抽出 ]
5524                         int nBGMチップの小節番号 = -1;
5525                         int nBGMチップのindex = -1;
5526                         foreach ( KeyValuePair<int, C小節> pair in this.mgr譜面管理者.dic小節 )
5527                         {
5528                                 C小節 c小節 = pair.Value;
5529                                 nBGMチップのindex = c小節.listチップ.FindIndex(
5530                                         delegate( Cチップ cチップ )
5531                                         {
5532                                                 return ( cチップ.nレーン番号0to == laneBGM );
5533                                         }
5534                                 );
5535                                 if ( nBGMチップのindex >= 0 )
5536                                 {
5537                                         nBGMチップの小節番号 = c小節.n小節番号0to3599;
5538                                         filename = this.mgrWAVリスト管理者.tファイル名を絶対パスで返す( c小節.listチップ[ nBGMチップのindex ].n値_整数1to1295);
5539                                         Debug.WriteLine( filename );
5540                                         break;  // とりあえず1個見つけたらbreakしちゃう
5541                                 }
5542                                 //for ( int i = 0; i < c小節.listチップ.Count; i++ )
5543                                 //{
5544                                 //Cチップ cチップ = c小節.listチップ[ i ];
5545                                 //if ( cチップ.nレーン番号0to == lane )
5546                                 //{
5547                                 //    nBGMチップのindex = i;
5548                                 //    filename = this.mgrWAVリスト管理者.tファイル名を絶対パスで返す( cチップ.n値・整数1to1295 );
5549                                 //    Debug.WriteLine( filename );
5550                                 //}
5551                                 //}
5552                         }
5553                         if ( filename == "" )
5554                         {
5555                                 MessageBox.Show( "BGMチップが配置されていません。BGMチップを1つ配置してください。", "BGMチップ検出エラー", MessageBoxButtons.OK, MessageBoxIcon.Error );
5556                                 return;
5557                         }
5558                         #endregion
5559                         #endregion
5560
5561                         #region [ マウスカーソルを待機中に変更 (アプリウインドウ外で右クリックメニュー選択していると、効果がない・・・) ]
5562                         this.Cursor = Cursors.WaitCursor;
5563                         #endregion
5564
5565                         #region [ BPM,BEATレーンの情報を消去 ]
5566                         this.mgr選択モード管理者.tレーン上の全チップを選択する( laneBPM );
5567                         this.tシナリオ_削除();
5568                         this.mgr選択モード管理者.tレーン上の全チップを選択する( laneBEAT );
5569                         this.tシナリオ_削除();
5570                         #endregion
5571
5572
5573                         #region [ BASSFXのBeat detectionを実行する ]
5574                         FDK.CBeatDetect cbd = new CBeatDetect( filename );
5575
5576                         float tempo = cbd.GetTempo();
5577 // Debug.WriteLine( "BPM=" + tempo );
5578
5579                         List<FDK.CBeatDetect.stBeatPos> listBeatPositions = cbd.GetBeatPositions();
5580 // Debug.WriteLine( "Count: " + listBeatPositions.Count );
5581                         #endregion
5582
5583                         // 四分音符以下、8分音符以下などと選べるようにしたい。
5584                         #region [ 四分音符以下の間隔で検出されたbeatを、端折る。端折らないと、検出beat数が多過ぎて、人が扱えなくなる。ただ、端折り方はもう少し熟慮が必要。]
5585                         float last = 0;
5586                         float minBeatDelta = 60.0f / tempo;             // 4分音符の長さ
5587                         int count = 10;
5588
5589                         // 最初の10個くらいは、端折らない。まず拍の頭をとるのに必要な情報を落とすわけにはいかないので。
5590                         // 10個目以降は、四分音符未満の長さのbeatを、端折る。(裏BEATレーンに回す)
5591                         //if ( listBeatPositions.Count > 10 )
5592                         //{
5593                         //    for ( int i = count; i < listBeatPositions.Count; i++ )
5594                         //    {
5595                         //        if ( listBeatPositions[ i ].fBeatTime - last < minBeatDelta )
5596                         //        {
5597                         //            FDK.CBeatDetect.stBeatPos sbp = new CBeatDetect.stBeatPos(
5598                         //                listBeatPositions[ i ].fBeatTime,
5599                         //                0,
5600                         //                0,
5601                         //                0,
5602                         //                ( listBeatPositions[ i ].fBeatTime - last < minBeatDelta ),
5603                         //                true
5604                         //            );
5605
5606                         //            listBeatPositions[ i ] = sbp;
5607                         //        }
5608                         //        last = listBeatPositions[ i ].fBeatTime;
5609                         //    }
5610                         //}
5611                         #endregion
5612
5613                         #region [ ただのデバッグ表示 ]
5614                         //last = 0;
5615                         //for ( int i = 0; i < listBeatPositions.Count; i++ )
5616                         //{
5617                         //    //Debug.WriteLine( listBeatPositionsLight[ i ] - last );
5618                         //    Debug.WriteLine( listBeatPositions[ i ].fBeatTime );
5619                         //    last = listBeatPositions[ i ].fBeatTime;
5620                         //}
5621                         //Debug.WriteLine( "========================" );
5622                         #endregion
5623
5624                         #region [ 未使用: 端折った区間内で、それぞれBPMを再取得してみる → これは意味なし。1つのbeatしか得られないため、正しいBPMを取得できない。]
5625                         //List<float> listTempo_interval = new List<float>();
5626                         //last = 0;
5627                         //for ( int i = 0; i < listBeatPositionsLight.Count - 1; i++ )
5628                         //{
5629                         //    listTempo_interval.Add( cbd.GetTempo( last, listBeatPositionsLight[ i ] ) );
5630                         //    last = listBeatPositionsLight[ i ];
5631                         //    Debug.WriteLine( listTempo_interval[ i ] );
5632                         //}
5633                         #endregion
5634
5635
5636                         int n1拍目のBeatPositionIndex = 0;
5637
5638                         #region [ 1小節目の頭に1発目の拍が来るよう、BGMチップをずらす。ただしこれだけだと、最大1grid分の時間誤差が発生する。(BPM=125時に最大10msの誤差)]
5639                         int nBGM位置grid = 0;
5640                         if ( nBGMチップの小節番号 >= 0 && nBGMチップのindex >= 0 )
5641                         {
5642                                 //      float f小節長倍率 = 1.0f;
5643                                 C小節 c小節_0小節目 = this.mgr譜面管理者.dic小節[ nBGMチップの小節番号 ];
5644                                 Cチップ cチップBGM = c小節_0小節目.listチップ[ nBGMチップのindex ];
5645                                 nBGM位置grid = (int) ( CWholeNoteDivision.n分解能 * c小節_0小節目.f小節長倍率 * listBeatPositions[ n1拍目のBeatPositionIndex ].fBeatTime / ( ( 60 * 4 ) / tempo ) + 0.5 );
5646                                 // ここでnBGM位置Gridが192(x小節長)を超えることがある
5647                                 // → 192(x小節長)をひいて、次の小節に回す。(小節ごとに小節長倍率が変化する可能性があることに注意)
5648                                 // → スマン、この実装ではまだ、DTXデータの最初はしばらく小節倍率が一定である前提になっちゃってる・・
5649                                 cチップBGM.n位置grid = (int) ( CWholeNoteDivision.n分解能 * c小節_0小節目.f小節長倍率 + 0.5f ) - ( nBGM位置grid % CWholeNoteDivision.n分解能 );                  // "192-" が必要なことに注意
5650                                 c小節_0小節目.listチップ[ nBGMチップのindex ] = cチップBGM;
5651                                 this.mgr譜面管理者.dic小節[ nBGMチップの小節番号 ] = c小節_0小節目;
5652                         }
5653                         #endregion
5654
5655                         #region [ 0小節目のBPMを設定し、1つ目の拍が1小節目の頭に来るようにする。]
5656                         // まず、0小節の頭にBPM設定を追加する。
5657                         this.mgr編集モード管理者.tBPMチップを配置する( 0 * CWholeNoteDivision.n分解能, tempo );                      // 既にBPMチップが配置されている場合の処理は????????????????
5658                         this.numericUpDownBPM.Value = (decimal) ( (int) ( tempo + 0.5 ) );
5659                         numericUpDownBPM_ValueChanged( null, null );
5660                         numericUpDownBPM_Leave( null, null );
5661
5662                         // 更に、先の1グリッド分の誤差をなくすために、BGMチップの位置だけでなく、0小節目のBPMも微調整する。
5663                         float f小節長倍率_ = this.mgr譜面管理者.dic小節[ nBGMチップの小節番号 ].f小節長倍率;                                   // 手抜き。すまん。
5664                         float fBGM再生直後のBPM = ( 60 * 4 ) * nBGM位置grid / ( CWholeNoteDivision.n分解能 * f小節長倍率_ ) / listBeatPositions[ n1拍目のBeatPositionIndex ].fBeatTime;
5665                         this.mgr編集モード管理者.tBPMチップを配置する( CWholeNoteDivision.n分解能 - ( nBGM位置grid % CWholeNoteDivision.n分解能 ), fBGM再生直後のBPM );
5666                         #endregion
5667
5668
5669
5670 // 頭の1個目のBEATチップがちゃんと配置されてないよ!!!!!
5671
5672
5673
5674                         #region [ BEATレーンにチップを配置する ]
5675                         //                      int lastGrid = (int) ( 192 * this.mgr譜面管理者.dic小節[ 0 ].f小節長倍率 ); // 0小節目の倍率
5676                         //int last小節内Grid = 0;
5677                         //int last小節番号 = nBGMチップの小節番号;
5678                         int n最初の拍のある小節番号 = 1 + ( nBGM位置grid / CWholeNoteDivision.n分解能 );
5679                         float lastBeatTime = listBeatPositions[ n1拍目のBeatPositionIndex ].fBeatTime;
5680                         int lastnGrid = -1;
5681
5682                         for ( int index = n1拍目のBeatPositionIndex; index < listBeatPositions.Count; index++ )
5683                         {
5684                                 //Debug.Write( "[" + index + "] " );
5685
5686                                 // 今注目しているBEATチップが、どの小節・拍(grid)に収まるかを計算する
5687                                 //              // 誤差を小さくするため、直前のBEATポイントからの相対位置として計算すること。
5688                                 //              // 絶対位置で計算すると、最初のBPM計算の誤差がそのままBEAT位置に現れる。                         // やり残し★★★★★★
5689                                 //              // ...としたいのだが、まだできてない。全部絶対位置で計算している。
5690                                 FDK.CBeatDetect.stBeatPos sbp = listBeatPositions[ index ];
5691
5692                                 float deltatime = sbp.fBeatTime - lastBeatTime;
5693                                 //Debug.Write( "delta=" + deltatime );
5694                                 int n小節番号 = n最初の拍のある小節番号;
5695                                 float f1小節の時間 = ( 60 / tempo ) * 4;
5696                                 #region [ 0小節目の場合 ]
5697                                 if ( deltatime < 0 )
5698                                 {
5699                                         while ( n小節番号 >= 0 && deltatime < 0 )
5700                                         {
5701                                                 n小節番号--;
5702                                                 deltatime += f1小節の時間 * this.mgr譜面管理者.dic小節[ n小節番号 ].f小節長倍率;
5703                                                 //(int) ( 192 * this.mgr譜面管理者.dic小節[ n小節番号 ].f小節長倍率 );  // 0小節目の倍率
5704                                         }
5705                                         if ( deltatime < 0 )
5706                                         {
5707                                                 Debug.WriteLine( "[" + index + "]: deltatime < 0; error (" + deltatime );
5708                                                 continue;
5709                                         }
5710                                 }
5711                                 #endregion
5712                                 #region [ 1小節目以降の場合 ]
5713                                 else
5714                                 {
5715                                         //Debug.Write( " + " + f1小節の時間 * this.mgr譜面管理者.dic小節[ n小節番号 ].f小節長倍率 * last小節内Grid / 192 + "(" + lastGrid + "|" + last小節内Grid +")=" );
5716                                         //                                      deltatime += f1小節の時間 * this.mgr譜面管理者.dic小節[ n小節番号 ].f小節長倍率 * last小節内Grid / 192;         // 直前のgrid(その小節の頭から)の分
5717                                         //Debug.WriteLine( deltatime );
5718                                         while ( true )
5719                                         {
5720                                                 if ( deltatime < f1小節の時間 * this.mgr譜面管理者.dic小節[ n小節番号 ].f小節長倍率 )
5721                                                 {
5722                                                         break;
5723                                                 }
5724                                                 n小節番号++;
5725
5726                                                 #region [ 小節ノードが不足しているなら、追加する ]
5727                                                 if ( this.mgr譜面管理者.n現在の最大の小節番号を返す() < n小節番号 )
5728                                                 {
5729                                                         for ( int i = n小節番号; i < n小節番号 + 5; i++ )
5730                                                         {
5731                                                                 this.mgr譜面管理者.dic小節.Add( i, new C小節( i ) );
5732                                                                 this.mgrUndoRedo管理者.tノードを追加する( new CUndoRedoセル<int>( null, new DGUndoを実行する<int>( this.mgr譜面管理者.t小節挿入のUndo ), new DGRedoを実行する<int>( this.mgr譜面管理者.t小節挿入のRedo ), i, i ) );
5733                                                         }
5734                                                 }
5735                                                 #endregion
5736
5737                                                 deltatime -= f1小節の時間 * this.mgr譜面管理者.dic小節[ n小節番号 ].f小節長倍率;
5738                                         }
5739                                         if ( deltatime < 0 )
5740                                         {
5741                                                 Debug.WriteLine( "[" + index + "]: deltatime < 0; error (" + deltatime );
5742                                                 continue;
5743                                         }
5744                                 }
5745                                 #endregion
5746
5747                                 // ここまでで、n小節番号を得ている
5748                                 // ここで、更にgridを得たうえで、16分音符相当にquantizeして、BEATチップの位置とする
5749
5750                                 #region [ BEATチップを置く ]
5751                                 float f小節長倍率 = this.mgr譜面管理者.dic小節[ n小節番号 ].f小節長倍率;
5752                                 int n小節内Grid = (int) ( CWholeNoteDivision.n分解能 * f小節長倍率 * deltatime / ( ( 60 * 4 ) / tempo ) + 0.5 );
5753
5754                                 #region [ Gridを16分音符単位(==12grid単位)でquantizeする ]
5755                                 //Debug.Write( "nGrid: " + n小節内Grid + " -> " );
5756                                 n小節内Grid = ( ( n小節内Grid + 6 ) / 12 ) * 12;
5757                                 //Debug.WriteLine( n小節内Grid );
5758                                 #endregion
5759
5760                                 int nGrid = this.mgr譜面管理者.n譜面先頭からみた小節先頭の位置gridを返す( n小節番号 ) + n小節内Grid;
5761
5762                                 if ( lastnGrid != nGrid )
5763                                 {
5764                                         // indexを+1しているのは、チップ番号を01から開始するため。
5765                                         this.mgr編集モード管理者.tBeatチップを配置する( nGrid, index + 1, sbp.fBeatTime, sbp.b無効 );
5766                                         //                              this.mgr編集モード管理者.tHHチップを配置する( nGrid, 1, sbp.b無効 );  // デバッグ用・見やすくするために暫定的に。
5767                                         sbp.nGrid = nGrid;
5768                                         sbp.n小節番号 = n小節番号;
5769                                         listBeatPositions[ index ] = sbp;               // Grid情報を入れて、listを更新 (この情報はBPx挿入時に使う)
5770                                         lastnGrid = nGrid;
5771                                 }
5772                                 //if ( !sbp.b無効 )
5773                                 {
5774                                         //lastGrid = nGrid;
5775                                         //last小節内Grid = n小節内Grid;
5776                                         //last小節番号 = n小節番号;
5777                                         //lastBeatTime = sbp.fBeatTime;
5778                                 }
5779                                 #endregion
5780                                 //Debug.WriteLine( "[" + index + "]: n小節番号=" + n小節番号 + ", Grid= " + n小節内Grid + "/" + nGrid + ", BeatTime=" + sbp.fBeatTime + ", 裏=" + sbp.b無効 );
5781                         }
5782                         #endregion
5783
5784                         BPMchipsGeneneration_Main();
5785
5786                         cbd.Dispose();
5787                         cbd = null;
5788
5789                         #region [ Beatレーンを表示する ]
5790                         this.mgr譜面管理者.listレーン[ laneBEAT ].bIsVisible = true;
5791                         #endregion
5792
5793                         #region [ 画面の再描画 ]
5794                         this.pictureBox譜面パネル.Invalidate();
5795                         #endregion
5796
5797
5798                         #region [ listBeatPositionsの開放 ]
5799                         listBeatPositions.Clear();
5800                         listBeatPositions = null;
5801                         #endregion
5802
5803                         #region [ マウスカーソルの形を元に戻す ]
5804                         this.Cursor = Cursors.Default;
5805                         #endregion
5806                 }
5807
5808                 //private void ToolStripMenuItemBPMChipsGeneration_Click( object sender, EventArgs e )
5809                 //{
5810                 //    BPMchipsGeneneration_Main();
5811                 //}
5812
5813                 private void BPMchipsGeneneration_Main()
5814                 {
5815                         #region [ BPMレーンとHHレーンを消去(0小節目を除く) ]
5816                         int laneBPM = this.mgr譜面管理者.nレーン名に対応するレーン番号を返す( "BPM" );
5817                         this.mgr選択モード管理者.tレーン上の全チップを選択する( laneBPM, 1 );
5818                         this.tシナリオ_削除();
5819
5820                         #region [ デバッグ用: HHレーンを消去 ]
5821                         int laneHH = this.mgr譜面管理者.nレーン名に対応するレーン番号を返す( "HH" );
5822                         this.mgr選択モード管理者.tレーン上の全チップを選択する( laneHH, 1 );
5823                         this.tシナリオ_削除();
5824                         #endregion
5825                         #endregion
5826
5827                                                                                                                                                                                         //★★★★小節長1.00以外の場合に後で対応のこと。
5828                         #region [ BEATレーンから、listBestPositionを生成 ]
5829                         int laneBEAT = this.mgr譜面管理者.nレーン名に対応するレーン番号を返す( "BEAT" );
5830 //Debug.WriteLine( "laneBEAT=" + laneBEAT );
5831                         List<FDK.CBeatDetect.stBeatPos> listBeatPositions = new List<CBeatDetect.stBeatPos>();
5832                         foreach ( KeyValuePair<int, C小節> pair in this.mgr譜面管理者.dic小節 )
5833                         {
5834                                 C小節 c小節 = pair.Value;
5835                                 for ( int index = 0; index < c小節.listチップ.Count; index++ )
5836                                 {
5837                                         if ( c小節.listチップ[ index ].nレーン番号0to == laneBEAT &&
5838                                                 !c小節.listチップ[ index ].b裏 )
5839                                         {
5840                                                 int n小節番号 = c小節.n小節番号0to3599;
5841 //Debug.WriteLine( "n小節番号=" + c小節.n小節番号0to3599 + ", 小節内Grid=" + c小節.listチップ[ index ].n位置grid + ",lane=" + c小節.listチップ[ index ].nレーン番号0to + ", f値=" + c小節.listチップ[ index ].f値・浮動小数 );
5842
5843                 
5844                                                 listBeatPositions.Add(
5845                                                         new CBeatDetect.stBeatPos(
5846                                                                 c小節.listチップ[ index ].f値_浮動小数,
5847                                                                 n小節番号,
5848                                                                 this.mgr譜面管理者.n譜面先頭からみた小節先頭の位置gridを返す( n小節番号 ) + c小節.listチップ[ index ].n位置grid,
5849                                                                 c小節.listチップ[ index ].n位置grid,
5850                                                                 c小節.listチップ[ index ].b裏,
5851                                                                 true
5852                                                         )
5853                                                 );
5854                                         }
5855                                         else
5856                                         {
5857 //Debug.WriteLine( "N小節番号=" + c小節.n小節番号0to3599 + ", 小節内Grid=" + c小節.listチップ[ index ].n位置grid + ",lane=" + c小節.listチップ[ index ].nレーン番号0to + ", f値=" + c小節.listチップ[ index ].f値・浮動小数 );
5858                                         }
5859                                 }
5860                         }
5861                         #endregion
5862
5863
5864                         #region [ BEATチップの位置に合わせて、BPMを計算し、BPxチップを配置する ]
5865
5866                         int n1拍目のBeatPositionIndex = 0;
5867
5868                         int lastindex = 0;
5869                         for ( int index = n1拍目のBeatPositionIndex; index < listBeatPositions.Count; index++ )
5870                         {
5871                                 if ( listBeatPositions[ index ].b無効 )
5872                                 {
5873                                         continue;
5874                                 }
5875                                 #region [ 次の有効なBeatPointを検出する ]
5876                                 int nextIndex = -1;
5877                                 for ( int i = index + 1; i < listBeatPositions.Count; i++ )
5878                                 {
5879                                         if ( listBeatPositions[ i ].bレーン表示する && !listBeatPositions[ i ].b無効 )
5880                                         //if ( listBeatPositions[ i ].bレーン表示する )
5881                                         {
5882                                                 nextIndex = i;
5883                                                 break;
5884                                         }
5885                                 }
5886                                 #endregion
5887
5888                                 #region [ BPMチップを置く]
5889                                 //int lastgrid = (int) ( 192 * this.mgr譜面管理者.dic小節[ 0 ].f小節長倍率 );       // 0小節目の倍率
5890                                 //int lastindex = n1拍目のBeatPositionIndex;
5891                                 //int last小節番号 = nBGMチップの小節番号;
5892
5893                                 if ( nextIndex >= 0 )
5894                                 {
5895                                         float deltatime = listBeatPositions[ nextIndex ].fBeatTime - listBeatPositions[ index ].fBeatTime;
5896 //Debug.WriteLine( "deltatime=" + deltatime+ ", nextIndex=" + nextIndex + ", fBeatTime(nextIndex)=" + listBeatPositions[ nextIndex ].fBeatTime+ ", index=" + index + ", fBeatTIme(index) =" + listBeatPositions[ index ].fBeatTime );
5897
5898                                         //int current小節番号 = listBeatPositionsLight[ index ].n小節番号;
5899                                         //int next小節番号 = listBeatPositionsLight[ nextIndex ].n小節番号;
5900                                         int deltagrid = listBeatPositions[ nextIndex ].nGrid - listBeatPositions[ index ].nGrid;
5901 //Debug.WriteLine( "deltagrid=" + deltagrid + ", nextIndex=" + nextIndex + ", nGrid(nextIndex)=" + listBeatPositions[ nextIndex ].nGrid + ", index=" + index + ", nGrid(index) =" + listBeatPositions[ index ].nGrid );
5902                                         float fBPM = 60.0f / ( deltatime / deltagrid * 48 );            // 四分音符==48grid
5903 //Debug.WriteLine( "fBPM=" + fBPM + ", deltatime=" + deltatime + ", deltagrid=" + deltagrid );
5904
5905                                         // BPMチップを配置する(裏BEATチップに対しては、配置しない)
5906                                         if ( nextIndex >= 0 )
5907                                         {
5908                                                 this.mgr編集モード管理者.tBPMチップを配置する( listBeatPositions[ index ].nGrid, fBPM );
5909 //      Debug.WriteLine( " tBPM: #" + index + "=" + fBPM );
5910                                         }
5911
5912
5913                                         //this.mgr編集モード管理者.tHHチップを配置する( listBeatPositions[ index ].nGrid, 1, listBeatPositions[ index ].b無効 );      // デバッグ用・見やすくするために暫定的に。
5914
5915 // Debug.WriteLine( "(" + index + "->" + nextIndex + "): BPM=" + fBPM + ", nGrid=" + listBeatPositions[ index ].nGrid + ", deltagrid=" + deltagrid +" , deltatime=" + deltatime );
5916                                         lastindex = index;
5917                                 }
5918                                 #endregion
5919                         }
5920                         #region [ デバッグ用: HHチップを置く ]
5921                         for ( int index = n1拍目のBeatPositionIndex; index < listBeatPositions.Count; index++ )
5922                         {
5923                                 this.mgr編集モード管理者.tHHチップを配置する( listBeatPositions[ index ].nGrid, 1, listBeatPositions[ index ].b無効 );        // デバッグ用・見やすくするために暫定的に。
5924                         }
5925                         #endregion
5926
5927                         #region [ listBeatPositionsの開放 ]
5928                         listBeatPositions.Clear();
5929                         listBeatPositions = null;
5930                         #endregion
5931
5932                         #endregion
5933                 }
5934
5935                 private void generateBeatChipsToolStripMenuItem_Click( object sender, EventArgs e )
5936                 {
5937                         GenarateBeatChip_Main();
5938                 }
5939
5940                 private void generateBPMFromBeatChipsToolStripMenuItem_Click( object sender, EventArgs e )
5941                 {
5942                         BPMchipsGeneneration_Main();
5943                 }
5944
5945                 private void toolStripComboBox演奏速度_SelectedIndexChanged( object sender, EventArgs e )
5946                 {
5947                         this.b再生速度を変更した = true;
5948                 }
5949
5950                 public bool DetectDTXManiaProcess()
5951                 {
5952                         // 検索結果のハンドルがZeroになることがあるので、50ms間隔で1回リトライする
5953                         #region [ 既に起動中のDTXManiaプロセスを検索する。]
5954                         // #39609 DTXManiaプロセス検索の単純化&高速化
5955                         System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName("DTXManiaGR");
5956                         if (ps.Length > 0) return true;
5957                         Thread.Sleep(50);
5958
5959                         ps = System.Diagnostics.Process.GetProcessesByName("DTXManiaGR");
5960                         if (ps.Length > 0) return true;
5961                         #endregion
5962                         return false;
5963                 }
5964
5965                 private void calcDifficultyToolStripMenuItem_Click(object sender, EventArgs e)
5966                 {
5967                         DTXCreator.コード._05.譜面.C難易度自動計算マン f = new コード._05.譜面.C難易度自動計算マン(this);
5968
5969                         Cメッセージポップアップ pop = new Cメッセージポップアップ(Resources.str難易度計算マン計算中);
5970                         pop.Owner = this;
5971                         pop.Show();
5972                         pop.Refresh();
5973
5974                         f.Prepare();
5975                         hScrollBarDLEVEL.Value = f.DLevel;
5976                         hScrollBarGLEVEL.Value = f.GLevel;
5977                         hScrollBarBLEVEL.Value = f.BLevel;
5978                         pop.Close();
5979                 }
5980
5981
5982                 //-----------------
5983                 #endregion
5984
5985                 //-----------------
5986                 #endregion
5987
5988
5989         }
5990 }