/////////////////////////////////////
// csFileList.cs for DLL
// Copyright (c) 06/19/2023 by ysama
/////////////////////////////////////
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;		//Assemblyを使う為
using System.Resources;			//リソース関係クラス等の使用の為
using System.IO;				//Stream関係クラス等の使用の為
using System.IO.Compression;	//ZipFileを使う為
using System.Diagnostics;		//Processを使用する為

namespace csFileList
{
/*	/////////////////////////////////////
	//エントリーポイントクラス
	//動的ライブラリー（DLL）にする場合、
	//MainAppクラスをすべて削除すること
	/////////////////////////////////////
	class MainApp
	{
		[STAThread]
		public static void Main()
		{
			//コマンドライン引数を配列で取得する
			string[] cmds = System.Environment.GetCommandLineArgs();	//先頭は実行ファイル名
			if(cmds.Length > 1)
			{
				string[] args = new string[cmds.Length - 1];
				Array.Copy(cmds, 1, args, 0, cmds.Length - 1);
				Application.Run(new FileList(args));
			}
			else
				Application.Run(new FileList());
		}
	}
*/
	///////////////////
	// FileListクラス
	///////////////////
	public partial class FileList : Form
	{
		//クラスメンバー変数
		ToolStrip toolStrip;				//ツールバー
		ToolStripButton[] toolStripButton;	//ツールバーボタン
		StatusStrip statusStrip;			//ステータスバー
		ToolStripStatusLabel[] tssl;		//ステータスバーラベル
		ListView file_List;					//ファイルリスト用リストビュー
		string[] fn_args = null;			//コマンドライン引数を参照する配列

		public FileList(string[] fns = null)
		{
			this.Load += new EventHandler(MainForm_Load);
			this.Text = "FileList";
			this.ClientSize = new Size(640, 341);	//Size = (656, 380);
			this.MinimumSize = new Size(656, 380);	//最小サイズ
			this.BackColor = SystemColors.Window;
			if(fns != null)
				fn_args = fns;
		}

		//WM_CREATE時処理
		private void MainForm_Load(object sender, EventArgs e)
		{
			//ツールバーとステータスバー作成
			SetBars();
			//コントロール作成
			InitControls();
		}
/*
		//WM_CLOSE時処理−DLLの場合は不要
		protected override void OnFormClosing(FormClosingEventArgs e)
		{
			base.OnFormClosing(e);
			DialogResult dr = MessageBox.Show("終了しますか？", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
			if(dr == DialogResult.No)
			{
				e.Cancel = true;
			}
		}
*/
		//ツールバーとステータスバーの設定
		protected void SetBars()
		{
			//フォームのレイアウトを一時停止
			this.SuspendLayout();
			//ツールバーの配置
			//ToolStripクラスインスタンスの生成
			this.toolStrip = new ToolStrip();
			//ツールバーのレイアウトを一時停止
			this.toolStrip.SuspendLayout();
			//ToolStripButton配列を作成
			this.toolStripButton = new ToolStripButton[9];
			//本プログラムの埋め込みリソースのリソースマネージャーを作成
			Assembly asm = Assembly.GetExecutingAssembly();
			ResourceManager rm = new ResourceManager("csFileList", asm);
			//アイコンをフォームにつける
			this.Icon = (Icon)rm.GetObject("Icon");
			//ツールバービットマップの読み込み
			ImageList imgList = new ImageList();
			imgList.ImageSize = new Size(16, 16);
			imgList.Images.AddStrip((Bitmap)rm.GetObject("ToolBar"));
			imgList.TransparentColor = Color.White;
			//ToolStripButton[0]を作成
			this.toolStripButton[0] = new ToolStripButton();
			this.toolStripButton[0].Text = "ファイルリストを開く(&O)";				//テキスト設定
			this.toolStripButton[0].Image = (Bitmap)imgList.Images[0];				//画像設定
			this.toolStripButton[0].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[0].Click += OnOpen_Click;							//Clickイベントハンドラ追加
			this.toolStrip.Items.Add(this.toolStripButton[0]);						//ボタンを追加
			//ToolStripButton[1]を作成
			this.toolStripButton[1] = new ToolStripButton();
			this.toolStripButton[1].Text = "ファイルリストの保存(&S)";				//テキスト設定
			this.toolStripButton[1].Image = (Bitmap)imgList.Images[1];				//画像設定
			this.toolStripButton[1].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[1].Click += OnSave_Click;							//Clickイベントハンドラ追加
			this.toolStripButton[1].Enabled = false;								//初期状態は無効
			this.toolStrip.Items.Add(this.toolStripButton[1]);						//ボタンを追加
			//セパレーターを挿入
			this.toolStrip.Items.Add(new ToolStripSeparator());
			//ToolStripButton[2]を作成
			this.toolStripButton[2] = new ToolStripButton();
			this.toolStripButton[2].Text = "終了(&X)";								//テキスト設定
			this.toolStripButton[2].Image = (Bitmap)imgList.Images[2];				//画像設定
			this.toolStripButton[2].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[2].Click += OnExit_Click;							//Clickイベントハンドラ追加
			this.toolStrip.Items.Add(this.toolStripButton[2]);						//ボタンを追加
			//セパレーターを挿入
			this.toolStrip.Items.Add(new ToolStripSeparator());
			//ToolStripButton[3]を作成
			this.toolStripButton[3] = new ToolStripButton();
			this.toolStripButton[3].Text = "ファイルを追加(&A)";					//テキスト設定
			this.toolStripButton[3].Image = (Bitmap)imgList.Images[3];				//画像設定
			this.toolStripButton[3].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[3].Click += OnAdd_Click;							//Clickイベントハンドラ追加
			this.toolStrip.Items.Add(this.toolStripButton[3]);						//ボタンを追加
			//ToolStripButton[4]を作成
			this.toolStripButton[4] = new ToolStripButton();
			this.toolStripButton[4].Text = "ファイルを除外(&R)";					//テキスト設定
			this.toolStripButton[4].Image = (Bitmap)imgList.Images[4];				//画像設定
			this.toolStripButton[4].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[4].Click += OnRemove_Click;						//Clickイベントハンドラ追加
			this.toolStripButton[4].Enabled = false;								//初期状態は無効
			this.toolStrip.Items.Add(this.toolStripButton[4]);						//ボタンを追加
			//セパレーターを挿入
			this.toolStrip.Items.Add(new ToolStripSeparator());
			//ToolStripButton[5]を作成
			this.toolStripButton[5] = new ToolStripButton();
			this.toolStripButton[5].Text = "削除(&D)";							//テキスト設定
			this.toolStripButton[5].Image = (Bitmap)imgList.Images[5];				//画像設定
			this.toolStripButton[5].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[5].Click += OnDelete_Click;						//Clickイベントハンドラ追加
			this.toolStripButton[5].Enabled = false;								//初期状態は無効
			this.toolStrip.Items.Add(this.toolStripButton[5]);						//ボタンを追加
			//ToolStripButton[6]を作成
			this.toolStripButton[6] = new ToolStripButton();
			this.toolStripButton[6].Text = "コピー(&C)";					//テキスト設定
			this.toolStripButton[6].Image = (Bitmap)imgList.Images[6];				//画像設定
			this.toolStripButton[6].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[6].Click += OnCopy_Click;							//Clickイベントハンドラ追加
			this.toolStripButton[6].Enabled = false;								//初期状態は無効
			this.toolStrip.Items.Add(this.toolStripButton[6]);						//ボタンを追加
			//ToolStripButton[7]を作成
			this.toolStripButton[7] = new ToolStripButton();
			this.toolStripButton[7].Text = "移動(&M)";								//テキスト設定
			this.toolStripButton[7].Image = (Bitmap)imgList.Images[7];				//画像設定
			this.toolStripButton[7].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[7].Click += OnMove_Click;							//Clickイベントハンドラ追加
			this.toolStripButton[7].Enabled = false;								//初期状態は無効
			this.toolStrip.Items.Add(this.toolStripButton[7]);						//ボタンを追加
			//ToolStripButton[8]を作成
			this.toolStripButton[8] = new ToolStripButton();
			this.toolStripButton[8].Text = "圧縮(&P)";								//テキスト設定
			this.toolStripButton[8].Image = (Bitmap)imgList.Images[8];				//画像設定
			this.toolStripButton[8].DisplayStyle = ToolStripItemDisplayStyle.Image;	//画像表示のみ
			this.toolStripButton[8].Click += OnCompress_Click;						//Clickイベントハンドラ追加
			this.toolStripButton[8].Enabled = false;								//初期状態は無効
			this.toolStrip.Items.Add(this.toolStripButton[8]);						//ボタンを追加
			//ツールバーの設定
			this.Controls.Add(this.toolStrip);
			//ツールバーのレイアウトを再開
			this.toolStrip.ResumeLayout(false);
			this.toolStrip.PerformLayout();
			//ステータスバーの配置
			//StatusStripクラスインスタンスの生成
			this.statusStrip = new StatusStrip();
			//ステータスバーのレイアウトを一時停止
			this.statusStrip.SuspendLayout();
			//ステータスバーにパネルとテキストを追加
			tssl = new ToolStripStatusLabel[3];
			tssl[0] = new ToolStripStatusLabel();
			tssl[0].BorderSides = ToolStripStatusLabelBorderSides.All;
			tssl[0].BorderStyle = Border3DStyle.SunkenInner;
			tssl[0].BackColor = SystemColors.Control;
			tssl[0].Text = "FileList Ver. 1.0";
			tssl[0].AutoSize = true;
			tssl[0].TextAlign = ContentAlignment.MiddleLeft;
			tssl[1] = new ToolStripStatusLabel();
			tssl[1].BorderSides = ToolStripStatusLabelBorderSides.All;
			tssl[1].BorderStyle = Border3DStyle.SunkenInner;
			tssl[1].BackColor = SystemColors.Control;
			tssl[1].Text = "（選択ファイル数）";
			tssl[1].ToolTipText = "（選択ファイル数）";	//ToolTip設定
			tssl[1].AutoSize = true;
			tssl[1].TextAlign = ContentAlignment.MiddleLeft;
			tssl[2] = new ToolStripStatusLabel();
			tssl[2].BorderSides = ToolStripStatusLabelBorderSides.All;
			tssl[2].BorderStyle = Border3DStyle.SunkenInner;
			tssl[2].BackColor = SystemColors.Control;
			tssl[2].Text = "（選択ファイル名）";
			tssl[2].ToolTipText = "（選択ファイル名）";	//ToolTip設定
			tssl[2].Spring = true;
			tssl[2].TextAlign = ContentAlignment.MiddleLeft;
			statusStrip.Items.AddRange(tssl);
			statusStrip.ShowItemToolTips = true;		//ToolTip表示
			this.Controls.Add(this.statusStrip);		//StatusStrip(ステータスバー)を追加
			//ステータスバーのレイアウトを再開
			this.statusStrip.ResumeLayout(false);
			this.statusStrip.PerformLayout();
			//メインフォームのレイアウトを再開
			this.ResumeLayout(false);
			this.PerformLayout();
		}

		//コントロールの設定
		protected void InitControls()
		{
			/////////////////////
			//コントロールの配置
			/////////////////////
			//リストビューの生成とプロパティの設定
			file_List = new ListView();
			file_List.Size = new Size(ClientSize.Width - 20, ClientSize.Height - toolStrip.Height - 10);	//サイズ
			file_List.Location = new Point(10,  toolStrip.Height);	//位置
			file_List.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right);
			file_List.FullRowSelect = true;				//一行選択
			file_List.GridLines = true;					//グリッドラインの表示
			file_List.MultiSelect = true;				//複数選択を許す
			file_List.HoverSelection = false;			//ポイントで選択できるようにする
			file_List.Activation = ItemActivation.OneClick;	//シングルクリック選択
			file_List.CheckBoxes = false;				//チェックボックス有効化
			file_List.View = View.Details;				//リストビューの表示方法
			//イベントハンドラの追加
			file_List.ColumnClick += new ColumnClickEventHandler(OnLV_ColumnClick);
			file_List.ItemSelectionChanged += new ListViewItemSelectionChangedEventHandler(OnLV_SelectionChanged);
			//ヘッダー定義
			file_List.Columns.Add("ファイル名", 200, HorizontalAlignment.Left);
			file_List.Columns.Add("ファイルパス", 416, HorizontalAlignment.Left);
			//Drag and Dropのイベントハンドラの追加
			file_List.DragEnter += new DragEventHandler(LV_DragEnter);
			file_List.DragDrop += new DragEventHandler(LV_DragDrop);
			file_List.AllowDrop = true;
			//FormにListViewを追加
			this.Controls.Add(file_List);
			//コンストラクター引数（ファイルパス、名）がある場合
			if(fn_args != null)
			{
				foreach(string fn in fn_args)
				{
					//ファイルが存在するか、フォールダーではないか、をチェックする
					if(!File.Exists(fn))
					{
						MessageBox.Show("このファイルは存在しません。\r\n" + fn, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
						continue;
					}
					ListViewItem item = file_List.Items.Add(Path.GetFileName(fn));
					item.SubItems.Add(Path.GetDirectoryName(fn));
				}
				//ツールバーボタンを有効化する
				ChangeToolBarStatus(true);
				//ファイル数を更新する
				ShowNumOfFiles();
			}
			else
				//ツールバーボタンを初期化する
				ChangeToolBarStatus(false);
		}

		//////////////////////////
		//ツールバー関連メソッド
		//////////////////////////
		//「ファイルリストを開く」処理
		private void OnOpen_Click(object sender, EventArgs e)
		{
			DialogResult dr = MessageBox.Show("ファイルリスト入れ替えますか（はい）、または\r\n追加しますか（いいえ）？", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
			if(dr == DialogResult.Yes)
			{
				file_List.Items.Clear();				//入替えの場合、リストビュー内の項目を全削除
			}
			OpenFileDialog ofDlg = new OpenFileDialog();
			ofDlg.Filter = "アルバムファイル(*.alb)|*.alb|プレイリストファイル(*.plf)|*.plf|すべてのファイル(*.*)|*.*";	//ファイルフィルターの指定
			ofDlg.FilterIndex = 1;						//ファイルフィルターインデックスの指定
			ofDlg.RestoreDirectory = true;				//ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
			ofDlg.CheckFileExists = true;				//存在しないファイルの名前が指定されたとき警告を表示する
			ofDlg.CheckPathExists = true;				//存在しないパスが指定されたとき警告を表示する
			ofDlg.InitialDirectory = @".\";				//デフォルトのフォルダを指定する
			ofDlg.Title = "ファイルリストを開く";		//ダイアログのタイトルを指定する
			if(ofDlg.ShowDialog() == DialogResult.OK)	//ダイアログを表示する
			{
				//ファイル("shift_jis")を開く
				using(StreamReader sr = new StreamReader(ofDlg.FileName, System.Text.Encoding.GetEncoding("shift_jis")))
				{
					//1行ずつ処理
					while(!sr.EndOfStream){
						string line = sr.ReadLine();
						//カンマで配列要素を分ける（最初の要素がファイルパス、名を前提とする）
		    			string[] fns = line.Split(',');
		    			//第1要素のファイルパス、名が'"'で括られていれば削除する
		    			string fn = fns[0].Trim('"');
						//ファイルが存在するか、フォールダーではないか、をチェックする
						if(!File.Exists(fn))
						{
							MessageBox.Show("このファイルは存在しません。\r\n" + fn, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
							continue;
						}
						ListViewItem item = file_List.Items.Add(Path.GetFileName(fn));
						item.SubItems.Add(Path.GetDirectoryName(fn));
					}
					sr.Close();
				}
				if(file_List.Items.Count > 0)
				{
					//ツールバーボタンを有効化する
					ChangeToolBarStatus(true);
					//ファイル数を更新する
					ShowNumOfFiles();
 				}
 			}
			else
			{
				MessageBox.Show("キャンセルされました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			//オブジェクトを破棄する
			ofDlg.Dispose();
		}

		//「ファイルリストを保存」処理
		private void OnSave_Click(object sender, EventArgs e)
		{
			//選択されたファイルパス、名をfilesに纏める
			string files = "";
			foreach(ListViewItem item in file_List.Items)
			{
				files += "\"" + item.SubItems[1].Text + "\\" + item.SubItems[0].Text + "\"\r\n";
			}
			//書き込みファイルを指定
			SaveFileDialog sfDlg = new SaveFileDialog();
			sfDlg.Filter = "アルバムファイル(*.alb)|*.alb|プレイリストファイル(*.plf)|*.plf|すべてのファイル(*.*)|*.*";	//ファイルフィルターの指定
			sfDlg.FilterIndex = 3;						//ファイルフィルターインデックスの指定
			sfDlg.RestoreDirectory = true;				//ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
			sfDlg.CheckPathExists = true;				//存在しないパスが指定されたとき警告を表示する
			sfDlg.InitialDirectory = @".\";				//デフォルトのフォルダを指定する
			sfDlg.Title = "ファイルリストを保存";		//ダイアログのタイトルを指定する
			if(sfDlg.ShowDialog() == DialogResult.OK)	//ダイアログを表示する
			{
				//ストリームで書き込む
				using(StreamWriter sw = new StreamWriter(sfDlg.FileName, false, System.Text.Encoding.GetEncoding("shift_jis")))	//falseは「上書き指定」
				{
					sw.Write(files);
					sw.Close();
				}
 			}
			else
			{
				MessageBox.Show("キャンセルされました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			//オブジェクトを破棄する
			sfDlg.Dispose();
		}

		//「終了」処理
		private void OnExit_Click(object sender, EventArgs e)
		{
			Close();
		}

		//「ファイルを追加」処理
		private void OnAdd_Click(object sender, EventArgs e)
		{
			OpenFileDialog ofDlg = new OpenFileDialog();
			ofDlg.Filter = "すべてのファイル(*.*)|*.*";	//ファイルフィルターの指定
			ofDlg.FilterIndex = 1;						//ファイルフィルターインデックスの指定
			ofDlg.RestoreDirectory = true;				//ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
			ofDlg.CheckFileExists = true;				//存在しないファイルの名前が指定されたとき警告を表示する
			ofDlg.CheckPathExists = true;				//存在しないパスが指定されたとき警告を表示する
			ofDlg.Multiselect = true;					//複数ファイルの選択を行う
			ofDlg.InitialDirectory = @".\";				//デフォルトのフォルダを指定する
			ofDlg.Title = "ファイルを開く";				//ダイアログのタイトルを指定する
			if(ofDlg.ShowDialog() == DialogResult.OK)	//ダイアログを表示する
			{
				foreach(string fn in ofDlg.FileNames)	//複数選択ファイル名コレクションの表示
				{
					ListViewItem item = file_List.Items.Add(Path.GetFileName(fn));
					item.SubItems.Add(Path.GetDirectoryName(fn));
				}
				if(file_List.Items.Count > 0)
				{
					//ツールバーボタンを有効化する
					ChangeToolBarStatus(true);
					//ファイル数を更新する
					ShowNumOfFiles();
 				}
 			}
			else
			{
				MessageBox.Show("キャンセルされました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			//オブジェクトを破棄する
			ofDlg.Dispose();
		}

		//「ファイルを除外」処理
		private void OnRemove_Click(object sender, EventArgs e)
		{
			if(file_List.SelectedItems.Count == 0)
			{
				MessageBox.Show("項目が選択されていません。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			else
			{
				DialogResult dr = MessageBox.Show("選択項目" + file_List.FocusedItem.Text + "（等）を削除しますか？", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
				if(dr == DialogResult.Yes)
				{
					foreach(ListViewItem item in file_List.SelectedItems)
					{
						//選択されたアイテムを削除する
						item.Remove();
					}
					if(file_List.Items.Count == 0)
						//ツールバーボタンを無効化する
						ChangeToolBarStatus(false);
					//ファイル数を更新する
					ShowNumOfFiles();
				}
			}
		}

		//「削除」処理
		private void OnDelete_Click(object sender, EventArgs e)
		{
			DialogResult dr = MessageBox.Show("リストの全ファイルを削除しますか？\r\n注意：削除するファイルのリストは予め「ファイルリストを保存」で作成してください。", "確認", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
			if(dr == DialogResult.Yes)
			{
				foreach(ListViewItem item in file_List.Items)
				{
					//全ファイルの削除
					try
					{
						File.Delete(item.SubItems[1].Text + "\\" + item.SubItems[0].Text);
						item.Remove();	//処理完了ファイルはリストから削除する
					}
					catch
					{
						MessageBox.Show(item.SubItems[1].Text + "\\" + item.SubItems[0].Text + "\r\nの削除に失敗しました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
						continue;
					}
				}
			}
		}

		//「コピー」処理
		private void OnCopy_Click(object sender, EventArgs e)
		{
			//「フォールダーを開く」処理
			FolderBrowserDialog fbDlg = new FolderBrowserDialog();
			fbDlg.Description = "コピー先のフォルダーを選択、または作成してください。";	//ダイアログの説明文
			fbDlg.SelectedPath = ".\\";					//デフォルトのフォルダー
			if(fbDlg.ShowDialog() == DialogResult.OK)	//フォルダを選択するダイアログを表示する
			{
				foreach(ListViewItem item in file_List.Items)
				{
					//全ファイルのコピー
					try
					{
						//既に同名ファイルがあった場合はエラーとなる（File.Copy(FromFile, ToFile, false)）
						File.Copy(item.SubItems[1].Text + "\\" + item.SubItems[0].Text, fbDlg.SelectedPath + "\\" + item.SubItems[0].Text);
						item.Remove();	//処理完了ファイルはリストから削除する
					}
					catch
					{
						MessageBox.Show(item.SubItems[1].Text + "\\" + item.SubItems[0].Text + "\r\nのコピーに失敗しました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
						continue;
					}
				}
			}
			else
			{
				MessageBox.Show("キャンセルされました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			//オブジェクトを破棄する
			fbDlg.Dispose();
		}

		//「移動」処理
		private void OnMove_Click(object sender, EventArgs e)
		{
			//「フォールダーを開く」処理
			FolderBrowserDialog fbDlg = new FolderBrowserDialog();
			fbDlg.Description = "移動先のフォルダーを選択、または作成してください。";	//ダイアログの説明文
			fbDlg.SelectedPath = ".\\";					//デフォルトのフォルダー
			if(fbDlg.ShowDialog() == DialogResult.OK)	//フォルダを選択するダイアログを表示する
			{
				foreach(ListViewItem item in file_List.Items)
				{
					//全ファイルの移動
					try
					{
						File.Move(item.SubItems[1].Text + "\\" + item.SubItems[0].Text, fbDlg.SelectedPath + "\\" + item.SubItems[0].Text);
						item.Remove();	//処理完了ファイルはリストから削除する
					}
					catch
					{
						MessageBox.Show(item.SubItems[1].Text + "\\" + item.SubItems[0].Text + "\r\nのコピーに失敗しました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
						continue;
					}
				}
			}
			else
			{
				MessageBox.Show("キャンセルされました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			//オブジェクトを破棄する
			fbDlg.Dispose();
		}

		//「圧縮」処理
		private void OnCompress_Click(object sender, EventArgs e)
		{
			//Zipファイル作成用の暫定フォールダーの作成
			string temp = ".\\Temp";
			Directory.CreateDirectory(temp);
			//全ファイルのコピー
			foreach(ListViewItem item in file_List.Items)
			{
				try
				{
					//既に同名ファイルがあった場合もエラーを出さない為に上書きする
					File.Copy(item.SubItems[1].Text + "\\" + item.SubItems[0].Text, temp + "\\" + item.SubItems[0].Text, true);
					item.Remove();	//処理完了ファイルはリストから削除する
				}
				catch
				{
					MessageBox.Show(item.SubItems[1].Text + "\\" + item.SubItems[0].Text + "\r\nの圧縮に失敗しました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
					continue;
				}
			}
			//「フォールダーを開く」処理
			FolderBrowserDialog fbDlg = new FolderBrowserDialog();
			fbDlg.Description = "圧縮先のフォルダーを選択、または作成してください。";	//ダイアログの説明文
			fbDlg.SelectedPath = ".\\";					//デフォルトのフォルダー
			if(fbDlg.ShowDialog() == DialogResult.OK)	//フォルダを選択するダイアログを表示する
			{	//Zipファイルの作成
				/*	注意：ZipFileの使用には,
					(1) "using System.IO.Compression;"と、
					(2) System.IO.Compression.FileSystemへの参照
					を追加する必要がある。*/
				ZipFile.CreateFromDirectory(temp, fbDlg.SelectedPath + "\\CompressedFileList.zip");
			}
			else
			{
				MessageBox.Show("キャンセルされました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			//オブジェクトを破棄する
			fbDlg.Dispose();
			//temp内全ファイルの削除
			DirectoryInfo temp_dir = new DirectoryInfo(temp);
			foreach(FileInfo file in temp_dir.GetFiles())
			{
				file.Delete();
			}
			//tempフォルダーの削除
			temp_dir.Delete(true);
		}

		///////////////////////////
		//コントロール関連メソッド
		///////////////////////////
		//file_Listのコラムがクリックされた時
		private void OnLV_ColumnClick(object sender, ColumnClickEventArgs e)
		{
			//ListViewItemSorterを指定する
			file_List.ListViewItemSorter = new ListViewItemComparer(e.Column);
			//正順、逆順交互に並び替える（ListViewItemSorterを設定するとSortが自動的に呼び出される）
		}

		//file_Listのアイテムが変更された時
		private void OnLV_SelectionChanged(Object sender, ListViewItemSelectionChangedEventArgs e)
		{
			if(file_List.SelectedItems.Count == 0)			//選択状態のチェック
			{
				tssl[2].Text = "（選択ファイル名）";
				tssl[2].ToolTipText = "（選択ファイル名）";	//ToolTip設定
			}
			else
			{
				tssl[2].Text = e.Item.Text;
				tssl[2].ToolTipText = e.Item.Text;			//ToolTip設定
			}
		}

		//file_Listにドラッグされた時
		private void LV_DragEnter(object sender, DragEventArgs e)
		{
			if(e.Data.GetDataPresent(DataFormats.FileDrop))
				e.Effect = DragDropEffects.Copy;
			else
				e.Effect = DragDropEffects.None;
		}

		//file_ListViewにドロップされたとき
		private void LV_DragDrop(object sender, DragEventArgs e)
		{
			//ドロップされたファイルパスを取得
			string[] ddlist =  (string[])e.Data.GetData(DataFormats.FileDrop, false);
			//ドロップされたデータをリストビューに追加する
			foreach(string fn in ddlist)
			{
				//ファイルが存在するか、フォールダーではないか、をチェックする
				if(!File.Exists(fn))
				{
					MessageBox.Show("このファイルは存在しません。\r\n" + fn, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
					continue;
				}
				ListViewItem item = file_List.Items.Add(Path.GetFileName(fn));
				item.SubItems.Add(Path.GetDirectoryName(fn));
 			}
			//ツールバーボタンを有効化する
			ChangeToolBarStatus(true);
			//ファイル数を更新する
			ShowNumOfFiles();
		}

		///////////////////////
		//FileList共通メソッド
		///////////////////////
		//ツールバーボタンの状態を有効、無効化する
		private void ChangeToolBarStatus(bool flag)
		{
			this.toolStripButton[1].Enabled = flag;
			for(int i = 4; i < 9; i++)
				this.toolStripButton[i].Enabled = flag;
		}

		//ファイル数を更新する
		private void ShowNumOfFiles()
		{
			tssl[1].Text = "ファイル数：" + file_List.Items.Count.ToString();
			tssl[1].ToolTipText = "ファイル数：" + file_List.Items.Count.ToString();	//ToolTip設定
		}

		//ファイルリストデータを取得する（DLL版用）
		public string[] GetFileList()
		{
			//ファイルリストデータ引き渡し用
			string[] flData = new string[file_List.Items.Count];
			for(int i = 0; i < file_List.Items.Count; i++)
			{
				flData[i] = file_List.Items[i].SubItems[1].Text + "\\" + file_List.Items[i].SubItems[0].Text;
			}
			return flData;
		}

		//FileListクラスインスタンスのリソース開放用Dispose()メソッド（Microsoft Docs）
		public void Dispose(int i = 0)
		{
			//アンマネージドリソースの開放
			Dispose(true);
			//ガーベージコレクション（終了抑制）
			GC.SuppressFinalize(this);
		}
	}
}

///////////////////////////////////////////
//ListViewの項目の並び替えに使用するクラス
///////////////////////////////////////////
public class ListViewItemComparer : IComparer
{
	private int m_column;
	private static int m_order = 1;	//毎回呼ばれるたびに正順、逆順を交代させるフラグ

	//ListViewItemComparerクラスのコンストラクタ
	public ListViewItemComparer(int col)
	{
		m_column = col;
		m_order *= -1;	//ListViewItemComparerが呼ばれる度に正順、逆順が変更される
	}

	//xがyより小さいときはマイナスの数、大きいときはプラスの数、同じときは0を返す
	public int Compare(object x, object y)
	{
		//ListViewItemの取得
		ListViewItem itemx = (ListViewItem) x;
		ListViewItem itemy = (ListViewItem) y;
		//xとyを文字列として比較する
		return string.Compare(itemx.SubItems[m_column].Text, itemy.SubItems[m_column].Text) * m_order;
	}
}
