private void OpenStateFile(string fileName, string ListFilePath)
        {
            var StopUndoBufferUpdate_TEMP = StopUndoBufferUpdate;
            StopUndoBufferUpdate = true;

            #if !DEBUG
            try
            #endif
            {
                newDlc = true;
                ClearMainUI();
                dlcData = Program.OpenState(fileName);

                MakeColumnsFromDLCData(dlcData);

                //btnSave.Text = Program.dicLanguage["SaveDLC"];
                setBtnSave();
                btnCmpSave.Enabled = btnSave.Enabled = true;
                btnSaveState.Enabled = true;
                btnCharsAdd.Enabled = true;
                btnHStylesAdd.Enabled = true;
                //clmCos.ReadOnly = false;
                clmInner.ReadOnly = false;
                if (dlcData.Chars.Count > 0)
                {
                    tbSavePath.Text = dlcData.SavePath;
                    setBtnSave(); // もう一回
                    tbBCMVer.Text = dlcData.BcmVer.ToString();
                    for (int i = 0; i < dlcData.Chars.Count; i++)
                    {
                        dgvChars.Rows.Add();
                        dgvChars.Rows[i].Cells[0].Value = GetCharNamesJpn(dlcData.Chars[i].ID);// Program.CharNamesJpn[dlcData.Chars[i].ID];
                        dgvChars.Rows[i].Cells[1].Value = dlcData.Chars[i].CostumeSlot.ToString();
                        dgvChars.Rows[i].Cells[2].Value = dlcData.Chars[i].AddTexsCount.ToString();

                        //dlcData.Chars[i].Comment = "";// GetComment()";
                        //dgvChars.Rows[i].Cells[3].Value = dlcData.Chars[i].Comment;
                        showComment(i);

                        /*
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("0");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("1");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("2");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("3");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("4");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("×39");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("39-");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("39*");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Items.Add("39?");
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).Value = "2";
                        //((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[2]).Items[3].Ba
                        //((ComboBox)dgvChars.Rows[i].Cells[1]).DrawItem += new DrawItemEventHandler(ComboBox1_DrawItem);
                        //((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).DisplayStyle;
                        //MessageBox.Show(((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).DropDownWidth.ToString());
                        //((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).DropDownWidth = 2;
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
                        ((DataGridViewComboBoxCell)dgvChars.Rows[i].Cells[1]).FlatStyle = FlatStyle.Flat;
                        */
                    }

                    dgvChars.Rows[0].Selected = true;

                }

                // リストファイルのパスを表示
                string ext = Path.GetExtension(fileName).ToLower();
                if (ext == ".lst" || ext == ".rst")
                {
                    tbListPath.Text = fileName.Substring(0, fileName.Length - 4);
                }
                else
                {
                    tbListPath.Text = fileName;
                }
                tbListPath.Select(tbListPath.Text.Length, 0);
                tbListPath.ScrollToCaret();

                // 既にリストファイルが保存してあって、そのリストファイルがその DLC 用のものである場合に限ってチェックボックスオン
                /*
                try
                {
                    string listInDLC = Path.Combine(dlcData.SavePath, Path.GetFileName(fileName));
                    if(listInDLC == fileName || (File.Exists(listInDLC) && (Program.OpenState(listInDLC).SavePath == dlcData.SavePath)))
                    {
                        cbSaveListInDLC.Checked = true;
                    }
                }
                catch { }*/
                // ・・・は止めて、既に DLC フォルダが存在して、その中に保存するべきリストファイルが存在しない場合を除いてチェックボックスオン
                // わざわざ中身までは見ないことにする
                try
                {
                    if (ListFilePath == null)
                    {
                        string listInDLC = Path.Combine(dlcData.SavePath, Path.GetFileName(fileName));
                        cbSaveListInDLC.Checked = (listInDLC == fileName || (!Directory.Exists(dlcData.SavePath)) || File.Exists(listInDLC));
                    }
                    else
                    {
                        string listInDLC = Path.Combine(dlcData.SavePath, Path.GetFileName(ListFilePath));
                        cbSaveListInDLC.Checked = (listInDLC == fileName || (!Directory.Exists(dlcData.SavePath)) || File.Exists(listInDLC));
                    }
                }
                catch
                {
                    cbSaveListInDLC.Checked = true;
                }

            }
            #if !DEBUG
            catch (Exception e)
            {
                MessageBox.Show(e.Message, Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            #endif

            StopUndoBufferUpdate = StopUndoBufferUpdate_TEMP;
        }
        private void SaveDLC(bool Compression, bool Instant)
        {
            List<string[]> FassingFolderList = null;
            #if !DEBUG
            try
            #endif
            {
                if(Instant && GetGameShortcut() =="" && GetGameExe() == "")
                {
                    var e = new FileNotFoundException(null, "game.exe");
                        MessageBox.Show(e.Message, Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error);
                    tbSavePath_TextChanged(null, null);//念のため
                    return;
                }

                Program.SlotTable<string> ComIniSlotCommentTable = GetComIniSlotCommentTable();
                var NotthingComIni = true;
                for(var i = 0; i < dlcData.Chars.Count; i++)
                {

                    if (ComIniSlotCommentTable[dlcData.Chars[i]] != "")
                    {
                        NotthingComIni = false;
                        break;
                    }
                }

                if(!NotthingComIni)
                {
                    throw new Exception(Program.dicLanguage["CharaCommonKillInstant"]);
                }

                if (dgvChars.Rows.Count == 0)
                {
                    throw new Exception(Program.dicLanguage["AddCharacter"]);
                }

                string dlcName = "";
                if (newDlc)
                {
                    bool direxists = false;
                    try
                    {
                        if (tbSavePath.Text != string.Empty)
                        {
                            direxists = Directory.Exists(Path.GetDirectoryName(tbSavePath.Text));
                        }
                    }
                    catch { }
                    if (!direxists)
                    {

                        var pt = LoadIniString("InitialDirectory", "BCM"); // ここも BMC で。
                        if (pt != "") saveFileDialog.InitialDirectory = GetOwnOFolderrExistingParent((Path.GetDirectoryName(pt))); // ただし親を見る。
                        saveFileDialog.FileName = Path.GetFileName(openFileDialog.FileName);

                        if (saveFileDialog.ShowDialog() == DialogResult.OK)
                        {
                            System.Text.RegularExpressions.Regex regex_doa = new System.Text.RegularExpressions.Regex(@"^(.*\\([^\\]+))\\\2\.bcm$",
                                System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                            if (regex_doa.IsMatch(saveFileDialog.FileName))
                            {
                                tbSavePath.Text = regex_doa.Replace(saveFileDialog.FileName, "$1");
                                SaveIniString("InitialDirectory", "BCM", Path.GetDirectoryName(saveFileDialog.FileName));
                            }
                            else
                            {
                                tbSavePath.Text = saveFileDialog.FileName;
                                SaveIniString("InitialDirectory", "BCM", saveFileDialog.FileName);
                            }
                        }
                        else
                        {
                            throw new Exception(Program.dicLanguage["SetDestinationToSave"]);
                        }

                    }

                    if (!DirectoryIsPureDLC(tbSavePath.Text))
                    {
                        MessageBox.Show(Program.dicLanguage["NotPureDLCFolder"], Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error);
                        tbSavePath_TextChanged(null, null);//念のため
                        return;
                    }

                    dlcName = Path.GetFileNameWithoutExtension(tbSavePath.Text);

                    // 保存用の dlcData 変数
                    DLCData dlcData4Save = new DLCData();
                    dlcData4Save.SavePath = dlcData.SavePath;
                    dlcData4Save.BcmVer = dlcData.BcmVer;
                    dlcData4Save.skipRead = dlcData.skipRead;

                    // 問題のもの以外をコピー
                    Program.SlotTable<int> slotCount = new Program.SlotTable<int>(0);
                    for (int i = 0; i < dgvChars.Rows.Count; i++)
                    {
                        slotCount[dlcData.Chars[i]]++;
                    }

                    for (int i = 0; i < dlcData.Chars.Count; i++)
                    {
                        if (CheckCharFile(dlcData.Chars[i]) && slotCount[dlcData.Chars[i]] == 1 && dlcData.Chars[i].AddTexsCount <= getAvailableTextsCount(dlcData.Chars[i]))
                        {
                            dlcData4Save.Chars.Add(dlcData.Chars[i]);
                        }
                    }

                    if (dlcData4Save.Chars.Count > 0)
                    {
                        bool comp = Compression;// cbComp.Checked;

                        if (Instant)
                        {
                            FassingFolderList = new List<string[]>();

                            // 今から保存しようとしているフォルダが存在していれば
                            if (Directory.Exists(tbSavePath.Text))
                            {
                                var src = tbSavePath.Text;
                                var back = GetBackupPath(src);
                                Directory.Move(src, back);
                                FassingFolderList.Add(new string[2] { src, back });
                                //BackupOriginal = true;
                            }

                            // 既存の DLC で邪魔になるものを排除
                            var sot = GetSlotOwnerPathAndDLCData();
                            var Path2DLC = new Dictionary<string, DLCData>();
                            for(var i = 0; i < dlcData.Chars.Count; i++)
                            {
                                var tpl = sot[dlcData.Chars[i]];
                                if (tpl != null)
                                {
                                    var jamapath = tpl.Item1;
                                    var dlcd = tpl.Item2;
                                    var idx = tpl.Item3;
                                    dlcd.Chars.RemoveAt(idx);
                                    Path2DLC[jamapath] = dlcd; // 以前の DLCData が上書きされるように見えるが、DLCdata の参照は全て同じなので問題ない。
                                }
                            }
                            foreach(var jamapath in Path2DLC.Keys)
                            {
                                var src = Path.GetDirectoryName(jamapath);
                                var back = GetBackupPath(src);

                                FassingFolderList.Add(new string[2] { src, back });
                                Directory.Move(src, back);
                                var KaridlcName = Path.GetFileNameWithoutExtension(src);
                            }
                        }

                        // DLC Tool 1.1 より
                        if (!Program.SaveDLC(dlcData4Save, tbSavePath.Text, dlcName, comp))
                        {
                            tbSavePath_TextChanged(null, null);//念のため
                            return;
                        }

                        string message;
                        if (dlcData4Save.Chars.Count == dlcData.Chars.Count)
                        {
                            message = Program.dicLanguage["SavedDLC"];
                        }
                        else
                        {
                            message = Program.dicLanguage["SavedPartialDLC"];
                        }

                        string path = tbSavePath.Text + @"\" + Path.GetFileName(tbListPath.Text) + ".lst";
                        if (cbSaveListInDLC.Enabled && cbSaveListInDLC.Checked && !Instant)
                        {

                            string name;
                            try
                            {
                                name = Path.GetFileName(tbListPath.Text);
                            }
                            catch
                            {
                                name = "";
                            }
                            bool GoodName = (name != "" && name.IndexOfAny(Path.GetInvalidFileNameChars()) < 0);
                            if (GoodName)
                            {
                                dlcData.SavePath = tbSavePath.Text;
                                Program.SaveState(dlcData, path); //dlcData4Save とどっちか迷うところだけど、バックアップ機能を兼ねると思えばオリジナルのほうで良いのでは。
                            }
                        }
                        else if (cbSaveListInDLC.Enabled && !cbSaveListInDLC.Checked)
                        {
                            // ファイルが存在していてそれがユーザーが保存したもので無ければ消す
                            try
                            {
                                if (path != tbListPath.Text + ".lst" && File.Exists(path))
                                {
                                    File.Delete(path);
                                }
                            }
                            catch { }
                        }

                        // ショートカットを探す
                        System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"\\DLC\\\d+$");
                        string shortcut = GetGameShortcut();

                        // ゲームそのものを探す
                        string DOA5EXE = "";
                        if (shortcut == "")
                        {
                            DOA5EXE = GetGameExe();
                        }

                        if (shortcut == "" && DOA5EXE == "")
                        {
                            if (!Instant)
                            {
                                MessageBox.Show(message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                throw new FileNotFoundException(null, "game.exe"); // ファイルの復元はエラー後に行われる
                            }
                        }
                        else
                        {
                            if (!Instant)
                            {
                                if (MessageBox.Show(message + "\n\n" + Program.dicLanguage["DoYouStartDOA5"], "Info", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                                {

                                    if (shortcut != "")
                                    {
                                        OpenWithShortcut(shortcut, "", false);
                                    }
                                    else
                                    {
                                        // 念のためカレントディレクトリを動かしておく
                                        string sCD = System.Environment.CurrentDirectory;
                                        System.Environment.CurrentDirectory = Path.GetDirectoryName(DOA5EXE); ;//System.IO.Path.GetDirectoryName(fileName);
                                        System.Diagnostics.Process.Start("\"" + DOA5EXE + "\"");
                                        System.Environment.CurrentDirectory = sCD;
                                    }
                                }
                            }
                            else
                            {

                                System.Diagnostics.Process DOAProcess = null;
                                Enabled = false;

                                // ゲーム起動
                                DateTime startTime = DateTime.Now;
                                if (shortcut != "")
                                {
                                    OpenWithShortcut(shortcut, "", false);
                                }
                                else
                                {
                                    // 念のためカレントディレクトリを動かしておく
                                    string sCD = Environment.CurrentDirectory;
                                    Environment.CurrentDirectory = Path.GetDirectoryName(DOA5EXE); ;//System.IO.Path.GetDirectoryName(fileName);
                                    System.Diagnostics.Process.Start("\"" + DOA5EXE + "\"");
                                    // コイツの戻り値は使えない模様(一度直ぐに閉じる)
                                    Environment.CurrentDirectory = sCD;
                                }

                                // スクリプト経由で起動する場合、ゲームの起動を動的に補足する
                                var foundAtLeastOne = false;
                                if (DOAProcess == null)
                                {
                                    var step = 0.1; // 秒
                                    var seekingTime = 10; // 秒
                                    double tFromFirstFound = 0;
                                    for (double t = 0; t < seekingTime; t += step)
                                    {

                                        //ローカルコンピュータ上で実行されているすべてのプロセスを取得
                                        System.Diagnostics.Process[] ps =
                                            System.Diagnostics.Process.GetProcesses();

                                        //配列から1つずつ取り出す
                                        foreach (System.Diagnostics.Process p in ps)
                                        {
                                            Application.DoEvents();
                                            try
                                            {
                                                if (p.ProcessName == "game" && Path.GetFileName(p.MainModule.FileName) == "game.exe" /*&& p.StartTime >= startTime*/)
                                                {
                                                    DOAProcess = p;
                                                }
                                            }
                                            catch
                                            {
                                            }
                                            if (DOAProcess != null)
                                            {
                                                foundAtLeastOne = true;
                                                break;
                                            }
                                        }

                                        if(foundAtLeastOne && DOAProcess == null)
                                        {
                                            tFromFirstFound = double.PositiveInfinity;
                                        }

                                        // 起動後一度すぐに閉じるので、
                                        // 2秒ほどは待つ
                                        if (tFromFirstFound < 2)
                                        {
                                            DOAProcess = null;

                                            System.Threading.Thread.Sleep((int)(step * 1000 + 0.5));
                                            if (foundAtLeastOne) tFromFirstFound += step;

                                            continue;
                                        }
                                        else if (DOAProcess != null)
                                        {
                                            break;
                                        }

                                        System.Threading.Thread.Sleep((int)(step * 1000 + 0.5));
                                        if (foundAtLeastOne) tFromFirstFound += step;
                                    }

                                }

                                if (DOAProcess == null && !foundAtLeastOne)
                                {
                                    Enabled = true;
                                    throw new Exception("Dead or alive process is not found.");
                                }
                                else if(DOAProcess != null)
                                {
                                    // プロセスが終了するのを待つ
                                    while (!DOAProcess.WaitForExit((int)(10)))
                                    {
                                        Application.DoEvents();
                                    }
                                }

                                var DLCDir = tbSavePath.Text;
                                var DLCName = Path.GetFileName(DLCDir);
                                File.Delete(DLCDir + @"\data\" + DLCName + ".bin");
                                File.Delete(DLCDir + @"\data\" + DLCName + ".blp");
                                File.Delete(DLCDir + @"\data\" + DLCName + ".lnk");
                                Directory.Delete(DLCDir + @"\data");
                                File.Delete(DLCDir + @"\" + DLCName + ".bcm");
                                Directory.Delete(DLCDir);
                                for (var i = 0; i < FassingFolderList.Count; i++)
                                {
                                    Directory.Move(FassingFolderList[i][1], FassingFolderList[i][0]);
                                }
                                Enabled = true;
                                this.TopMost = true;
                                Activate();
                                this.TopMost = false;
                            }
                        }

                    }
                    else
                    {
                        throw new Exception(Program.dicLanguage["NotSavedDLC"]);
                    }
                }
                else
                {

                    bool direxists = false;
                    try
                    {
                        if (tbSavePath.Text != string.Empty)
                        {
                            direxists = Directory.Exists(tbSavePath.Text);
                        }
                    }
                    catch { }

                    if (!direxists || dlcData.skipRead > 0)
                    {
                        if (dlcData.skipRead > 0)
                        {
                            MessageBox.Show(Program.dicLanguage["OverwritingKillsSkipedItem"], Program.dicLanguage["Notice"], MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }

                        var pt = GetOwnOFolderrExistingParent(LoadIniString("InitialDirectory", "BCM"));
                        if (pt != "") saveFileDialogBCM.InitialDirectory = pt;
                        saveFileDialogBCM.FileName = Path.GetFileName(openFileDialogBCM.FileName);
                        if (saveFileDialogBCM.ShowDialog() == DialogResult.OK)
                        {
                            SaveIniString("InitialDirectory", "BCM", Path.GetDirectoryName(saveFileDialogBCM.FileName));
                            tbSavePath.Text = saveFileDialogBCM.FileName;
                        }
                        else
                        {
                            throw new Exception(Program.dicLanguage["SetDestinationToSave"]);
                        }
                    }

                    if (!DirectoryIsPureDLC(Path.GetDirectoryName(tbSavePath.Text)))
                    {
                        MessageBox.Show(Program.dicLanguage["NotPureDLCFolder"], Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error);
                        tbSavePath_TextChanged(null, null);//念のため
                        return;
                    }

                    dlcName = Path.GetFileNameWithoutExtension(tbSavePath.Text);

                    Program.SaveBCM(dlcData, tbSavePath.Text, dlcName);
                    MessageBox.Show(Program.dicLanguage["SavedBCM"], "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            #if !DEBUG
            catch (Exception ex)
            {

                if (FassingFolderList != null)
                {

                    for (var i = 0; i < FassingFolderList.Count; i++)
                    {
                        try
                        {
                            Directory.Move(FassingFolderList[i][1], FassingFolderList[i][0]);
                        }
                        catch { }
                    }
                }

                Enabled = true; // 必須
                if (ex is OverflowException)
                {
                    MessageBox.Show(Program.dicLanguage["DecreaseDLCNum"], Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    MessageBox.Show(ex.Message, Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            #endif
            tbSavePath_TextChanged(null, null);//これは念のためじゃなくて必須
        }
        private void MakeColumnsFromDLCData(DLCData dlcData)
        {
            // 読み込んだ dlcData.Chars の中でコンマが一番多いもののコンマの数を取得
            int max = 0;
            for (int i = 0; i < dlcData.Chars.Count; i++)
            {
                int start = 0;
                int commacount = 0;
                string com = dlcData.Chars[i].Comment;
                while (true)
                {
                    start = com.IndexOf(',', start) + 1;
                    if (start > 0)
                    {
                        commacount++;
                    }
                    else
                    {
                        break;
                    }
                }
                if (commacount > max)
                {
                    max = commacount;
                }
            }

            // 現在のコメント数
            int corcom = dgvChars.Columns.Count - 3;

            // max + 1 - corcom 列だけ末尾にコメント列を追加
            //MessageBox.Show(max.ToString());
            for (int i = 0; i < max + 1 - corcom; i++)
            {
                AddComColumn(i + 2 + corcom, true);
            }
        }
        private void OpenFile(string fileName)
        {
            var StopUndoBufferUpdate_TEMP = StopUndoBufferUpdate;
            StopUndoBufferUpdate = true;

            #if !DEBUG
            try
            #endif
            {
                newDlc = false;
                ClearMainUI();

                dlcData = Program.OpenBCM_超原始的修正(fileName);

                tbSavePath.Text = fileName;
                //dlcData = Program.OpenBCM(fileName);
                //通常のオープンファイルもこっちにしちゃおう

                //btnSave.Text = Program.dicLanguage["SaveBCM"];
                setBtnSave();

                btnCmpSave.Enabled = true;
                btnCmpSave.Text = Program.dicLanguage["ExtractFiles"];

                //btnCmpSave.Enabled =
                btnSave.Enabled = true;
                btnHStylesAdd.Enabled = true;
                //clmCos.ReadOnly = true;
                clmInner.ReadOnly = true;

                dgvChars.BackgroundColor = System.Drawing.SystemColors.MenuBar;
                //dgvChars.DefaultCellStyle.BackColor = System.Drawing.SystemColors.MenuBar;
                //dgvChars.DefaultCellStyle.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
                dgvChars.Columns[0].DefaultCellStyle.BackColor = System.Drawing.SystemColors.MenuBar;
                dgvChars.Columns[0].DefaultCellStyle.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
                dgvChars.Columns[1].DefaultCellStyle.BackColor = System.Drawing.SystemColors.MenuBar;
                dgvChars.Columns[1].DefaultCellStyle.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
                dgvChars.Columns[2].DefaultCellStyle.BackColor = System.Drawing.SystemColors.MenuBar;
                dgvChars.Columns[2].DefaultCellStyle.ForeColor = System.Drawing.SystemColors.ControlDarkDark;

                tbBCMVer.Text = dlcData.BcmVer.ToString();
                dlcData.SavePath = fileName;

                cbSaveListInDLC.Checked = false;
                cbSaveListInDLC.Enabled = false;

                for (int i = 0; i < dlcData.Chars.Count; i++)
                {
                    dgvChars.Rows.Add();
                    dgvChars.Rows[i].Cells[0].Value = GetCharNamesJpn(dlcData.Chars[i].ID);// Program.CharNamesJpn[dlcData.Chars[i].ID];
                    dgvChars.Rows[i].Cells[1].Value = dlcData.Chars[i].CostumeSlot.ToString();
                    dgvChars.Rows[i].Cells[2].Value = dlcData.Chars[i].AddTexsCount.ToString();
                    //dgvChars.Rows[i].Cells[3].Value = dlcData.Chars[i].Comment;
                    showComment(i);
                }
                dgvChars.Rows[0].Selected = true;

            }
            #if !DEBUG
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            #endif

            StopUndoBufferUpdate = StopUndoBufferUpdate_TEMP;
        }
        private void ExtractFiles(string savePath, string loadPath)
        {
            try
            {
                var archData = Archive_Tool.Program.ParseArchive(loadPath, DAT); // loadPath == "" でもエラーを投げてくれない
                if (archData == null)
                {
                    if (!File.Exists(loadPath))
                    {
                        throw new FileNotFoundException(null, loadPath);
                    }
                    else if (!File.Exists(DAT))
                    {
                        throw new FileNotFoundException(null, DAT);
                    }
                    else
                    {
                        throw new ArgumentNullException("archData");
                    }
                }

                var targetArchData = new System.Collections.Generic.List<Archive_Tool.ArchiveFile>();

                var Chars = dlcData.Chars;

                tbSavePath.Text = Path.GetDirectoryName(Path.GetDirectoryName(loadPath));
                newDlc = true;
                ClearMainUI();
                dlcData = new DLCData();
                setBtnSave();
                btnCmpSave.Enabled = btnSave.Enabled = true;
                btnSaveState.Enabled = true;
                btnCharsAdd.Enabled = true;
                clmInner.ReadOnly = false;
                dlcData.BcmVer = 9;
                tbBCMVer.Text = "9";
                cbSaveListInDLC.Enabled = true;
                cbSaveListInDLC.Checked = true;

                if(File.Exists(savePath))
                {
                    File.Delete(savePath);
                }
                if (!Directory.Exists(savePath))
                {
                    Directory.CreateDirectory(savePath);
                }

                var userFlags = new bool[] { false, false, false, false };

                // 主要な計算は明らかに抽出処理なのでこれは不要というか、無いほうが良い
                // と思ったが、処理中はリストの更新は行われずチェックボックスだけがチラついたのでやっぱりやる
                var dgvChars_SelectionChanged_RepairingSelection_current = dgvChars_SelectionChanged_RepairingSelection;
                dgvChars_SelectionChanged_RepairingSelection = true;

                // スクロールバーが変に動くのでファイルの抽出だけは先にしておく
                SetProgressBar(true, Chars.Count);
                for (var i = 0; i < Chars.Count; i++)
                {
                    IncrementProgressBar();

                    var chr = Chars[i];

                    var decName = GetDecName(chr);
                    for (var j = 0; j < archData.Length; j++)
                    {
                        var archFile = archData[j];
                        if (archFile.Name.StartsWith(decName))
                        {
                            var dataFilePath = Path.Combine(savePath, archFile.Name);
                            var result = Archive_Tool.Program.ExtractFile(archFile, dataFilePath, userFlags);
                            if(result != null)
                            {
                                throw new Exception(result.Item1);
                            }
                        }
                    }
                }

                for (var i = 0; i < Chars.Count; i++)
                {
                    //IncrementProgressBar();

                    var chr = Chars[i];

                    // これは一番下に追加する処理
                    dlcData.Chars.Add(chr);
                    dgvChars.Rows.Add();
                    dgvChars.Rows[dgvChars.Rows.Count - 1].Cells[0].Value = GetCharNamesJpn(chr.ID);// Program.CharNamesJpn[chr.ID];
                    dgvChars.Rows[dgvChars.Rows.Count - 1].Cells[1].Value = chr.CostumeSlot.ToString();
                    dgvChars.Rows[dgvChars.Rows.Count - 1].Cells[2].Value = chr.AddTexsCount.ToString();
                    showComment(dgvChars.Rows.Count - 1);
                    dgvChars.ClearSelection(); //AddFiles のために必要
                    dgvChars.Rows[dgvChars.Rows.Count - 1].Selected = true; //AddFiles のために必要

                    var decName = GetDecName(chr);
                    var fileNameList = new System.Collections.Generic.List<string>();
                    for(var j = 0; j < archData.Length; j++)
                    {
                        var archFile = archData[j];
                        if(archFile.Name.StartsWith(decName) )
                        {
                            var dataFilePath = Path.Combine(savePath, archFile.Name);
                            fileNameList.Add(dataFilePath);
                        }
                    }
                    var fileNames = new string[fileNameList.Count];
                    for(int j = 0; j < fileNames.Length; j++)
                    {
                        fileNames[j] = fileNameList[j];
                    }
                    AddFiles(fileNames, false, false);
                }

                // 主要な計算は明らかに抽出処理なのでこれは不要というか、無いほうが良い
                // と思ったが、処理中はリストの更新は行われずチェックボックスだけがチラついたのでやっぱりやる
                dgvChars_SelectionChanged_RepairingSelection = dgvChars_SelectionChanged_RepairingSelection_current;

                //1つめを選択。この時点で描画モードはオンになってないとダメ
                dgvChars.ClearSelection(); //AddFiles のために必要
                if(dgvChars.Rows.Count > 0) dgvChars.Rows[0].Selected = true; //AddFiles のために必要

                //コピーじゃないのでこれは必要
                btnCharsDelete.Enabled = true;
                btnFilesAdd.Enabled = true;

                setEgvCharsSlotColor(); // これらも追加
                setEgvCharsNameColor();
                setEgvCharsTextsColor(); // デフォルト機能により初めから問題があることも多々

                SetProgressBar(false, 0);

                return;
            }
            catch (Exception e)
            {
            #if DEBUG
                throw;
            #else
                MessageBox.Show(e.Message, Program.dicLanguage["Error"], MessageBoxButtons.OK, MessageBoxIcon.Error);
            #endif
            }
        }
        private void dgvChars_KeyDown(object sender, KeyEventArgs e)
        {
            if (dragStartIndexes != null) return;

            /*
            // テスト用のコード
            if (e.KeyCode == Keys.T && e.Control)
            {
                //MessageBox.Show("hero");

                //DataTableを作成する
                System.Data.DataTable dt = new System.Data.DataTable();
                //文字列型のWeek列を追加する
                dt.Columns.Add("Week", typeof(string));
                //Week列に日曜日~土曜日のデータを追加する
                dt.Rows.Add("0");
                dt.Rows.Add("1");
                dt.Rows.Add("2");
                //DataGridViewにデータソースを設定する
                dgvChars.DataSource = dt;

                //DataGridViewComboBoxColumnを作成
                DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();
                //ComboBoxのリストに表示する項目を設定する
                column.Items.Add("0");
                column.Items.Add("1");
                column.Items.Add("2");
                column.Items.Add("3");
                column.Items.Add("4");
                column.Items.Add("5");
                column.Items.Add("6");

                //DataGridView1に現在存在しているWeek列と
                // 今作成したDataGridViewComboBoxColumnを入れ替える
                //表示する列の名前を設定する
                column.DataPropertyName = dgvChars.Columns[2].DataPropertyName;
                //以下のようにしても同じ
                //column.DataPropertyName = "Week";
                //現在Week列が存在している位置に挿入する
                dgvChars.Columns[2].set
                //今までのWeek列を削除する
                dgvChars.Columns.RemoveAt(2);
                //挿入した列の名前を「Week」とする
                column.Name = "Dtl";

            return;

            }
            */

            var kc = e.KeyCode;
            if (kc == Keys.C && CKeyUp && e.Control)
            {
                CKeyUp = false;
                DLCData dlcData2 = new DLCData();

                try // dlcData が作られる前に呼び出されることもある
                {
                    //dlcData2.SavePath = dlcData.SavePath; 意図がわからないけど、この式の右辺は必要になるまで設定されないらしい
                    dlcData2.SavePath = tbSavePath.Text;
                    dlcData2.BcmVer = dlcData.BcmVer;
                    dlcData2.skipRead = dlcData.skipRead;
                }
                catch
                {
                    return;
                }

                if (dgvChars.SelectedRows.Count > 0)
                {
                    // 選択中のものをコピー
                    var SortedSelectedIndexes = GetSelectedCharsIndexesArray();
                    Array.Sort(SortedSelectedIndexes);
                    for (int i = 0; i < SortedSelectedIndexes.Length; i++)
                    {
                        dlcData2.Chars.Add(dlcData.Chars[SortedSelectedIndexes[i]]);
                    }
                    Clipboard.SetText(Program.dlcData2string(dlcData2));

                }
            }
            else if (kc == Keys.V && VKeyUp && e.Control)
            {
                VKeyUp = false;

                if (Clipboard.GetDataObject().GetDataPresent(DataFormats.FileDrop))
                {
                    string[] paths = (string[])Clipboard.GetDataObject().GetData(DataFormats.FileDrop);
                    if (AddFiles(paths, true))
                    {
                        //var charselectedrows = GetSelectedCharsIndexesArray();
                        int CharSelected = GetFirstSelectedCharIndex();
                        if (CharSelected < 0)
                        {
                            return;
                        }
                        /*
                        int CharSelected;
                        try
                        {
                            CharSelected = dgvChars.SelectedRows[0].Index;
                        }
                        catch
                        {
                            return;
                        }
                        */
                        for (int i = 0; i < dlcData.Chars[CharSelected].Files.Length /* = 12 */; i++)
                        {
                            dlcData.Chars[CharSelected].Files[i] = null;
                        }

                        clikedForm = "dgvFiles";
                        貼り付けCtrlVToolStripMenuItem_Click(null, null);
                    }
                }
                else if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Text))
                {

                    if (PasteHStyles(true))
                    {

                        int CharSelected = GetFirstSelectedCharIndex();
                        if (CharSelected < 0)
                        {
                            return;
                        }
                        /*
                        int CharSelected;
                        try
                        {
                            CharSelected = dgvChars.SelectedRows[0].Index;
                        }
                        catch
                        {
                            return;
                        }
                        */
                        dlcData.Chars[CharSelected].HStyles.Clear();

                        // 直後にペーストが控えているのでこれは不要
                        //ShowHairstyles(CharSelected);

                        // 髪型の貼り付けは現在の表示を見て選択位置に挿入しようとする
                        // なのでその前に整合性を取っておく必要がある。
                        ShowHairstyles(CharSelected);

                        // その後貼り付け処理
                        clikedForm = "dgvHStyles";
                        貼り付けCtrlVToolStripMenuItem_Click(null, null);
                    }
                    else
                    {
                        if (dgvChars.SelectedRows.Count <= 0)
                        {
                            return;
                        }

                        string str = Clipboard.GetText();

                        DLCData dlcData2 = Program.string2dlcData(str);

                        if (dlcData2 != null && dlcData2.Chars.Count > 0)
                        {
                            // 今選択されている場所。挿入に使う
                            int index = GetFirstSelectedCharIndex();
                            if (index < 0)
                            {
                                index = dgvChars.Rows.Count;
                            }
                            int index0 = index;

                            var dlcData3 = new DLCData();
                            dlcData3.Chars.AddRange(dlcData.Chars);
                            dlcData3.Chars.AddRange(dlcData2.Chars);
                            MakeColumnsFromDLCData(dlcData3);

                            Program.SlotTable<bool> CurrentUsableSlotTable = GetCurrentUsableSlotTable();

                            for (int j = 0; j < dlcData2.Chars.Count; j++)
                            {
                                Character curChar;
                                Character newChar;
                                try
                                {
                                    curChar = dlcData2.Chars[j];
                                    newChar = new Character();
                                    newChar.ID = curChar.ID;
                                    newChar.Female = curChar.Female;
                                    newChar.CostumeSlot = curChar.CostumeSlot; // これもコピーしてしまおう
                                    newChar.Comment = curChar.Comment;
                                    newChar.AddTexsCount = curChar.AddTexsCount;
                                    for (int i = 0; i < curChar.HStyles.Count; i++)
                                    {
                                        newChar.HStyles.Add(new Hairstyle(curChar.HStyles[i].Hair, curChar.HStyles[i].Face));
                                    }
                                    for (int i = 0; i < curChar.Files.Length /* = 12 */; i++)
                                    {
                                        newChar.Files[i] = curChar.Files[i];
                                    }
                                }
                                catch
                                {
                                    continue;
                                }

                                ResetToUsableSlotIfAble(newChar, CurrentUsableSlotTable);

                                // 挿入。今はこっち
                                // ボタンでのコピーだけ index + 1 だけどあっちは index == Length を許してないから間違いではない。
                                dlcData.Chars.Insert(index, newChar);
                                dgvChars.Rows.Insert(index);
                                dgvChars.Rows[index].Cells[0].Value = GetCharNamesJpn(newChar.ID);// Program.CharNamesJpn[newChar.ID];
                                dgvChars.Rows[index].Cells[1].Value = newChar.CostumeSlot.ToString();
                                dgvChars.Rows[index].Cells[2].Value = newChar.AddTexsCount.ToString();
                                //dgvChars.Rows[index].Cells[3].Value = newChar.Comment;
                                showComment(index);
                                // dgvChars.Rows[index].Selected = true; これは最後でいいですね

                                // 複数貼り付けることを考えるとこれを付けるか挿入の順番を逆にしないと結果が逆転する
                                index++;

                                /* これは最後に付け加える処理
                                dlcData.Chars.Add(newChar);

                                dgvChars.Rows.Add();
                                dgvChars.Rows[dgvChars.Rows.Count - 1].Cells[0].Value = GetCharNamesJpn(newChar.ID);// Program.CharNamesJpn[newChar.ID];
                                dgvChars.Rows[dgvChars.Rows.Count - 1].Cells[1].Value = newChar.CostumeSlot.ToString();
                                dgvChars.Rows[dgvChars.Rows.Count - 1].Cells[2].Value = newChar.AddTexsCount.ToString();
                                //dgvChars.Rows[dgvChars.Rows.Count - 1].Cells[3].Value = newChar.Comment;
                                showComment(dgvChars.Rows.Count - 1);
                                dgvChars.Rows[dgvChars.Rows.Count - 1].Selected = true;
                                */
                            }

                            //dgvChars.Columns[0].HeaderCell.SortGlyphDirection = SortOrder.None;
                            //dgvChars.Columns[1].HeaderCell.SortGlyphDirection = SortOrder.None;
                            for (int i = 0; i < dgvChars.Columns.Count; i++)
                            {
                                dgvChars.Columns[i].HeaderCell.SortGlyphDirection = SortOrder.None;
                            }

                            setEgvCharsSlotColor();
                            setEgvCharsNameColor();
                            setEgvCharsTextsColor();

                            dgvChars.ClearSelection();
                            for (int i = 0; i < dlcData2.Chars.Count; i++)
                            {
                                dgvChars.Rows[index0 + i].Selected = true;
                            }

                            /*
                            // 選択するのは一番上で。
                            try // 一つも読み込まれる前だとここで落ちる
                            {
                                dgvChars.Rows[index0].Selected = true;
                            }
                            catch
                            {
                                return;
                            }
                            */

                        }
                    }
                }
            }
            else if (kc == Keys.Delete && DeleteKeyUp)
            {
                DeleteKeyUp = false;

                btnCharsDelete_Click(null, null);

            }
            /*
            else if (e.KeyCode == Keys.Z && ZKeyUp && e.Control)
            {
                ZKeyUp = false;

                btnUndo_Click(null, null);

            }
            else if (e.KeyCode == Keys.Y && YKeyUp && e.Control)
            {
                YKeyUp = false;

                btnRedo_Click(null, null);
            }
            */
        }
        private void btnUndo_Click(object sender, EventArgs e)
        {
            if (undoBuffer == null || !undoBuffer.Undoable()) return;

            var c = GetSelectedCharacters();

            dlcData = undoBuffer.Undo();
            ApplyFullDLCDataInfoToUI(c);
            btnUndo.Enabled = undoBuffer.Undoable();
            btnRedo.Enabled = undoBuffer.Redoable();
        }
        private void btnOpenState_Click(object sender, EventArgs e)
        {
            try
            {

                var pt = GetOwnOFolderrExistingParent(LoadIniString("InitialDirectory", "LST"));
                if (pt != "") openFileDialogState.InitialDirectory = pt;
                openFileDialogState.FileName = Path.GetFileName(saveFileDialogState.FileName);
                if (ConformScrap() && openFileDialogState.ShowDialog() == DialogResult.OK)
                {
                    SaveIniString("InitialDirectory", "LST", Path.GetDirectoryName(openFileDialogState.FileName));
                    //dgvChars.Columns[0].HeaderCell.SortGlyphDirection = SortOrder.None;
                    //dgvChars.Columns[1].HeaderCell.SortGlyphDirection = SortOrder.None;
                    for (int i = 0; i < dgvChars.Columns.Count; i++)
                    {
                        dgvChars.Columns[i].HeaderCell.SortGlyphDirection = SortOrder.None;
                    }

                    if (openFileDialogState.FilterIndex == 1)
                    {
                        string orgpath = openFileDialogState.FileName;
                        string ext = Path.GetExtension(orgpath).ToLower();
                        //newDlc = true; // OpenStateFile で行われるけど tbListPath.Text 編集イベントの前にかえておかないといけない

                        OpenStateFile(openFileDialogState.FileName);

                    }
                    else
                    {

                        var bf = new BinaryFormatter();
                        using (var fs = new FileStream(openFileDialogState.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            dlcData = (DLCData)bf.Deserialize(fs);
                        }

                        newDlc = true;
                        tbListPath.Text = "";// newDLC より後で。
                        ClearMainUI();

                        MakeColumnsFromDLCData(dlcData);

                        tbSavePath.Text = dlcData.SavePath;
                        btnSave.Text = Program.dicLanguage["SaveDLC"]; ;
                        btnCmpSave.Enabled = btnSave.Enabled = true;
                        btnSaveState.Enabled = true;
                        btnCharsAdd.Enabled = true;
                        //clmCos.ReadOnly = false;
                        clmInner.ReadOnly = false;
                        tbBCMVer.Text = dlcData.BcmVer.ToString();

                        for (int i = 0; i < dlcData.Chars.Count; i++)
                        {
                            dgvChars.Rows.Add();
                            dgvChars.Rows[i].Cells[0].Value = GetCharNamesJpn(dlcData.Chars[i].ID);// Program.CharNamesJpn[dlcData.Chars[i].ID];
                            dgvChars.Rows[i].Cells[1].Value = dlcData.Chars[i].CostumeSlot.ToString();
                            dgvChars.Rows[i].Cells[2].Value = dlcData.Chars[i].AddTexsCount.ToString();

                            dlcData.Chars[i].Comment = "";// GetComment()";
                            //dgvChars.Rows[i].Cells[3].Value = dlcData.Chars[i].Comment;
                            showComment(i);

                        }
                        if (dlcData.Chars.Count > 0)
                        {
                            dgvChars.Rows[0].Selected = true;
                        }

                    }
                    saveFileDialogState.FileName = openFileDialogState.FileName;

                    setEgvCharsSlotColor();
                    setEgvCharsNameColor();
                    setEgvCharsTextsColor();
                    if (dgvChars.Rows.Count <= 0)
                    {
                        btnCharsDelete.Enabled = false;
                    }

                    undoBuffer = new UndoBuffer<DLCData>();
                    undoBufferUpdate();
                    undoBuffer.SetSaved();
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void btnNewDLC_Click(object sender, EventArgs e)
        {
            var pt = LoadIniString("InitialDirectory", "BCM");
            if (pt != "") saveFileDialog.InitialDirectory = GetOwnOFolderrExistingParent(Path.GetDirectoryName(pt));
            saveFileDialog.FileName = Path.GetFileName(openFileDialog.FileName);
            if (ConformScrap() && saveFileDialog.ShowDialog() == DialogResult.OK)
            {

                //MessageBox.Show("a");
                System.Text.RegularExpressions.Regex regex_doa = new System.Text.RegularExpressions.Regex(@"^(.*\\([^\\]+))\\\2\.bcm$",
                    System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                if (regex_doa.IsMatch(saveFileDialog.FileName))
                {
                    tbSavePath.Text = regex_doa.Replace(saveFileDialog.FileName, "$1");
                    SaveIniString("InitialDirectory", "BCM", Path.GetDirectoryName(saveFileDialog.FileName));

                }
                else
                {
                    tbSavePath.Text = saveFileDialog.FileName;
                    SaveIniString("InitialDirectory", "BCM", saveFileDialog.FileName);
                }

                newDlc = true;
                ClearMainUI();
                //tbSavePath.Text = saveFileDialog.FileName;
                dlcData = new DLCData();
                //btnSave.Text = Program.dicLanguage["SaveDLC"];
                setBtnSave();
                btnCmpSave.Enabled = btnSave.Enabled = true;
                btnSaveState.Enabled = true;
                btnCharsAdd.Enabled = true;
                //clmCos.ReadOnly = false;
                clmInner.ReadOnly = false;
                dlcData.BcmVer = 9;
                tbBCMVer.Text = "9";
                //dlcData.SavePath = saveFileDialog.FileName;

                cbSaveListInDLC.Enabled = true;
                cbSaveListInDLC.Checked = true;

                undoBuffer = new UndoBuffer<DLCData>();
                undoBufferUpdate();
                undoBuffer.SetSaved();

            }
        }