第29回 再生フォルダ読み込みをキャンセル可能にする


「プロジェクト」メニューにある「Windowsフォームの追加」から「ProgressForm.cs」を追加する。
そしてそこに
状況表示用のラベル「labelProgress」
キャンセルボタン「buttonCancel」
を配置し、ボタンをダブルクリックしてイベントハンドラーを自動生成。
そこにキャンセルボタンを押したらtrueとするbCancelプロパティを用意する。

あとはForm1.CreateFileListAndPlay()でProgressFormを開き、スレッド上を作ってそこで処理をさせる。
時間のかかるForm1.EnumFiles()でbCancelプロパティを随時参照してtrueになったら中断する。

■ProgressForm.cs
using System;
using System.Windows.Forms;

namespace MP3Player
{
	public partial class ProgressForm : Form
	{
		public bool bCancel
		{
			get { return _bCancel; }
		}
		bool _bCancel = false;

		public EventHandler<EventArgs> Canceled = null;

		public string strProgress
		{
			set
			{
				try
				{
					Invoke((MethodInvoker)delegate
					{
						labelProgress.Text = value;
					});
				}
				catch (Exception)
				{
				}
			}
		}

		public ProgressForm(string strTitle)
		{
			InitializeComponent();
			Text = strTitle;
		}

		private void buttonCancel_Click(object sender, EventArgs e)
		{
			try
			{
				_bCancel = true;
				if (Canceled != null)
					Canceled(null, null);
			}
			catch (Exception)
			{
			}

			try
			{
				Close();
			}
			catch (Exception)
			{
			}
		}
	}
}
■Form1.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Threading;			//追加
using System.Windows.Forms;
using WMPLib;

namespace MP3Player
{
	public partial class Form1 : Form
	{
		WindowsMediaPlayer _mediaPlayer = new WindowsMediaPlayer();

		System.Windows.Forms.Timer _timer = new System.Windows.Forms.Timer();		//変更

		public static Option _option = new Option();
		/// <summary>
		/// 設定フォルダから音楽ファイルリストを読み込む
		/// </summary>
		void CreateFileListAndPlay(bool bPlay)
		{
			buttonStop_Click(null, null);		//再生停止

			//再生リストのクリア
			_listPlayHistory.Clear();
			_listPlayNext.Clear();
			_nCurrentIndex = -1;

			ProgressForm dlg = new ProgressForm("再生フォルダの読み込み中");

			dlg.Show(this);

			Thread thread = new Thread(new ThreadStart(delegate
				{
					//mp3フォルダからの音楽ファイルリスト読み込み
					_listFiles = EnumFiles(_option.strFolder, dlg);

					try
					{
						Invoke((MethodInvoker)delegate
						{
							dlg.Close();
						});
					}
					catch (Exception)
					{
					}

					if (bPlay)
					{
						Invoke((MethodInvoker)delegate
						{
							Play();		//再生開始
						});
					}
				}));

			thread.Start();
		}



		/// <summary>
		/// フォルダ内のファイルを一覧して返す
		/// 
		/// dlg.bCancel==trueになったら処理を中断して抜ける
		/// </summary>
		List<AudioItem> EnumFiles(string strFolder, ProgressForm dlg = null)		//変更
		{
			List<AudioItem> ret = new List<AudioItem>();

			//指定フォルダ以下の全子フォルダから全ファイルを抜き出す
			IEnumerable<string> listFiles = Directory.EnumerateFiles(strFolder, "*.*", SearchOption.AllDirectories);
			//↑の処理は遅いが途中で中断できない

			foreach (string strFile in listFiles)
			{
				//追加
				if (dlg != null)
				{
					try
					{
						dlg.strProgress = "" + ret.Count;
						if (dlg.bCancel)
							break;
					}
					catch (Exception)
					{
					}
				}

				//見つかったファイルの拡張子を取り出し
				string strExt = Path.GetExtension(strFile).ToLower();
				if (strExt == "")
					continue;

				//mp3/m4aならそのまま追加
				if (strExt == ".mp3" || strExt == ".m4a")
				{
					ret.Add(new AudioItem(strFile));
					continue;
				}

				//ZIPファイルなら書庫に含まれるmp3/m4aファイルのエントリーを追加
				if (strExt == ".zip")
				{
					try
					{
						using (ZipArchive archive = ZipFile.OpenRead(strFile))
						{
							for (int i = 0; i < archive.Entries.Count; i++)
							{
								//追加
								if (dlg != null)
								{
									try
									{
										dlg.strProgress = "" + ret.Count;
										if (dlg.bCancel)
											break;
									}
									catch (Exception)
									{
									}
								}

								string strExtension = Path.GetExtension(archive.Entries[i].FullName).ToLower();
								if (strExtension == ".mp3" || strExtension == ".m4a")
								{
									ret.Add(new AudioItem(strFile, i));
								}
							}
						}
					}
					catch (Exception)
					{
					}
				}

			}

			return ret;
		}

プロジェクトファイルをダウンロード


カテゴリー「MP3プレーヤーを作る(C#)」 のエントリー