OSDN Git Service

#xxxxx songs.dbにBPMの情報を含めるよう修正。
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / スコア、曲 / CSong管理.cs
index 5f81392..576f838 100644 (file)
@@ -5,9 +5,11 @@ using System.Text;
 using System.Diagnostics;\r
 using System.IO;\r
 using System.Drawing;\r
+using System.Threading;\r
 \r
 namespace DTXMania\r
 {\r
+       [Serializable]\r
        internal class CSongs管理\r
        {\r
                // プロパティ\r
@@ -42,9 +44,34 @@ namespace DTXMania
                        get; \r
                        set;\r
                }\r
-               public List<Cスコア> listSongsDB;\r
-               public List<C曲リストノード> list曲ルート;\r
+               [NonSerialized]\r
+               public List<Cスコア> listSongsDB;                                    // songs.dbから構築されるlist\r
+               public List<C曲リストノード> list曲ルート;                   // 起動時にフォルダ検索して構築されるlist\r
+               public bool bIsSuspending                                                       // 外部スレッドから、内部スレッドのsuspendを指示する時にtrueにする\r
+               {                                                                                                       // 再開時は、これをfalseにしてから、次のautoReset.Set()を実行する\r
+                       get;\r
+                       set;\r
+               }\r
+               public bool bIsSlowdown                                                         // #PREMOVIE再生時に曲検索を遅くする\r
+               {\r
+                       get;\r
+                       set;\r
+               }\r
+               [NonSerialized]\r
+               private AutoResetEvent autoReset;\r
+               public AutoResetEvent AutoReset\r
+               {\r
+                       get\r
+                       {\r
+                               return autoReset;\r
+                       }\r
+                       private set\r
+                       {\r
+                               autoReset = value;\r
+                       }\r
+               }\r
 \r
+               private int searchCount;                                                        // #PREMOVIE中は検索n回実行したら少しスリープする\r
 \r
                // コンストラクタ\r
 \r
@@ -54,6 +81,9 @@ namespace DTXMania
                        this.list曲ルート = new List<C曲リストノード>();\r
                        this.n検索された曲ノード数 = 0;\r
                        this.n検索されたスコア数 = 0;\r
+                       this.bIsSuspending = false;                                             // #27060\r
+                       this.autoReset = new AutoResetEvent( true );    // #27060\r
+                       this.searchCount = 0;\r
                }\r
 \r
 \r
@@ -70,7 +100,7 @@ namespace DTXMania
                                try\r
                                {\r
                                        br = new BinaryReader( File.OpenRead( SongsDBファイル名 ) );\r
-                                       if( !br.ReadString().Equals( "SongsDB2" ) )\r
+                                       if ( !br.ReadString().Equals( SONGSDB_VERSION ) )\r
                                        {\r
                                                throw new InvalidDataException( "ヘッダが異なります。" );\r
                                        }\r
@@ -99,6 +129,7 @@ namespace DTXMania
                }\r
                //-----------------\r
                #endregion\r
+\r
                #region [ 曲を検索してリストを作成する ]\r
                //-----------------\r
                public void t曲を検索してリストを作成する( string str基点フォルダ, bool b子BOXへ再帰する )\r
@@ -124,11 +155,12 @@ namespace DTXMania
                                new FileInfo( path );\r
                                if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                {\r
-                                       Trace.TraceInformation( "set.def検出 : {0}", new object[] { path } );\r
+                                       Trace.TraceInformation( "set.def検出 : {0}", path );\r
                                        Trace.Indent();\r
                                }\r
                                try\r
                                {\r
+                                       SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
                                        for( int i = 0; i < def.blocks.Count; i++ )\r
                                        {\r
                                                CSetDef.CBlock block = def.blocks[ i ];\r
@@ -141,6 +173,10 @@ namespace DTXMania
                                                item.SetDefのブロック番号 = i;\r
                                                item.pathSetDefの絶対パス = path;\r
                                                item.r親ノード = node親;\r
+\r
+                                               item.strBreadcrumbs = ( item.r親ノード == null ) ?\r
+                                                       path + i : item.r親ノード.strBreadcrumbs + " > " + path + i;\r
+\r
                                                for( int j = 0; j < 5; j++ )\r
                                                {\r
                                                        if( !string.IsNullOrEmpty( block.File[ j ] ) )\r
@@ -241,49 +277,54 @@ namespace DTXMania
                        //-----------------------------\r
                        else\r
                        {\r
-                               foreach( FileInfo info4 in info.GetFiles() )\r
+                               foreach( FileInfo fileinfo in info.GetFiles() )\r
                                {\r
-                                       string str4 = info4.Extension.ToLower();\r
-                                       if( ( str4.Equals( ".dtx" ) || str4.Equals( ".gda" ) ) || ( ( str4.Equals( ".g2d" ) || str4.Equals( ".bms" ) ) || str4.Equals( ".bme" ) ) )\r
-                                       {\r
-                                               C曲リストノード c曲リストノード2 = new C曲リストノード();\r
-                                               c曲リストノード2.eノード種別 = C曲リストノード.Eノード種別.SCORE;\r
-                                               c曲リストノード2.nスコア数 = 1;\r
-                                               c曲リストノード2.r親ノード = node親;\r
-                                               c曲リストノード2.arスコア[ 0 ] = new Cスコア();\r
-                                               c曲リストノード2.arスコア[ 0 ].ファイル情報.ファイルの絶対パス = str基点フォルダ + info4.Name;\r
-                                               c曲リストノード2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = str基点フォルダ;\r
-                                               c曲リストノード2.arスコア[ 0 ].ファイル情報.ファイルサイズ = info4.Length;\r
-                                               c曲リストノード2.arスコア[ 0 ].ファイル情報.最終更新日時 = info4.LastWriteTime;\r
-                                               string str5 = c曲リストノード2.arスコア[ 0 ].ファイル情報.ファイルの絶対パス + ".score.ini";\r
-                                               if( File.Exists( str5 ) )\r
+                                       SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
+                                       string strExt = fileinfo.Extension.ToLower();\r
+                                       if( ( strExt.Equals( ".dtx" ) || strExt.Equals( ".gda" ) ) || ( ( strExt.Equals( ".g2d" ) || strExt.Equals( ".bms" ) ) || strExt.Equals( ".bme" ) ) )\r
+                                       {\r
+                                               C曲リストノード c曲リストノード = new C曲リストノード();\r
+                                               c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.SCORE;\r
+                                               c曲リストノード.nスコア数 = 1;\r
+                                               c曲リストノード.r親ノード = node親;\r
+\r
+                                               c曲リストノード.strBreadcrumbs = ( c曲リストノード.r親ノード == null ) ?\r
+                                                       str基点フォルダ + fileinfo.Name : c曲リストノード.r親ノード.strBreadcrumbs + " > " + str基点フォルダ + fileinfo.Name;\r
+\r
+                                               c曲リストノード.arスコア[ 0 ] = new Cスコア();\r
+                                               c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス = str基点フォルダ + fileinfo.Name;\r
+                                               c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = str基点フォルダ;\r
+                                               c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルサイズ = fileinfo.Length;\r
+                                               c曲リストノード.arスコア[ 0 ].ファイル情報.最終更新日時 = fileinfo.LastWriteTime;\r
+                                               string strFileNameScoreIni = c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス + ".score.ini";\r
+                                               if( File.Exists( strFileNameScoreIni ) )\r
                                                {\r
-                                                       FileInfo info5 = new FileInfo( str5 );\r
-                                                       c曲リストノード2.arスコア[ 0 ].ScoreIni情報.ファイルサイズ = info5.Length;\r
-                                                       c曲リストノード2.arスコア[ 0 ].ScoreIni情報.最終更新日時 = info5.LastWriteTime;\r
+                                                       FileInfo infoScoreIni = new FileInfo( strFileNameScoreIni );\r
+                                                       c曲リストノード.arスコア[ 0 ].ScoreIni情報.ファイルサイズ = infoScoreIni.Length;\r
+                                                       c曲リストノード.arスコア[ 0 ].ScoreIni情報.最終更新日時 = infoScoreIni.LastWriteTime;\r
                                                }\r
                                                this.n検索されたスコア数++;\r
-                                               listノードリスト.Add( c曲リストノード2 );\r
+                                               listノードリスト.Add( c曲リストノード );\r
                                                this.n検索された曲ノード数++;\r
                                                if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                                {\r
                                                        Trace.Indent();\r
                                                        try\r
                                                        {\r
-                                                               StringBuilder builder2 = new StringBuilder( 0x100 );\r
-                                                               builder2.Append( string.Format( "nID#{0:D3}", c曲リストノード2.nID ) );\r
-                                                               if( c曲リストノード2.r親ノード != null )\r
+                                                               StringBuilder sb = new StringBuilder( 0x100 );\r
+                                                               sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );\r
+                                                               if( c曲リストノード.r親ノード != null )\r
                                                                {\r
-                                                                       builder2.Append( string.Format( "(in#{0:D3}):", c曲リストノード2.r親ノード.nID ) );\r
+                                                                       sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );\r
                                                                }\r
                                                                else\r
                                                                {\r
-                                                                       builder2.Append( "(onRoot):" );\r
+                                                                       sb.Append( "(onRoot):" );\r
                                                                }\r
-                                                               builder2.Append( " SONG, File=" + c曲リストノード2.arスコア[ 0 ].ファイル情報.ファイルの絶対パス );\r
-                                                               builder2.Append( ", Size=" + c曲リストノード2.arスコア[ 0 ].ファイル情報.ファイルサイズ );\r
-                                                               builder2.Append( ", LastUpdate=" + c曲リストノード2.arスコア[ 0 ].ファイル情報.最終更新日時 );\r
-                                                               Trace.TraceInformation( builder2.ToString() );\r
+                                                               sb.Append( " SONG, File=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス );\r
+                                                               sb.Append( ", Size=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルサイズ );\r
+                                                               sb.Append( ", LastUpdate=" + c曲リストノード.arスコア[ 0 ].ファイル情報.最終更新日時 );\r
+                                                               Trace.TraceInformation( sb.ToString() );\r
                                                        }\r
                                                        finally\r
                                                        {\r
@@ -291,86 +332,124 @@ namespace DTXMania
                                                        }\r
                                                }\r
                                        }\r
-                                       else if( !str4.Equals( ".mid" ) )\r
+                                       else if( strExt.Equals( ".mid" ) || strExt.Equals( ".smf" ))\r
                                        {\r
-                                               str4.Equals( ".smf" );\r
+                                               // 何もしない\r
                                        }\r
                                }\r
                        }\r
                        //-----------------------------\r
                        #endregion\r
 \r
-                       foreach( DirectoryInfo info6 in info.GetDirectories() )\r
+                       foreach( DirectoryInfo infoDir in info.GetDirectories() )\r
                        {\r
+                               SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
+\r
                                #region [ a. "dtxfiles." で始まるフォルダの場合 ]\r
                                //-----------------------------\r
-                               if( info6.Name.ToLower().StartsWith( "dtxfiles." ) )\r
+                               if( infoDir.Name.ToLower().StartsWith( "dtxfiles." ) )\r
                                {\r
-                                       C曲リストノード c曲リストノード3 = new C曲リストノード();\r
-                                       c曲リストノード3.eノード種別 = C曲リストノード.Eノード種別.BOX;\r
-                                       c曲リストノード3.bDTXFilesで始まるフォルダ名のBOXである = true;\r
-                                       c曲リストノード3.strタイトル = info6.Name.Substring( 9 );\r
-                                       c曲リストノード3.nスコア数 = 1;\r
-                                       c曲リストノード3.r親ノード = node親;\r
-                                       c曲リストノード3.list子リスト = new List<C曲リストノード>();\r
-                                       c曲リストノード3.arスコア[ 0 ] = new Cスコア();\r
-                                       c曲リストノード3.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = info6.FullName + @"\";\r
-                                       c曲リストノード3.arスコア[ 0 ].譜面情報.タイトル = c曲リストノード3.strタイトル;\r
-                                       c曲リストノード3.arスコア[ 0 ].譜面情報.コメント =\r
+                                       C曲リストノード c曲リストノード = new C曲リストノード();\r
+                                       c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.BOX;\r
+                                       c曲リストノード.bDTXFilesで始まるフォルダ名のBOXである = true;\r
+                                       c曲リストノード.strタイトル = infoDir.Name.Substring( 9 );\r
+                                       c曲リストノード.nスコア数 = 1;\r
+                                       c曲リストノード.r親ノード = node親;\r
+\r
+                                       // 一旦、上位BOXのスキン情報をコピー (後でbox.defの記載にて上書きされる場合がある)\r
+                                       c曲リストノード.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
+                                               "" : c曲リストノード.r親ノード.strSkinPath;\r
+\r
+                                       c曲リストノード.strBreadcrumbs = ( c曲リストノード.r親ノード == null ) ?\r
+                                               c曲リストノード.strタイトル : c曲リストノード.r親ノード.strBreadcrumbs + " > " + c曲リストノード.strタイトル;\r
+\r
+               \r
+                                       c曲リストノード.list子リスト = new List<C曲リストノード>();\r
+                                       c曲リストノード.arスコア[ 0 ] = new Cスコア();\r
+                                       c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = infoDir.FullName + @"\";\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.タイトル = c曲リストノード.strタイトル;\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.コメント =\r
                                                (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?\r
                                                "BOX に移動します。" :\r
                                                "Enter into the BOX.";\r
-                                       listノードリスト.Add(c曲リストノード3);\r
-                                       if( File.Exists( info6.FullName + @"\box.def" ) )\r
+                                       listノードリスト.Add(c曲リストノード);\r
+                                       if( File.Exists( infoDir.FullName + @"\box.def" ) )\r
                                        {\r
-                                               CBoxDef def2 = new CBoxDef( info6.FullName + @"\box.def" );\r
-                                               if( ( def2.Title != null ) && ( def2.Title.Length > 0 ) )\r
+                                               CBoxDef boxdef = new CBoxDef( infoDir.FullName + @"\box.def" );\r
+                                               if( ( boxdef.Title != null ) && ( boxdef.Title.Length > 0 ) )\r
                                                {\r
-                                                       c曲リストノード3.strタイトル = def2.Title;\r
+                                                       c曲リストノード.strタイトル = boxdef.Title;\r
                                                }\r
-                                               if( ( def2.Genre != null ) && ( def2.Genre.Length > 0 ) )\r
+                                               if( ( boxdef.Genre != null ) && ( boxdef.Genre.Length > 0 ) )\r
                                                {\r
-                                                       c曲リストノード3.strジャンル = def2.Genre;\r
+                                                       c曲リストノード.strジャンル = boxdef.Genre;\r
                                                }\r
-                                               if( def2.Color != Color.White )\r
+                                               if( boxdef.Color != Color.White )\r
                                                {\r
-                                                       c曲リストノード3.col文字色 = def2.Color;\r
+                                                       c曲リストノード.col文字色 = boxdef.Color;\r
                                                }\r
-                                               if( ( def2.Artist != null ) && ( def2.Artist.Length > 0 ) )\r
+                                               if( ( boxdef.Artist != null ) && ( boxdef.Artist.Length > 0 ) )\r
                                                {\r
-                                                       c曲リストノード3.arスコア[ 0 ].譜面情報.アーティスト名 = def2.Artist;\r
+                                                       c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 = boxdef.Artist;\r
                                                }\r
-                                               if( ( def2.Comment != null ) && ( def2.Comment.Length > 0 ) )\r
+                                               if( ( boxdef.Comment != null ) && ( boxdef.Comment.Length > 0 ) )\r
                                                {\r
-                                                       c曲リストノード3.arスコア[ 0 ].譜面情報.コメント = def2.Comment;\r
+                                                       c曲リストノード.arスコア[ 0 ].譜面情報.コメント = boxdef.Comment;\r
                                                }\r
-                                               if( ( def2.Preimage != null ) && ( def2.Preimage.Length > 0 ) )\r
+                                               if( ( boxdef.Preimage != null ) && ( boxdef.Preimage.Length > 0 ) )\r
                                                {\r
-                                                       c曲リストノード3.arスコア[ 0 ].譜面情報.Preimage = def2.Preimage;\r
+                                                       c曲リストノード.arスコア[ 0 ].譜面情報.Preimage = boxdef.Preimage;\r
                                                }\r
-                                               if( ( def2.Premovie != null ) && ( def2.Premovie.Length > 0 ) )\r
+                                               if( ( boxdef.Premovie != null ) && ( boxdef.Premovie.Length > 0 ) )\r
                                                {\r
-                                                       c曲リストノード3.arスコア[ 0 ].譜面情報.Premovie = def2.Premovie;\r
+                                                       c曲リストノード.arスコア[ 0 ].譜面情報.Premovie = boxdef.Premovie;\r
                                                }\r
-                                               if( ( def2.Presound != null ) && ( def2.Presound.Length > 0 ) )\r
+                                               if( ( boxdef.Presound != null ) && ( boxdef.Presound.Length > 0 ) )\r
                                                {\r
-                                                       c曲リストノード3.arスコア[ 0 ].譜面情報.Presound = def2.Presound;\r
+                                                       c曲リストノード.arスコア[ 0 ].譜面情報.Presound = boxdef.Presound;\r
+                                               }\r
+                                               if ( boxdef.SkinPath != null )\r
+                                               {\r
+                                                       if ( boxdef.SkinPath == "" )\r
+                                                       {\r
+                                                               // box.defにスキン情報が記載されていないなら、上位BOXのスキン情報をコピー\r
+                                                               c曲リストノード.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
+                                                                       "" : c曲リストノード.r親ノード.strSkinPath;\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               // box.defに記載されているスキン情報をコピー。末尾に必ず\をつけておくこと。\r
+                                                               string s = System.IO.Path.Combine( infoDir.FullName, boxdef.SkinPath );\r
+                                                               if ( s[ s.Length - 1 ] != System.IO.Path.DirectorySeparatorChar )       // フォルダ名末尾に\を必ずつけて、CSkin側と表記を統一する\r
+                                                               {\r
+                                                                       s += System.IO.Path.DirectorySeparatorChar;\r
+                                                               }\r
+                                                               if ( CDTXMania.Skin.bIsValid( s ) )\r
+                                                               {\r
+                                                                       c曲リストノード.strSkinPath = s;\r
+                                                               }\r
+                                                               else\r
+                                                               {\r
+                                                                       c曲リストノード.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
+                                                                               "" : c曲リストノード.r親ノード.strSkinPath;\r
+                                                               }\r
+                                                       }\r
                                                }\r
-                                               if( def2.PerfectRange >= 0 )\r
+                                               if ( boxdef.PerfectRange >= 0 )\r
                                                {\r
-                                                       c曲リストノード3.nPerfect範囲ms = def2.PerfectRange;\r
+                                                       c曲リストノード.nPerfect範囲ms = boxdef.PerfectRange;\r
                                                }\r
-                                               if( def2.GreatRange >= 0 )\r
+                                               if( boxdef.GreatRange >= 0 )\r
                                                {\r
-                                                       c曲リストノード3.nGreat範囲ms = def2.GreatRange;\r
+                                                       c曲リストノード.nGreat範囲ms = boxdef.GreatRange;\r
                                                }\r
-                                               if( def2.GoodRange >= 0 )\r
+                                               if( boxdef.GoodRange >= 0 )\r
                                                {\r
-                                                       c曲リストノード3.nGood範囲ms = def2.GoodRange;\r
+                                                       c曲リストノード.nGood範囲ms = boxdef.GoodRange;\r
                                                }\r
-                                               if( def2.PoorRange >= 0 )\r
+                                               if( boxdef.PoorRange >= 0 )\r
                                                {\r
-                                                       c曲リストノード3.nPoor範囲ms = def2.PoorRange;\r
+                                                       c曲リストノード.nPoor範囲ms = boxdef.PoorRange;\r
                                                }\r
                                        }\r
                                        if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
@@ -378,20 +457,21 @@ namespace DTXMania
                                                Trace.Indent();\r
                                                try\r
                                                {\r
-                                                       StringBuilder builder3 = new StringBuilder( 0x100 );\r
-                                                       builder3.Append( string.Format( "nID#{0:D3}", c曲リストノード3.nID ) );\r
-                                                       if( c曲リストノード3.r親ノード != null )\r
+                                                       StringBuilder sb = new StringBuilder( 0x100 );\r
+                                                       sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );\r
+                                                       if( c曲リストノード.r親ノード != null )\r
                                                        {\r
-                                                               builder3.Append( string.Format( "(in#{0:D3}):", c曲リストノード3.r親ノード.nID ) );\r
+                                                               sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );\r
                                                        }\r
                                                        else\r
                                                        {\r
-                                                               builder3.Append( "(onRoot):" );\r
+                                                               sb.Append( "(onRoot):" );\r
                                                        }\r
-                                                       builder3.Append( " BOX, Title=" + c曲リストノード3.strタイトル );\r
-                                                       builder3.Append( ", Folder=" + c曲リストノード3.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
-                                                       builder3.Append( ", Comment=" + c曲リストノード3.arスコア[ 0 ].譜面情報.コメント );\r
-                                                       Trace.TraceInformation( builder3.ToString() );\r
+                                                       sb.Append( " BOX, Title=" + c曲リストノード.strタイトル );\r
+                                                       sb.Append( ", Folder=" + c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
+                                                       sb.Append( ", Comment=" + c曲リストノード.arスコア[ 0 ].譜面情報.コメント );\r
+                                                       sb.Append( ", SkinPath=" + c曲リストノード.strSkinPath );\r
+                                                       Trace.TraceInformation( sb.ToString() );\r
                                                }\r
                                                finally\r
                                                {\r
@@ -400,7 +480,7 @@ namespace DTXMania
                                        }\r
                                        if( b子BOXへ再帰する )\r
                                        {\r
-                                               this.t曲を検索してリストを作成する( info6.FullName + @"\", b子BOXへ再帰する, c曲リストノード3.list子リスト, c曲リストノード3 );\r
+                                               this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, c曲リストノード.list子リスト, c曲リストノード );\r
                                        }\r
                                }\r
                                //-----------------------------\r
@@ -408,94 +488,127 @@ namespace DTXMania
 \r
                                #region [ b.box.def を含むフォルダの場合  ]\r
                                //-----------------------------\r
-                               else if( File.Exists( info6.FullName + @"\box.def" ) )\r
+                               else if( File.Exists( infoDir.FullName + @"\box.def" ) )\r
                                {\r
-                                       CBoxDef def3 = new CBoxDef( info6.FullName + @"\box.def" );\r
-                                       C曲リストノード c曲リストノード4 = new C曲リストノード();\r
-                                       c曲リストノード4.eノード種別 = C曲リストノード.Eノード種別.BOX;\r
-                                       c曲リストノード4.bDTXFilesで始まるフォルダ名のBOXである = false;\r
-                                       c曲リストノード4.strタイトル = def3.Title;\r
-                                       c曲リストノード4.strジャンル = def3.Genre;\r
-                                       c曲リストノード4.col文字色 = def3.Color;\r
-                                       c曲リストノード4.nスコア数 = 1;\r
-                                       c曲リストノード4.arスコア[ 0 ] = new Cスコア();\r
-                                       c曲リストノード4.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = info6.FullName + @"\";\r
-                                       c曲リストノード4.arスコア[ 0 ].譜面情報.タイトル = def3.Title;\r
-                                       c曲リストノード4.arスコア[ 0 ].譜面情報.ジャンル = def3.Genre;\r
-                                       c曲リストノード4.arスコア[ 0 ].譜面情報.アーティスト名 = def3.Artist;\r
-                                       c曲リストノード4.arスコア[ 0 ].譜面情報.コメント = def3.Comment;\r
-                                       c曲リストノード4.arスコア[ 0 ].譜面情報.Preimage = def3.Preimage;\r
-                                       c曲リストノード4.arスコア[ 0 ].譜面情報.Premovie = def3.Premovie;\r
-                                       c曲リストノード4.arスコア[ 0 ].譜面情報.Presound = def3.Presound;\r
-                                       c曲リストノード4.r親ノード = node親;\r
-                                       c曲リストノード4.list子リスト = new List<C曲リストノード>();\r
-                                       c曲リストノード4.nPerfect範囲ms = def3.PerfectRange;\r
-                                       c曲リストノード4.nGreat範囲ms = def3.GreatRange;\r
-                                       c曲リストノード4.nGood範囲ms = def3.GoodRange;\r
-                                       c曲リストノード4.nPoor範囲ms = def3.PoorRange;\r
-                                       listノードリスト.Add( c曲リストノード4 );\r
+                                       CBoxDef boxdef = new CBoxDef( infoDir.FullName + @"\box.def" );\r
+                                       C曲リストノード c曲リストノード = new C曲リストノード();\r
+                                       c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.BOX;\r
+                                       c曲リストノード.bDTXFilesで始まるフォルダ名のBOXである = false;\r
+                                       c曲リストノード.strタイトル = boxdef.Title;\r
+                                       c曲リストノード.strジャンル = boxdef.Genre;\r
+                                       c曲リストノード.col文字色 = boxdef.Color;\r
+                                       c曲リストノード.nスコア数 = 1;\r
+                                       c曲リストノード.arスコア[ 0 ] = new Cスコア();\r
+                                       c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = infoDir.FullName + @"\";\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.タイトル = boxdef.Title;\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.ジャンル = boxdef.Genre;\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 = boxdef.Artist;\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.コメント = boxdef.Comment;\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.Preimage = boxdef.Preimage;\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.Premovie = boxdef.Premovie;\r
+                                       c曲リストノード.arスコア[ 0 ].譜面情報.Presound = boxdef.Presound;\r
+                                       c曲リストノード.r親ノード = node親;\r
+\r
+                                       if ( boxdef.SkinPath == "" )\r
+                                       {\r
+                                               // box.defにスキン情報が記載されていないなら、上位BOXのスキン情報をコピー\r
+                                               c曲リストノード.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
+                                                       "" : c曲リストノード.r親ノード.strSkinPath;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               // box.defに記載されているスキン情報をコピー。末尾に必ず\をつけておくこと。\r
+                                               string s = System.IO.Path.Combine( infoDir.FullName, boxdef.SkinPath );\r
+                                               if ( s[ s.Length - 1 ] != System.IO.Path.DirectorySeparatorChar )       // フォルダ名末尾に\を必ずつけて、CSkin側と表記を統一する\r
+                                               {\r
+                                                       s += System.IO.Path.DirectorySeparatorChar;\r
+                                               }\r
+                                               if ( CDTXMania.Skin.bIsValid( s ) )\r
+                                               {\r
+                                                       c曲リストノード.strSkinPath = s;\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       c曲リストノード.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
+                                                               "" : c曲リストノード.r親ノード.strSkinPath;\r
+                                               }\r
+                                       }\r
+                                       c曲リストノード.strBreadcrumbs = ( c曲リストノード.r親ノード == null ) ?\r
+                                               c曲リストノード.strタイトル : c曲リストノード.r親ノード.strBreadcrumbs + " > " + c曲リストノード.strタイトル;\r
+       \r
+                                       \r
+                                       c曲リストノード.list子リスト = new List<C曲リストノード>();\r
+                                       c曲リストノード.nPerfect範囲ms = boxdef.PerfectRange;\r
+                                       c曲リストノード.nGreat範囲ms = boxdef.GreatRange;\r
+                                       c曲リストノード.nGood範囲ms = boxdef.GoodRange;\r
+                                       c曲リストノード.nPoor範囲ms = boxdef.PoorRange;\r
+                                       listノードリスト.Add( c曲リストノード );\r
                                        if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                        {\r
-                                               Trace.TraceInformation( "box.def検出 : {0}", new object[] { info6.FullName + @"\box.def" } );\r
+                                               Trace.TraceInformation( "box.def検出 : {0}", infoDir.FullName + @"\box.def" );\r
                                                Trace.Indent();\r
                                                try\r
                                                {\r
-                                                       StringBuilder builder4 = new StringBuilder( 0x400 );\r
-                                                       builder4.Append( string.Format( "nID#{0:D3}", c曲リストノード4.nID ) );\r
-                                                       if( c曲リストノード4.r親ノード != null )\r
+                                                       StringBuilder sb = new StringBuilder( 0x400 );\r
+                                                       sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );\r
+                                                       if( c曲リストノード.r親ノード != null )\r
                                                        {\r
-                                                               builder4.Append( string.Format( "(in#{0:D3}):", c曲リストノード4.r親ノード.nID ) );\r
+                                                               sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );\r
                                                        }\r
                                                        else\r
                                                        {\r
-                                                               builder4.Append( "(onRoot):" );\r
+                                                               sb.Append( "(onRoot):" );\r
                                                        }\r
-                                                       builder4.Append( "BOX, Title=" + c曲リストノード4.strタイトル );\r
-                                                       if( ( c曲リストノード4.strジャンル != null ) && ( c曲リストノード4.strジャンル.Length > 0 ) )\r
+                                                       sb.Append( "BOX, Title=" + c曲リストノード.strタイトル );\r
+                                                       if( ( c曲リストノード.strジャンル != null ) && ( c曲リストノード.strジャンル.Length > 0 ) )\r
                                                        {\r
-                                                               builder4.Append( ", Genre=" + c曲リストノード4.strジャンル );\r
+                                                               sb.Append( ", Genre=" + c曲リストノード.strジャンル );\r
                                                        }\r
-                                                       if( ( c曲リストノード4.arスコア[ 0 ].譜面情報.アーティスト名 != null ) && ( c曲リストノード4.arスコア[ 0 ].譜面情報.アーティスト名.Length > 0 ) )\r
+                                                       if( ( c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名.Length > 0 ) )\r
                                                        {\r
-                                                               builder4.Append( ", Artist=" + c曲リストノード4.arスコア[ 0 ].譜面情報.アーティスト名 );\r
+                                                               sb.Append( ", Artist=" + c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 );\r
                                                        }\r
-                                                       if( ( c曲リストノード4.arスコア[ 0 ].譜面情報.コメント != null ) && ( c曲リストノード4.arスコア[ 0 ].譜面情報.コメント.Length > 0 ) )\r
+                                                       if( ( c曲リストノード.arスコア[ 0 ].譜面情報.コメント != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.コメント.Length > 0 ) )\r
                                                        {\r
-                                                               builder4.Append( ", Comment=" + c曲リストノード4.arスコア[ 0 ].譜面情報.コメント );\r
+                                                               sb.Append( ", Comment=" + c曲リストノード.arスコア[ 0 ].譜面情報.コメント );\r
                                                        }\r
-                                                       if( ( c曲リストノード4.arスコア[ 0 ].譜面情報.Preimage != null ) && ( c曲リストノード4.arスコア[ 0 ].譜面情報.Preimage.Length > 0 ) )\r
+                                                       if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Preimage != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Preimage.Length > 0 ) )\r
                                                        {\r
-                                                               builder4.Append( ", Preimage=" + c曲リストノード4.arスコア[ 0 ].譜面情報.Preimage );\r
+                                                               sb.Append( ", Preimage=" + c曲リストノード.arスコア[ 0 ].譜面情報.Preimage );\r
                                                        }\r
-                                                       if( ( c曲リストノード4.arスコア[ 0 ].譜面情報.Premovie != null ) && ( c曲リストノード4.arスコア[ 0 ].譜面情報.Premovie.Length > 0 ) )\r
+                                                       if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Premovie != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Premovie.Length > 0 ) )\r
                                                        {\r
-                                                               builder4.Append( ", Premovie=" + c曲リストノード4.arスコア[ 0 ].譜面情報.Premovie );\r
+                                                               sb.Append( ", Premovie=" + c曲リストノード.arスコア[ 0 ].譜面情報.Premovie );\r
                                                        }\r
-                                                       if( ( c曲リストノード4.arスコア[ 0 ].譜面情報.Presound != null ) && ( c曲リストノード4.arスコア[ 0 ].譜面情報.Presound.Length > 0 ) )\r
+                                                       if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Presound != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Presound.Length > 0 ) )\r
                                                        {\r
-                                                               builder4.Append( ", Presound=" + c曲リストノード4.arスコア[ 0 ].譜面情報.Presound );\r
+                                                               sb.Append( ", Presound=" + c曲リストノード.arスコア[ 0 ].譜面情報.Presound );\r
                                                        }\r
-                                                       if( c曲リストノード4.col文字色 != ColorTranslator.FromHtml( "White" ) )\r
+                                                       if( c曲リストノード.col文字色 != ColorTranslator.FromHtml( "White" ) )\r
                                                        {\r
-                                                               builder4.Append( ", FontColor=" + c曲リストノード4.col文字色 );\r
+                                                               sb.Append( ", FontColor=" + c曲リストノード.col文字色 );\r
                                                        }\r
-                                                       if( c曲リストノード4.nPerfect範囲ms != -1 )\r
+                                                       if( c曲リストノード.nPerfect範囲ms != -1 )\r
                                                        {\r
-                                                               builder4.Append( ", Perfect=" + c曲リストノード4.nPerfect範囲ms + "ms" );\r
+                                                               sb.Append( ", Perfect=" + c曲リストノード.nPerfect範囲ms + "ms" );\r
                                                        }\r
-                                                       if( c曲リストノード4.nGreat範囲ms != -1 )\r
+                                                       if( c曲リストノード.nGreat範囲ms != -1 )\r
                                                        {\r
-                                                               builder4.Append( ", Great=" + c曲リストノード4.nGreat範囲ms + "ms" );\r
+                                                               sb.Append( ", Great=" + c曲リストノード.nGreat範囲ms + "ms" );\r
                                                        }\r
-                                                       if( c曲リストノード4.nGood範囲ms != -1 )\r
+                                                       if( c曲リストノード.nGood範囲ms != -1 )\r
                                                        {\r
-                                                               builder4.Append( ", Good=" + c曲リストノード4.nGood範囲ms + "ms" );\r
+                                                               sb.Append( ", Good=" + c曲リストノード.nGood範囲ms + "ms" );\r
                                                        }\r
-                                                       if( c曲リストノード4.nPoor範囲ms != -1 )\r
+                                                       if( c曲リストノード.nPoor範囲ms != -1 )\r
                                                        {\r
-                                                               builder4.Append( ", Poor=" + c曲リストノード4.nPoor範囲ms + "ms" );\r
+                                                               sb.Append( ", Poor=" + c曲リストノード.nPoor範囲ms + "ms" );\r
                                                        }\r
-                                                       Trace.TraceInformation( builder4.ToString() );\r
+                                                       if ( ( c曲リストノード.strSkinPath != null ) && ( c曲リストノード.strSkinPath.Length > 0 ) )\r
+                                                       {\r
+                                                               sb.Append( ", SkinPath=" + c曲リストノード.strSkinPath );\r
+                                                       }\r
+                                                       Trace.TraceInformation( sb.ToString() );\r
                                                }\r
                                                finally\r
                                                {\r
@@ -504,7 +617,7 @@ namespace DTXMania
                                        }\r
                                        if( b子BOXへ再帰する )\r
                                        {\r
-                                               this.t曲を検索してリストを作成する( info6.FullName + @"\", b子BOXへ再帰する, c曲リストノード4.list子リスト, c曲リストノード4 );\r
+                                               this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, c曲リストノード.list子リスト, c曲リストノード );\r
                                        }\r
                                }\r
                                //-----------------------------\r
@@ -514,7 +627,7 @@ namespace DTXMania
                                //-----------------------------\r
                                else\r
                                {\r
-                                       this.t曲を検索してリストを作成する( info6.FullName + @"\", b子BOXへ再帰する, listノードリスト, node親 );\r
+                                       this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, listノードリスト, node親 );\r
                                }\r
                                //-----------------------------\r
                                #endregion\r
@@ -535,6 +648,8 @@ namespace DTXMania
                        {\r
                                while( enumerator.MoveNext() )\r
                                {\r
+                                       SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
+\r
                                        C曲リストノード node = enumerator.Current;\r
                                        if( node.eノード種別 == C曲リストノード.Eノード種別.BOX )\r
                                        {\r
@@ -551,66 +666,74 @@ namespace DTXMania
                                                                {\r
                                                                        match = delegate( Cスコア sc )\r
                                                                        {\r
-                                                                               return ( ( sc.ファイル情報.ファイルの絶対パス.Equals( node.arスコア[ lv ].ファイル情報.ファイルの絶対パス )\r
+                                                                               return\r
+                                                                                       (\r
+                                                                                       ( sc.ファイル情報.ファイルの絶対パス.Equals( node.arスコア[ lv ].ファイル情報.ファイルの絶対パス )\r
                                                                                        && sc.ファイル情報.ファイルサイズ.Equals( node.arスコア[ lv ].ファイル情報.ファイルサイズ ) )\r
                                                                                        && ( sc.ファイル情報.最終更新日時.Equals( node.arスコア[ lv ].ファイル情報.最終更新日時 )\r
                                                                                        && sc.ScoreIni情報.ファイルサイズ.Equals( node.arスコア[ lv ].ScoreIni情報.ファイルサイズ ) ) )\r
                                                                                        && sc.ScoreIni情報.最終更新日時.Equals( node.arスコア[ lv ].ScoreIni情報.最終更新日時 );\r
                                                                        };\r
                                                                }\r
-                                                               int num = this.listSongsDB.FindIndex( match );\r
-                                                               if( num == -1 )\r
+                                                               int nMatched = this.listSongsDB.FindIndex( match );\r
+                                                               if( nMatched == -1 )\r
                                                                {\r
-                                                                       if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
+//Trace.TraceInformation( "songs.db に存在しません。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );\r
+                                                                       if ( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                                                        {\r
-                                                                               Trace.TraceInformation( "songs.db に存在しません。({0})", new object[] { node.arスコア[ lv ].ファイル情報.ファイルの絶対パス } );\r
+                                                                               Trace.TraceInformation( "songs.db に存在しません。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );\r
                                                                        }\r
                                                                }\r
                                                                else\r
                                                                {\r
-                                                                       node.arスコア[ lv ].譜面情報 = this.listSongsDB[ num ].譜面情報;\r
+                                                                       node.arスコア[ lv ].譜面情報 = this.listSongsDB[ nMatched ].譜面情報;\r
                                                                        node.arスコア[ lv ].bSongDBにキャッシュがあった = true;\r
                                                                        if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                                                        {\r
-                                                                               Trace.TraceInformation( "songs.db から転記しました。({0})", new object[] { node.arスコア[ lv ].ファイル情報.ファイルの絶対パス } );\r
+                                                                               Trace.TraceInformation( "songs.db から転記しました。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );\r
                                                                        }\r
                                                                        this.nスコアキャッシュから反映できたスコア数++;\r
-                                                                       if( node.arスコア[ lv ].ScoreIni情報.最終更新日時 != this.listSongsDB[ num ].ScoreIni情報.最終更新日時 )\r
+                                                                       if( node.arスコア[ lv ].ScoreIni情報.最終更新日時 != this.listSongsDB[ nMatched ].ScoreIni情報.最終更新日時 )\r
                                                                        {\r
-                                                                               string str = node.arスコア[ lv ].ファイル情報.ファイルの絶対パス + ".score.ini";\r
+                                                                               string strFileNameScoreIni = node.arスコア[ lv ].ファイル情報.ファイルの絶対パス + ".score.ini";\r
                                                                                try\r
                                                                                {\r
-                                                                                       CScoreIni ini = new CScoreIni( str );\r
-                                                                                       ini.t全演奏記録セクションの整合性をチェックし不整合があればリセットする();\r
+                                                                                       CScoreIni scoreIni = new CScoreIni( strFileNameScoreIni );\r
+                                                                                       scoreIni.t全演奏記録セクションの整合性をチェックし不整合があればリセットする();\r
                                                                                        for( int i = 0; i < 3; i++ )\r
                                                                                        {\r
-                                                                                               int num3 = ( i * 2 ) + 1;\r
-                                                                                               if( ( ini.stセクション[ num3 ].b演奏にMIDI入力を使用した || ini.stセクション[ num3 ].b演奏にキーボードを使用した ) || ( ini.stセクション[ num3 ].b演奏にジョイパッドを使用した || ini.stセクション[ num3 ].b演奏にマウスを使用した ) )\r
+                                                                                               int nSectionHiSkill = ( i * 2 ) + 1;\r
+                                                                                               if(    scoreIni.stセクション[ nSectionHiSkill ].b演奏にMIDI入力を使用した\r
+                                                                                                       || scoreIni.stセクション[ nSectionHiSkill ].b演奏にキーボードを使用した\r
+                                                                                                       || scoreIni.stセクション[ nSectionHiSkill ].b演奏にジョイパッドを使用した\r
+                                                                                                       || scoreIni.stセクション[ nSectionHiSkill ].b演奏にマウスを使用した )\r
                                                                                                {\r
-                                                                                                       node.arスコア[ lv ].譜面情報.最大ランク[ i ] = CScoreIni.tランク値を計算して返す( ini.stセクション[ num3 ] );\r
+                                                                                                       node.arスコア[ lv ].譜面情報.最大ランク[ i ] = \r
+                                                                                                               (scoreIni.stファイル.BestRank[i] != (int)CScoreIni.ERANK.UNKNOWN)?\r
+                                                                                                               (int)scoreIni.stファイル.BestRank[i] : CScoreIni.tランク値を計算して返す( scoreIni.stセクション[ nSectionHiSkill ] );\r
                                                                                                }\r
                                                                                                else\r
                                                                                                {\r
-                                                                                                       node.arスコア[ lv ].譜面情報.最大ランク[ i ] = 0x63;\r
+                                                                                                       node.arスコア[ lv ].譜面情報.最大ランク[ i ] = (int)CScoreIni.ERANK.UNKNOWN;\r
                                                                                                }\r
-                                                                                               node.arスコア[ lv ].譜面情報.最大スキル[ i ] = ini.stセクション[ num3 ].db演奏型スキル値;\r
-                                                                                               node.arスコア[ lv ].譜面情報.フルコンボ[ i ] = ini.stセクション[ num3 ].bフルコンボである;\r
+                                                                                               node.arスコア[ lv ].譜面情報.最大スキル[ i ] = scoreIni.stセクション[ nSectionHiSkill ].db演奏型スキル値;\r
+                                                                                               node.arスコア[ lv ].譜面情報.フルコンボ[ i ] = scoreIni.stセクション[ nSectionHiSkill ].bフルコンボである;\r
                                                                                        }\r
-                                                                                       node.arスコア[ lv ].譜面情報.演奏回数.Drums = ini.stファイル.PlayCountDrums;\r
-                                                                                       node.arスコア[ lv ].譜面情報.演奏回数.Guitar = ini.stファイル.PlayCountGuitar;\r
-                                                                                       node.arスコア[ lv ].譜面情報.演奏回数.Bass = ini.stファイル.PlayCountBass;\r
+                                                                                       node.arスコア[ lv ].譜面情報.演奏回数.Drums = scoreIni.stファイル.PlayCountDrums;\r
+                                                                                       node.arスコア[ lv ].譜面情報.演奏回数.Guitar = scoreIni.stファイル.PlayCountGuitar;\r
+                                                                                       node.arスコア[ lv ].譜面情報.演奏回数.Bass = scoreIni.stファイル.PlayCountBass;\r
                                                                                        for( int j = 0; j < 5; j++ )\r
                                                                                        {\r
-                                                                                               node.arスコア[ lv ].譜面情報.演奏履歴[ j ] = ini.stファイル.History[ j ];\r
+                                                                                               node.arスコア[ lv ].譜面情報.演奏履歴[ j ] = scoreIni.stファイル.History[ j ];\r
                                                                                        }\r
                                                                                        if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                                                                        {\r
-                                                                                               Trace.TraceInformation( "演奏記録ファイルから HiSkill 情報と演奏履歴を取得しました。({0})", new object[] { str } );\r
+                                                                                               Trace.TraceInformation( "演奏記録ファイルから HiSkill 情報と演奏履歴を取得しました。({0})", strFileNameScoreIni );\r
                                                                                        }\r
                                                                                }\r
                                                                                catch\r
                                                                                {\r
-                                                                                       Trace.TraceError( "演奏記録ファイルの読み込みに失敗しました。({0})", new object[] { str } );\r
+                                                                                       Trace.TraceError( "演奏記録ファイルの読み込みに失敗しました。({0})", strFileNameScoreIni );\r
                                                                                }\r
                                                                        }\r
                                                                }\r
@@ -659,6 +782,10 @@ namespace DTXMania
                        cスコア.譜面情報.演奏履歴.行5 = br.ReadString();\r
                        cスコア.譜面情報.レベルを非表示にする = br.ReadBoolean();\r
                        cスコア.譜面情報.曲種別 = (CDTX.E種別) br.ReadInt32();\r
+                       cスコア.譜面情報.Bpm = br.ReadDouble();\r
+                       cスコア.譜面情報.Duration = br.ReadInt32();\r
+\r
+//Debug.WriteLine( "songs.db: " + cスコア.ファイル情報.ファイルの絶対パス );\r
                        return cスコア;\r
                }\r
                //-----------------\r
@@ -674,16 +801,21 @@ namespace DTXMania
                {\r
                        foreach( C曲リストノード c曲リストノード in ノードリスト )\r
                        {\r
+                               SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
+\r
                                if( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.BOX )\r
                                {\r
                                        this.tSongsDBになかった曲をファイルから読み込んで反映する( c曲リストノード.list子リスト );\r
                                }\r
-                               else if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE ) || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )\r
+                               else if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE )\r
+                                         || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )\r
                                {\r
                                        for( int i = 0; i < 5; i++ )\r
                                        {\r
                                                if( ( c曲リストノード.arスコア[ i ] != null ) && !c曲リストノード.arスコア[ i ].bSongDBにキャッシュがあった )\r
                                                {\r
+                                                       #region [ DTX ファイルのヘッダだけ読み込み、Cスコア.譜面情報 を設定する ]\r
+                                                       //-----------------\r
                                                        string path = c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス;\r
                                                        if( File.Exists( path ) )\r
                                                        {\r
@@ -703,27 +835,36 @@ namespace DTXMania
                                                                        c曲リストノード.arスコア[ i ].譜面情報.レベル.Bass = cdtx.LEVEL.Bass;\r
                                                                        c曲リストノード.arスコア[ i ].譜面情報.レベルを非表示にする = cdtx.HIDDENLEVEL;\r
                                                                        c曲リストノード.arスコア[ i ].譜面情報.曲種別 = cdtx.e種別;\r
+                                                                       c曲リストノード.arスコア[ i ].譜面情報.Bpm = cdtx.BPM;\r
+                                                                       c曲リストノード.arスコア[ i ].譜面情報.Duration = 0;      //  (cdtx.listChip == null)? 0 : cdtx.listChip[ cdtx.listChip.Count - 1 ].n発声時刻ms;\r
                                                                        this.nファイルから反映できたスコア数++;\r
                                                                        cdtx.On非活性化();\r
+//Debug.WriteLine( "★" + this.nファイルから反映できたスコア数 + " " + c曲リストノード.arスコア[ i ].譜面情報.タイトル );\r
+                                                                       #region [ 曲検索ログ出力 ]\r
+                                                                       //-----------------\r
                                                                        if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                                                        {\r
-                                                                               StringBuilder builder = new StringBuilder( 0x400 );\r
-                                                                               builder.Append( string.Format( "曲データファイルから譜面情報を転記しました。({0})", path ) );\r
-                                                                               builder.Append( "(title=" + c曲リストノード.arスコア[ i ].譜面情報.タイトル );\r
-                                                                               builder.Append( ", artist=" + c曲リストノード.arスコア[ i ].譜面情報.アーティスト名 );\r
-                                                                               builder.Append( ", comment=" + c曲リストノード.arスコア[ i ].譜面情報.コメント );\r
-                                                                               builder.Append( ", genre=" + c曲リストノード.arスコア[ i ].譜面情報.ジャンル );\r
-                                                                               builder.Append( ", preimage=" + c曲リストノード.arスコア[ i ].譜面情報.Preimage );\r
-                                                                               builder.Append( ", premovie=" + c曲リストノード.arスコア[ i ].譜面情報.Premovie );\r
-                                                                               builder.Append( ", presound=" + c曲リストノード.arスコア[ i ].譜面情報.Presound );\r
-                                                                               builder.Append( ", background=" + c曲リストノード.arスコア[ i ].譜面情報.Backgound );\r
-                                                                               builder.Append( ", lvDr=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Drums );\r
-                                                                               builder.Append( ", lvGt=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Guitar );\r
-                                                                               builder.Append( ", lvBs=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Bass );\r
-                                                                               builder.Append( ", lvHide=" + c曲リストノード.arスコア[ i ].譜面情報.レベルを非表示にする );\r
-                                                                               builder.Append( ", type=" + c曲リストノード.arスコア[ i ].譜面情報.曲種別 );\r
-                                                                               Trace.TraceInformation( builder.ToString() );\r
+                                                                               StringBuilder sb = new StringBuilder( 0x400 );\r
+                                                                               sb.Append( string.Format( "曲データファイルから譜面情報を転記しました。({0})", path ) );\r
+                                                                               sb.Append( "(title=" + c曲リストノード.arスコア[ i ].譜面情報.タイトル );\r
+                                                                               sb.Append( ", artist=" + c曲リストノード.arスコア[ i ].譜面情報.アーティスト名 );\r
+                                                                               sb.Append( ", comment=" + c曲リストノード.arスコア[ i ].譜面情報.コメント );\r
+                                                                               sb.Append( ", genre=" + c曲リストノード.arスコア[ i ].譜面情報.ジャンル );\r
+                                                                               sb.Append( ", preimage=" + c曲リストノード.arスコア[ i ].譜面情報.Preimage );\r
+                                                                               sb.Append( ", premovie=" + c曲リストノード.arスコア[ i ].譜面情報.Premovie );\r
+                                                                               sb.Append( ", presound=" + c曲リストノード.arスコア[ i ].譜面情報.Presound );\r
+                                                                               sb.Append( ", background=" + c曲リストノード.arスコア[ i ].譜面情報.Backgound );\r
+                                                                               sb.Append( ", lvDr=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Drums );\r
+                                                                               sb.Append( ", lvGt=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Guitar );\r
+                                                                               sb.Append( ", lvBs=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Bass );\r
+                                                                               sb.Append( ", lvHide=" + c曲リストノード.arスコア[ i ].譜面情報.レベルを非表示にする );\r
+                                                                               sb.Append( ", type=" + c曲リストノード.arスコア[ i ].譜面情報.曲種別 );\r
+                                                                               sb.Append( ", bpm=" + c曲リストノード.arスコア[ i ].譜面情報.Bpm );\r
+                                                                       //      sb.Append( ", duration=" + c曲リストノード.arスコア[ i ].譜面情報.Duration );\r
+                                                                               Trace.TraceInformation( sb.ToString() );\r
                                                                        }\r
+                                                                       //-----------------\r
+                                                                       #endregion\r
                                                                }\r
                                                                catch( Exception exception )\r
                                                                {\r
@@ -731,43 +872,17 @@ namespace DTXMania
                                                                        c曲リストノード.arスコア[ i ] = null;\r
                                                                        c曲リストノード.nスコア数--;\r
                                                                        this.n検索されたスコア数--;\r
-                                                                       Trace.TraceError( "曲データファイルの読み込みに失敗しました。({0})", new object[] { path } );\r
-                                                               }\r
-                                                       }\r
-                                                       string str2 = c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス + ".score.ini";\r
-                                                       if( File.Exists( str2 ) )\r
-                                                       {\r
-                                                               try\r
-                                                               {\r
-                                                                       CScoreIni ini = new CScoreIni( str2 );\r
-                                                                       ini.t全演奏記録セクションの整合性をチェックし不整合があればリセットする();\r
-                                                                       for( int j = 0; j < 3; j++ )\r
-                                                                       {\r
-                                                                               int num3 = ( j * 2 ) + 1;\r
-                                                                               if( ( ini.stセクション[ num3 ].b演奏にMIDI入力を使用した || ini.stセクション[ num3 ].b演奏にキーボードを使用した ) || ( ini.stセクション[ num3 ].b演奏にジョイパッドを使用した || ini.stセクション[ num3 ].b演奏にマウスを使用した ) )\r
-                                                                               {\r
-                                                                                       c曲リストノード.arスコア[ i ].譜面情報.最大ランク[ j ] = CScoreIni.tランク値を計算して返す( ini.stセクション[ num3 ].n全チップ数, ini.stセクション[ num3 ].nPerfect数, ini.stセクション[ num3 ].nGreat数, ini.stセクション[ num3 ].nGood数, ini.stセクション[ num3 ].nPoor数, ini.stセクション[ num3 ].nMiss数 );\r
-                                                                               }\r
-                                                                               else\r
-                                                                               {\r
-                                                                                       c曲リストノード.arスコア[ i ].譜面情報.最大ランク[ j ] = 0x63;\r
-                                                                               }\r
-                                                                               c曲リストノード.arスコア[ i ].譜面情報.最大スキル[ j ] = ini.stセクション[ num3 ].db演奏型スキル値;\r
-                                                                               c曲リストノード.arスコア[ i ].譜面情報.フルコンボ[ j ] = ini.stセクション[ num3 ].bフルコンボである;\r
-                                                                       }\r
-                                                                       c曲リストノード.arスコア[ i ].譜面情報.演奏回数.Drums = ini.stファイル.PlayCountDrums;\r
-                                                                       c曲リストノード.arスコア[ i ].譜面情報.演奏回数.Guitar = ini.stファイル.PlayCountGuitar;\r
-                                                                       c曲リストノード.arスコア[ i ].譜面情報.演奏回数.Bass = ini.stファイル.PlayCountBass;\r
-                                                                       for( int k = 0; k < 5; k++ )\r
-                                                                       {\r
-                                                                               c曲リストノード.arスコア[ i ].譜面情報.演奏履歴[ k ] = ini.stファイル.History[ k ];\r
-                                                                       }\r
-                                                               }\r
-                                                               catch\r
-                                                               {\r
-                                                                       Trace.TraceError( "演奏記録ファイルの読み込みに失敗しました。[{0}]", new object[] { str2 } );\r
+                                                                       Trace.TraceError( "曲データファイルの読み込みに失敗しました。({0})", path );\r
                                                                }\r
                                                        }\r
+                                                       //-----------------\r
+                                                       #endregion\r
+\r
+                                                       #region [ 対応する .score.ini が存在していれば読み込み、Cスコア.譜面情報 に追加設定する ]\r
+                                                       //-----------------\r
+                                                       this.tScoreIniを読み込んで譜面情報を設定する( c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス + ".score.ini", ref c曲リストノード.arスコア[ i ] );\r
+                                                       //-----------------\r
+                                                       #endregion\r
                                                }\r
                                        }\r
                                }\r
@@ -779,7 +894,33 @@ namespace DTXMania
                //-----------------\r
                public void t曲リストへ後処理を適用する()\r
                {\r
+                       listStrBoxDefSkinSubfolderFullName = new List<string>();\r
+                       if ( CDTXMania.Skin.strBoxDefSkinSubfolders != null )\r
+                       {\r
+                               foreach ( string b in CDTXMania.Skin.strBoxDefSkinSubfolders )\r
+                               {\r
+                                       listStrBoxDefSkinSubfolderFullName.Add( b );\r
+                               }\r
+                       }\r
+\r
                        this.t曲リストへ後処理を適用する( this.list曲ルート );\r
+\r
+                       #region [ skin名で比較して、systemスキンとboxdefスキンに重複があれば、boxdefスキン側を削除する ]\r
+                       string[] systemSkinNames = CSkin.GetSkinName( CDTXMania.Skin.strSystemSkinSubfolders );\r
+                       List<string> l = new List<string>( listStrBoxDefSkinSubfolderFullName );\r
+                       foreach ( string boxdefSkinSubfolderFullName in l )\r
+                       {\r
+                               if ( Array.BinarySearch( systemSkinNames,\r
+                                       CSkin.GetSkinName( boxdefSkinSubfolderFullName ),\r
+                                       StringComparer.InvariantCultureIgnoreCase ) >= 0 )\r
+                               {\r
+                                       listStrBoxDefSkinSubfolderFullName.Remove( boxdefSkinSubfolderFullName );\r
+                               }\r
+                       }\r
+                       #endregion\r
+                       string[] ba = listStrBoxDefSkinSubfolderFullName.ToArray();\r
+                       Array.Sort( ba );\r
+                       CDTXMania.Skin.strBoxDefSkinSubfolders = ba;\r
                }\r
                private void t曲リストへ後処理を適用する( List<C曲リストノード> ノードリスト )\r
                {\r
@@ -787,39 +928,43 @@ namespace DTXMania
                        //-----------------------------\r
                        if( ノードリスト.Count > 0 )\r
                        {\r
-                               C曲リストノード item = new C曲リストノード();\r
-                               item.eノード種別 = C曲リストノード.Eノード種別.RANDOM;\r
-                               item.strタイトル = "< RANDOM SELECT >";\r
-                               item.nスコア数 = 5;\r
-                               item.r親ノード = ノードリスト[ 0 ].r親ノード;\r
+                               C曲リストノード itemRandom = new C曲リストノード();\r
+                               itemRandom.eノード種別 = C曲リストノード.Eノード種別.RANDOM;\r
+                               itemRandom.strタイトル = "< RANDOM SELECT >";\r
+                               itemRandom.nスコア数 = 5;\r
+                               itemRandom.r親ノード = ノードリスト[ 0 ].r親ノード;\r
+\r
+                               itemRandom.strBreadcrumbs = ( itemRandom.r親ノード == null ) ?\r
+                                       itemRandom.strタイトル :  itemRandom.r親ノード.strBreadcrumbs + " > " + itemRandom.strタイトル;\r
+\r
                                for( int i = 0; i < 5; i++ )\r
                                {\r
-                                       item.arスコア[ i ] = new Cスコア();\r
-                                       item.arスコア[ i ].譜面情報.タイトル = string.Format( "< RANDOM SELECT Lv.{0} >", i + 1 );\r
-                                       item.arスコア[i].譜面情報.コメント =\r
+                                       itemRandom.arスコア[ i ] = new Cスコア();\r
+                                       itemRandom.arスコア[ i ].譜面情報.タイトル = string.Format( "< RANDOM SELECT Lv.{0} >", i + 1 );\r
+                                       itemRandom.arスコア[i].譜面情報.コメント =\r
                                                 (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?\r
                                                 string.Format("難易度レベル {0} 付近の曲をランダムに選択します。難易度レベルを持たない曲も選択候補となります。", i + 1) :\r
                                                 string.Format("Random select from the songs which has the level about L{0}. Non-leveled songs may also selected.", i + 1);\r
-                                       item.ar難易度ラベル[ i ] = string.Format( "L{0}", i + 1 );\r
+                                       itemRandom.ar難易度ラベル[ i ] = string.Format( "L{0}", i + 1 );\r
                                }\r
-                               ノードリスト.Add( item );\r
+                               ノードリスト.Add( itemRandom );\r
 \r
                                #region [ ログ出力 ]\r
                                //-----------------------------\r
                                if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                {\r
-                                       StringBuilder builder = new StringBuilder( 0x100 );\r
-                                       builder.Append( string.Format( "nID#{0:D3}", item.nID ) );\r
-                                       if( item.r親ノード != null )\r
+                                       StringBuilder sb = new StringBuilder( 0x100 );\r
+                                       sb.Append( string.Format( "nID#{0:D3}", itemRandom.nID ) );\r
+                                       if( itemRandom.r親ノード != null )\r
                                        {\r
-                                               builder.Append( string.Format( "(in#{0:D3}):", item.r親ノード.nID ) );\r
+                                               sb.Append( string.Format( "(in#{0:D3}):", itemRandom.r親ノード.nID ) );\r
                                        }\r
                                        else\r
                                        {\r
-                                               builder.Append( "(onRoot):" );\r
+                                               sb.Append( "(onRoot):" );\r
                                        }\r
-                                       builder.Append( " RANDOM" );\r
-                                       Trace.TraceInformation( builder.ToString() );\r
+                                       sb.Append( " RANDOM" );\r
+                                       Trace.TraceInformation( sb.ToString() );\r
                                }\r
                                //-----------------------------\r
                                #endregion\r
@@ -828,47 +973,61 @@ namespace DTXMania
                        #endregion\r
 \r
                        // すべてのノードについて…\r
-                       foreach( C曲リストノード c曲リストノード2 in ノードリスト )\r
+                       foreach( C曲リストノード c曲リストノード in ノードリスト )\r
                        {\r
+                               SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
+\r
                                #region [ BOXノードなら子リストに <<BACK を入れ、子リストに後処理を適用する ]\r
                                //-----------------------------\r
-                               if( c曲リストノード2.eノード種別 == C曲リストノード.Eノード種別.BOX )\r
+                               if( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.BOX )\r
                                {\r
-                                       C曲リストノード c曲リストノード3 = new C曲リストノード();\r
-                                       c曲リストノード3.eノード種別 = C曲リストノード.Eノード種別.BACKBOX;\r
-                                       c曲リストノード3.strタイトル = "<< BACK";\r
-                                       c曲リストノード3.nスコア数 = 1;\r
-                                       c曲リストノード3.r親ノード = c曲リストノード2;\r
-                                       c曲リストノード3.arスコア[ 0 ] = new Cスコア();\r
-                                       c曲リストノード3.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = "";\r
-                                       c曲リストノード3.arスコア[ 0 ].譜面情報.タイトル = c曲リストノード3.strタイトル;\r
-                                       c曲リストノード3.arスコア[ 0 ].譜面情報.コメント =\r
+                                       C曲リストノード itemBack = new C曲リストノード();\r
+                                       itemBack.eノード種別 = C曲リストノード.Eノード種別.BACKBOX;\r
+                                       itemBack.strタイトル = "<< BACK";\r
+                                       itemBack.nスコア数 = 1;\r
+                                       itemBack.r親ノード = c曲リストノード;\r
+\r
+                                       itemBack.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
+                                               "" : c曲リストノード.r親ノード.strSkinPath;\r
+\r
+                                       if ( itemBack.strSkinPath != "" && !listStrBoxDefSkinSubfolderFullName.Contains( itemBack.strSkinPath ) )\r
+                                       {\r
+                                               listStrBoxDefSkinSubfolderFullName.Add( itemBack.strSkinPath );\r
+                                       }\r
+\r
+                                       itemBack.strBreadcrumbs = ( itemBack.r親ノード == null ) ?\r
+                                               itemBack.strタイトル : itemBack.r親ノード.strBreadcrumbs + " > " + itemBack.strタイトル;\r
+\r
+                                       itemBack.arスコア[ 0 ] = new Cスコア();\r
+                                       itemBack.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = "";\r
+                                       itemBack.arスコア[ 0 ].譜面情報.タイトル = itemBack.strタイトル;\r
+                                       itemBack.arスコア[ 0 ].譜面情報.コメント =\r
                                                (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?\r
                                                "BOX を出ます。" :\r
                                                "Exit from the BOX.";\r
-                                       c曲リストノード2.list子リスト.Insert( 0, c曲リストノード3 );\r
+                                       c曲リストノード.list子リスト.Insert( 0, itemBack );\r
 \r
                                        #region [ ログ出力 ]\r
                                        //-----------------------------\r
                                        if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
                                        {\r
-                                               StringBuilder builder2 = new StringBuilder( 0x100 );\r
-                                               builder2.Append( string.Format( "nID#{0:D3}", c曲リストノード3.nID ) );\r
-                                               if( c曲リストノード3.r親ノード != null )\r
+                                               StringBuilder sb = new StringBuilder( 0x100 );\r
+                                               sb.Append( string.Format( "nID#{0:D3}", itemBack.nID ) );\r
+                                               if( itemBack.r親ノード != null )\r
                                                {\r
-                                                       builder2.Append( string.Format( "(in#{0:D3}):", c曲リストノード3.r親ノード.nID ) );\r
+                                                       sb.Append( string.Format( "(in#{0:D3}):", itemBack.r親ノード.nID ) );\r
                                                }\r
                                                else\r
                                                {\r
-                                                       builder2.Append( "(onRoot):" );\r
+                                                       sb.Append( "(onRoot):" );\r
                                                }\r
-                                               builder2.Append( " BACKBOX" );\r
-                                               Trace.TraceInformation( builder2.ToString() );\r
+                                               sb.Append( " BACKBOX" );\r
+                                               Trace.TraceInformation( sb.ToString() );\r
                                        }\r
                                        //-----------------------------\r
                                        #endregion\r
 \r
-                                       this.t曲リストへ後処理を適用する( c曲リストノード2.list子リスト );\r
+                                       this.t曲リストへ後処理を適用する( c曲リストノード.list子リスト );\r
                                        continue;\r
                                }\r
                                //-----------------------------\r
@@ -876,16 +1035,16 @@ namespace DTXMania
 \r
                                #region [ ノードにタイトルがないなら、最初に見つけたスコアのタイトルを設定する ]\r
                                //-----------------------------\r
-                               if( string.IsNullOrEmpty( c曲リストノード2.strタイトル ) )\r
+                               if( string.IsNullOrEmpty( c曲リストノード.strタイトル ) )\r
                                {\r
                                        for( int j = 0; j < 5; j++ )\r
                                        {\r
-                                               if( ( c曲リストノード2.arスコア[ j ] != null ) && !string.IsNullOrEmpty( c曲リストノード2.arスコア[ j ].譜面情報.タイトル ) )\r
+                                               if( ( c曲リストノード.arスコア[ j ] != null ) && !string.IsNullOrEmpty( c曲リストノード.arスコア[ j ].譜面情報.タイトル ) )\r
                                                {\r
-                                                       c曲リストノード2.strタイトル = c曲リストノード2.arスコア[ j ].譜面情報.タイトル;\r
+                                                       c曲リストノード.strタイトル = c曲リストノード.arスコア[ j ].譜面情報.タイトル;\r
 \r
                                                        if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
-                                                               Trace.TraceInformation( "タイトルを設定しました。(nID#{0:D3}, title={1})", new object[] { c曲リストノード2.nID, c曲リストノード2.strタイトル } );\r
+                                                               Trace.TraceInformation( "タイトルを設定しました。(nID#{0:D3}, title={1})", c曲リストノード.nID, c曲リストノード.strタイトル );\r
 \r
                                                        break;\r
                                                }\r
@@ -911,7 +1070,7 @@ namespace DTXMania
                        try\r
                        {\r
                                BinaryWriter bw = new BinaryWriter( new FileStream( SongsDBファイル名, FileMode.Create, FileAccess.Write ) );\r
-                               bw.Write( "SongsDB2" );\r
+                               bw.Write( SONGSDB_VERSION );\r
                                this.tSongsDBにリストを1つ出力する( bw, this.list曲ルート );\r
                                bw.Close();\r
                        }\r
@@ -924,6 +1083,12 @@ namespace DTXMania
                {\r
                        for( int i = 0; i < 5; i++ )\r
                        {\r
+                               // ここではsuspendに応じないようにしておく(深い意味はない。ファイルの書き込みオープン状態を長時間維持したくないだけ)\r
+                               //if ( this.bIsSuspending )             // #27060 中断要求があったら、解除要求が来るまで待機\r
+                               //{\r
+                               //      autoReset.WaitOne();\r
+                               //}\r
+\r
                                if( node.arスコア[ i ] != null )\r
                                {\r
                                        bw.Write( node.arスコア[ i ].ファイル情報.ファイルの絶対パス );\r
@@ -962,6 +1127,8 @@ namespace DTXMania
                                        bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行5 );\r
                                        bw.Write( node.arスコア[ i ].譜面情報.レベルを非表示にする );\r
                                        bw.Write( (int) node.arスコア[ i ].譜面情報.曲種別 );\r
+                                       bw.Write( node.arスコア[ i ].譜面情報.Bpm );\r
+                                       bw.Write( node.arスコア[ i ].譜面情報.Duration );\r
                                        this.nSongsDBへ出力できたスコア数++;\r
                                }\r
                        }\r
@@ -970,7 +1137,8 @@ namespace DTXMania
                {\r
                        foreach( C曲リストノード c曲リストノード in list )\r
                        {\r
-                               if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE ) || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )\r
+                               if(    ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE )\r
+                                       || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )\r
                                {\r
                                        this.tSongsDBにノードを1つ出力する( bw, c曲リストノード );\r
                                }\r
@@ -982,14 +1150,15 @@ namespace DTXMania
                }\r
                //-----------------\r
                #endregion\r
-\r
+               \r
                #region [ 曲リストソート ]\r
                //-----------------\r
                public void t曲リストのソート1_絶対パス順( List<C曲リストノード> ノードリスト )\r
                {\r
                        ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
                        {\r
-                               if( n1 == n2 )\r
+                               #region [ 共通処理 ]\r
+                               if ( n1 == n2 )\r
                                {\r
                                        return 0;\r
                                }\r
@@ -1002,6 +1171,7 @@ namespace DTXMania
                                {\r
                                        return n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
                                }\r
+                               #endregion\r
                                string str = "";\r
                                if( string.IsNullOrEmpty( n1.pathSetDefの絶対パス ) )\r
                                {\r
@@ -1052,7 +1222,7 @@ namespace DTXMania
                                }\r
                        }\r
                }\r
-               public void t曲リストのソート2_タイトル順( List<C曲リストノード> ノードリスト )\r
+               public void t曲リストのソート2_タイトル順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
                {\r
                        ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
                        {\r
@@ -1063,67 +1233,441 @@ namespace DTXMania
                                int num = this.t比較0_共通( n1, n2 );\r
                                if( num != 0 )\r
                                {\r
-                                       return num;\r
+                                       return order * num;\r
                                }\r
-                               return n1.strタイトル.CompareTo( n2.strタイトル );\r
+                               return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
                        } );\r
-                       foreach( C曲リストノード c曲リストノード in ノードリスト )\r
-                       {\r
-                               if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )\r
-                               {\r
-                                       this.t曲リストのソート2_タイトル順( c曲リストノード.list子リスト );\r
-                               }\r
-                       }\r
+//                     foreach( C曲リストノード c曲リストノード in ノードリスト )\r
+//                     {\r
+//                             if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )\r
+//                             {\r
+//                                     this.t曲リストのソート2_タイトル順( c曲リストノード.list子リスト, part, order );\r
+//                             }\r
+//                     }\r
                }\r
-               public void t曲リストのソート3_演奏回数の多い順( List<C曲リストノード> ノードリスト, E楽器パート part )\r
+               /// <summary>\r
+               /// \r
+               /// </summary>\r
+               /// <param name="ノードリスト"></param>\r
+               /// <param name="part"></param>\r
+               /// <param name="order">1=Ascend -1=Descend</param>\r
+               public void t曲リストのソート3_演奏回数の多い順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
                {\r
-                       if( part != E楽器パート.UNKNOWN )\r
+                       order = -order;\r
+                       int nL12345 = (int) p[ 0 ];\r
+                       if ( part != E楽器パート.UNKNOWN )\r
                        {\r
                                ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
                                {\r
-                                       if( n1 == n2 )\r
+                                       #region [ 共通処理 ]\r
+                                       if ( n1 == n2 )\r
                                        {\r
                                                return 0;\r
                                        }\r
-                                       int num = 0;\r
-                                       num = this.t比較0_共通( n1, n2 );\r
+                                       int num = this.t比較0_共通( n1, n2 );\r
                                        if( num != 0 )\r
                                        {\r
-                                               return num;\r
+                                               return order * num;\r
                                        }\r
                                        if( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
                                        {\r
-                                               return n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
+                                               return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
                                        }\r
-                                       int num2 = 0;\r
-                                       int num3 = 0;\r
-                                       for( int i = 0; i < 5; i++ )\r
-                                       {\r
-                                               if( n1.arスコア[ i ] != null )\r
+                                       #endregion\r
+                                       int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;\r
+//                                     for( int i = 0; i < 5; i++ )\r
+//                                     {\r
+                                               if( n1.arスコア[ nL12345 ] != null )\r
                                                {\r
-                                                       num2 += n1.arスコア[ i ].譜面情報.演奏回数[ (int) part ];\r
+                                                       nSumPlayCountN1 += n1.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];\r
                                                }\r
-                                               if( n2.arスコア[ i ] != null )\r
+                                               if( n2.arスコア[ nL12345 ] != null )\r
                                                {\r
-                                                       num3 += n2.arスコア[ i ].譜面情報.演奏回数[ (int) part ];\r
+                                                       nSumPlayCountN2 += n2.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];\r
                                                }\r
-                                       }\r
-                                       num = num3 - num2;\r
+//                                     }\r
+                                       num = nSumPlayCountN2 - nSumPlayCountN1;\r
                                        if( num != 0 )\r
                                        {\r
-                                               return num;\r
+                                               return order * num;\r
+                                       }\r
+                                       return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
+                               } );\r
+                               foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
+                               {\r
+                                       int nSumPlayCountN1 = 0;\r
+//                                     for ( int i = 0; i < 5; i++ )\r
+//                                     {\r
+                                               if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
+                                               {\r
+                                                       nSumPlayCountN1 += c曲リストノード.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];\r
+                                               }\r
+//                                     }\r
+// Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
+                               }\r
+\r
+//                             foreach( C曲リストノード c曲リストノード in ノードリスト )\r
+//                             {\r
+//                                     if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )\r
+//                                     {\r
+//                                             this.t曲リストのソート3_演奏回数の多い順( c曲リストノード.list子リスト, part );\r
+//                                     }\r
+//                             }\r
+                       }\r
+               }\r
+               public void t曲リストのソート4_LEVEL順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
+               {\r
+                       order = -order;\r
+                       int nL12345 = (int)p[ 0 ];\r
+                       if ( part != E楽器パート.UNKNOWN )\r
+                       {\r
+                               ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
+                               {\r
+                                       #region [ 共通処理 ]\r
+                                       if ( n1 == n2 )\r
+                                       {\r
+                                               return 0;\r
+                                       }\r
+                                       int num = this.t比較0_共通( n1, n2 );\r
+                                       if ( num != 0 )\r
+                                       {\r
+                                               return order * num;\r
                                        }\r
-                                       return n1.strタイトル.CompareTo( n2.strタイトル );\r
+                                       if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
+                                       {\r
+                                               return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
+                                       }\r
+                                       #endregion\r
+                                       int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;\r
+                                       if ( n1.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];\r
+                                       }\r
+                                       if ( n2.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];\r
+                                       }\r
+                                       num = nSumPlayCountN2 - nSumPlayCountN1;\r
+                                       if ( num != 0 )\r
+                                       {\r
+                                               return order * num;\r
+                                       }\r
+                                       return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
                                } );\r
-                               foreach( C曲リストノード c曲リストノード in ノードリスト )\r
+                               foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
                                {\r
-                                       if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )\r
+                                       int nSumPlayCountN1 = 0;\r
+                                       if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
                                        {\r
-                                               this.t曲リストのソート3_演奏回数の多い順( c曲リストノード.list子リスト, part );\r
+                                               nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];\r
                                        }\r
+// Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
                                }\r
                        }\r
                }\r
+               public void t曲リストのソート5_BestRank順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
+               {\r
+                       order = -order;\r
+                       int nL12345 = (int) p[ 0 ];\r
+                       if ( part != E楽器パート.UNKNOWN )\r
+                       {\r
+                               ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
+                               {\r
+                                       #region [ 共通処理 ]\r
+                                       if ( n1 == n2 )\r
+                                       {\r
+                                               return 0;\r
+                                       }\r
+                                       int num = this.t比較0_共通( n1, n2 );\r
+                                       if ( num != 0 )\r
+                                       {\r
+                                               return order * num;\r
+                                       }\r
+                                       if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
+                                       {\r
+                                               return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
+                                       }\r
+                                       #endregion\r
+                                       int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;\r
+                                       bool isFullCombo1 = false, isFullCombo2 = false;\r
+                                       if ( n1.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               isFullCombo1 = n1.arスコア[ nL12345 ].譜面情報.フルコンボ[ (int) part ];\r
+                                               nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];\r
+                                       }\r
+                                       if ( n2.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               isFullCombo2 = n2.arスコア[ nL12345 ].譜面情報.フルコンボ[ (int) part ];\r
+                                               nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];\r
+                                       }\r
+                                       if ( isFullCombo1 ^ isFullCombo2 )\r
+                                       {\r
+                                               if ( isFullCombo1 ) return order; else return -order;\r
+                                       }\r
+                                       num = nSumPlayCountN2 - nSumPlayCountN1;\r
+                                       if ( num != 0 )\r
+                                       {\r
+                                               return order * num;\r
+                                       }\r
+                                       return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
+                               } );\r
+                               foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
+                               {\r
+                                       int nSumPlayCountN1 = 0;\r
+                                       if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];\r
+                                       }\r
+// Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
+                               }\r
+                       }\r
+               }\r
+               public void t曲リストのソート6_SkillPoint順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
+               {\r
+                       order = -order;\r
+                       int nL12345 = (int) p[ 0 ];\r
+                       if ( part != E楽器パート.UNKNOWN )\r
+                       {\r
+                               ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
+                               {\r
+                                       #region [ 共通処理 ]\r
+                                       if ( n1 == n2 )\r
+                                       {\r
+                                               return 0;\r
+                                       }\r
+                                       int num = this.t比較0_共通( n1, n2 );\r
+                                       if ( num != 0 )\r
+                                       {\r
+                                               return order * num;\r
+                                       }\r
+                                       if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
+                                       {\r
+                                               return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
+                                       }\r
+                                       #endregion\r
+                                       double nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;\r
+                                       if ( n1.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];\r
+                                       }\r
+                                       if ( n2.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];\r
+                                       }\r
+                                       double d = nSumPlayCountN2 - nSumPlayCountN1;\r
+                                       if ( d != 0 )\r
+                                       {\r
+                                               return order * System.Math.Sign(d);\r
+                                       }\r
+                                       return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
+                               } );\r
+                               foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
+                               {\r
+                                       double nSumPlayCountN1 = 0;\r
+                                       if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];\r
+                                       }\r
+// Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
+                               }\r
+                       }\r
+               }\r
+               public void t曲リストのソート7_更新日時順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
+               {\r
+                       int nL12345 = (int) p[ 0 ];\r
+                       if ( part != E楽器パート.UNKNOWN )\r
+                       {\r
+                               ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
+                               {\r
+                                       #region [ 共通処理 ]\r
+                                       if ( n1 == n2 )\r
+                                       {\r
+                                               return 0;\r
+                                       }\r
+                                       int num = this.t比較0_共通( n1, n2 );\r
+                                       if ( num != 0 )\r
+                                       {\r
+                                               return order * num;\r
+                                       }\r
+                                       if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
+                                       {\r
+                                               return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
+                                       }\r
+                                       #endregion\r
+                                       DateTime nSumPlayCountN1 = DateTime.Parse("0001/01/01 12:00:01.000");\r
+                                       DateTime nSumPlayCountN2 = DateTime.Parse("0001/01/01 12:00:01.000");\r
+                                       if ( n1.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN1 = n1.arスコア[ nL12345 ].ファイル情報.最終更新日時;\r
+                                       }\r
+                                       if ( n2.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN2 = n2.arスコア[ nL12345 ].ファイル情報.最終更新日時;\r
+                                       }\r
+                                       int d = nSumPlayCountN1.CompareTo(nSumPlayCountN2);\r
+                                       if ( d != 0 )\r
+                                       {\r
+                                               return order * System.Math.Sign( d );\r
+                                       }\r
+                                       return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
+                               } );\r
+                               foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
+                               {\r
+                                       DateTime nSumPlayCountN1 = DateTime.Parse( "0001/01/01 12:00:01.000" );\r
+                                       if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].ファイル情報.最終更新日時;\r
+                                       }\r
+// Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
+                               }\r
+                       }\r
+               }\r
+               public void t曲リストのソート8_アーティスト名順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
+               {\r
+                       int nL12345 = (int) p[ 0 ]; \r
+                       ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
+                       {\r
+                               if ( n1 == n2 )\r
+                               {\r
+                                       return 0;\r
+                               }\r
+                               int num = this.t比較0_共通( n1, n2 );\r
+                               if ( num != 0 )\r
+                               {\r
+                                       return order * System.Math.Sign( num );\r
+                               }\r
+                               string strAuthorN1 = "";\r
+                               string strAuthorN2 = "";\r
+                               if (n1.arスコア[ nL12345 ] != null ) {\r
+                                       strAuthorN1 = n1.arスコア[ nL12345 ].譜面情報.アーティスト名;\r
+                               }\r
+                               if ( n2.arスコア[ nL12345 ] != null )\r
+                               {\r
+                                       strAuthorN2 = n2.arスコア[ nL12345 ].譜面情報.アーティスト名;\r
+                               }\r
+\r
+                               return order * strAuthorN1.CompareTo( strAuthorN2 );\r
+                       } );\r
+                       foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
+                       {\r
+                               string s = "";\r
+                               if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
+                               {\r
+                                       s = c曲リストノード.arスコア[ nL12345 ].譜面情報.アーティスト名;\r
+                               }\r
+Debug.WriteLine( s + ":" + c曲リストノード.strタイトル );\r
+                       }\r
+               }\r
+#if TEST_SORTBGM\r
+               public void t曲リストのソート9_BPM順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
+               {\r
+                       order = -order;\r
+                       int nL12345 = (int) p[ 0 ];\r
+                       if ( part != E楽器パート.UNKNOWN )\r
+                       {\r
+                               ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
+                               {\r
+                                       #region [ 共通処理 ]\r
+                                       if ( n1 == n2 )\r
+                                       {\r
+                                               return 0;\r
+                                       }\r
+                                       int num = this.t比較0_共通( n1, n2 );\r
+                                       if ( num != 0 )\r
+                                       {\r
+                                               return order * num;\r
+                                       }\r
+                                       if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
+                                       {\r
+                                               return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
+                                       }\r
+                                       #endregion\r
+                                       double dBPMn1 = 0.0, dBPMn2 = 0.0;\r
+                                       if ( n1.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               dBPMn1 = n1.arスコア[ nL12345 ].譜面情報.bpm;\r
+                                       }\r
+                                       if ( n2.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               dBPMn2 = n2.arスコア[ nL12345 ].譜面情報.bpm;\r
+                                       }\r
+                                       double d = dBPMn1- dBPMn2;\r
+                                       if ( d != 0 )\r
+                                       {\r
+                                               return order * System.Math.Sign( d );\r
+                                       }\r
+                                       return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
+                               } );\r
+                               foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
+                               {\r
+                                       double dBPM = 0;\r
+                                       if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
+                                       {\r
+                                               dBPM = c曲リストノード.arスコア[ nL12345 ].譜面情報.bpm;\r
+                                       }\r
+Debug.WriteLine( dBPM + ":" + c曲リストノード.strタイトル );\r
+                               }\r
+                       }\r
+               }\r
+#endif\r
+               //-----------------\r
+               #endregion\r
+               #region [ .score.ini を読み込んで Cスコア.譜面情報に設定する ]\r
+               //-----------------\r
+               public void tScoreIniを読み込んで譜面情報を設定する( string strScoreIniファイルパス, ref Cスコア score )\r
+               {\r
+                       if( !File.Exists( strScoreIniファイルパス ) )\r
+                               return;\r
+\r
+                       try\r
+                       {\r
+                               var ini = new CScoreIni( strScoreIniファイルパス );\r
+                               ini.t全演奏記録セクションの整合性をチェックし不整合があればリセットする();\r
+\r
+                               for( int n楽器番号 = 0; n楽器番号 < 3; n楽器番号++ )\r
+                               {\r
+                                       int n = ( n楽器番号 * 2 ) + 1;      // n = 0~5\r
+\r
+                                       #region socre.譜面情報.最大ランク[ n楽器番号 ] = ... \r
+                                       //-----------------\r
+                                       if( ini.stセクション[ n ].b演奏にMIDI入力を使用した ||\r
+                                               ini.stセクション[ n ].b演奏にキーボードを使用した ||\r
+                                               ini.stセクション[ n ].b演奏にジョイパッドを使用した ||\r
+                                               ini.stセクション[ n ].b演奏にマウスを使用した )\r
+                                       {\r
+                                               // (A) 全オートじゃないようなので、演奏結果情報を有効としてランクを算出する。\r
+\r
+                                               score.譜面情報.最大ランク[ n楽器番号 ] =\r
+                                                       CScoreIni.tランク値を計算して返す( \r
+                                                               ini.stセクション[ n ].n全チップ数,\r
+                                                               ini.stセクション[ n ].nPerfect数, \r
+                                                               ini.stセクション[ n ].nGreat数,\r
+                                                               ini.stセクション[ n ].nGood数, \r
+                                                               ini.stセクション[ n ].nPoor数,\r
+                                                               ini.stセクション[ n ].nMiss数 );\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               // (B) 全オートらしいので、ランクは無効とする。\r
+\r
+                                               score.譜面情報.最大ランク[ n楽器番号 ] = (int) CScoreIni.ERANK.UNKNOWN;\r
+                                       }\r
+                                       //-----------------\r
+                                       #endregion\r
+                                       score.譜面情報.最大スキル[ n楽器番号 ] = ini.stセクション[ n ].db演奏型スキル値;\r
+                                       score.譜面情報.フルコンボ[ n楽器番号 ] = ini.stセクション[ n ].bフルコンボである;\r
+                               }\r
+                               score.譜面情報.演奏回数.Drums = ini.stファイル.PlayCountDrums;\r
+                               score.譜面情報.演奏回数.Guitar = ini.stファイル.PlayCountGuitar;\r
+                               score.譜面情報.演奏回数.Bass = ini.stファイル.PlayCountBass;\r
+                               for( int i = 0; i < 5; i++ )\r
+                                       score.譜面情報.演奏履歴[ i ] = ini.stファイル.History[ i ];\r
+                       }\r
+                       catch\r
+                       {\r
+                               Trace.TraceError( "演奏記録ファイルの読み込みに失敗しました。[{0}]", strScoreIniファイルパス );\r
+                       }\r
+               }\r
                //-----------------\r
                #endregion\r
 \r
@@ -1132,7 +1676,8 @@ namespace DTXMania
 \r
                #region [ private ]\r
                //-----------------\r
-               private const string SONGSDB_VERSION = "SongsDB2";\r
+               private const string SONGSDB_VERSION = "SongsDB3";\r
+               private List<string> listStrBoxDefSkinSubfolderFullName;\r
 \r
                private int t比較0_共通( C曲リストノード n1, C曲リストノード n2 )\r
                {\r
@@ -1162,6 +1707,23 @@ namespace DTXMania
                        }\r
                        return 0;\r
                }\r
+\r
+               /// <summary>\r
+               /// 検索を中断・スローダウンする\r
+               /// </summary>\r
+               private void SlowOrSuspendSearchTask()\r
+               {\r
+                       if ( this.bIsSuspending )               // #27060 中断要求があったら、解除要求が来るまで待機\r
+                       {\r
+                               autoReset.WaitOne();\r
+                       }\r
+                       if ( this.bIsSlowdown && ++this.searchCount > 10 )                      // #27060 #PREMOVIE再生中は検索負荷を下げる\r
+                       {\r
+                               Thread.Sleep( 100 );\r
+                               this.searchCount = 0;\r
+                       }\r
+               }\r
+\r
                //-----------------\r
                #endregion\r
        }\r