以前、C#で簡単なMusic Playerを作成したのですが、ちょっと更新してみました。
主な変更点は、再生位置の表示をTrackbarからPictureBoxに変えたことです。Trackbarだと、使いにくかった。
ソースコードのご利用はご自由に。
using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Collections.Generic;
/*--------------------------------------------------*/
class Program
{
[STAThread]
static void Main()
{
Application.Run( new MusicPlayer());
}
}
/*--------------------------------------------------*/
class MusicPlayer : Form
{
/*--------------------------------------------------*/
[DllImport( "Winmm.dll")]
extern static int mciSendString( string cmd, System.Text.StringBuilder retStr, uint sieStr, IntPtr hwnd);
/*--------------------------------------------------*/
private MenuStrip ms;
private ToolStripMenuItem[][] tsmi;
private Label lblPlayList;
private ListBox lbx;
private PictureBox pbx;
private Label lblPosition;
private Label lblVolume;
private Button btnPlayStop;
private Button btnClose;
private Button btnVolumeDown;
private Button btnVolumeUp;
/*--------------------------------------------------*/
private const string DeviceID = "mysound";
private string filename = System.Environment.CurrentDirectory + @"\list.txt";
private List<string> lst;
private int position;
private int length;
private int volume; //1 to 5
private Timer tmr;
private enum MCIStatus
{
None,
Playing,
Stopped,
}
MCIStatus mst;
/*--------------------------------------------------*/
public MusicPlayer()
{
/*--------------------------------------------------*/
this.ClientSize = new Size( 280, 360);
this.Text = "Music Player";
/*--------------------------------------------------*/
this.CreateMenu();
/*--------------------------------------------------*/
this.CreateCtrl();
/*--------------------------------------------------*/
this.Load += new EventHandler( this.Form_Load);
this.Closed += new EventHandler( this.Form_Closed);
this.AllowDrop = true;
this.DragEnter += new DragEventHandler( this.Form_DragEnter);
this.DragDrop += new DragEventHandler( this.Form_DragDrop);
}
/*--------------------------------------------------*/
private void Form_Load( object sender, EventArgs e)
{
Console.WriteLine( "Form_Load");
this.lst = new List<string>();
this.LoadFileList();
this.position = 0;
this.length = 0;
this.volume = 3;
this.tmr = new Timer();
this.tmr.Interval = 1000;
this.tmr.Tick += new EventHandler( this.timer_Tick);
this.mst = MCIStatus.None;
this.timer_Tick( null, null);
}
private void Form_Closed( object sender, EventArgs e)
{
Console.WriteLine( "Form_Closed");
this.SaveFileList();
this.mciStop();
this.mciClose();
}
/*--------------------------------------------------*/
private void LoadFileList()
{
if( !File.Exists( this.filename))
{
using( File.Create( this.filename))
{
}
}
using( StreamReader sr = new StreamReader( this.filename))
{
while( -1 < sr.Peek())
{
string temp = sr.ReadLine();
Console.WriteLine( temp);
this.lst.Add( temp);
this.lbx.Items.Add( Path.GetFileName( temp));
}
}
}
private void SaveFileList()
{
using( StreamWriter sw = new StreamWriter( this.filename, false))
{
for( int i = 0; i < this.lst.Count; i++)
{
sw.WriteLine( this.lst[i]);
}
}
}
/*--------------------------------------------------*/
private void Form_DragEnter( object sender, DragEventArgs e)
{
if( e.Data.GetDataPresent( DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Move;
}
}
private void Form_DragDrop( object sender, DragEventArgs e)
{
string[] filenames = (string[]) e.Data.GetData( DataFormats.FileDrop, false);
this.lbx_Add( filenames);
}
/*--------------------------------------------------*/
/* Menuの作成 */
/*--------------------------------------------------*/
private void CreateMenu()
{
this.ms = new MenuStrip();
this.tsmi = new ToolStripMenuItem[1][];
this.tsmi[0] = new ToolStripMenuItem[5];
for( int i = 0; i < this.tsmi.Length; i++)
{
for( int j = 0; j < this.tsmi[i].Length; j++)
{
this.tsmi[i][j] = new ToolStripMenuItem();
}
}
this.tsmi[0][0].Text = "List (&L)";
this.tsmi[0][1].Text = "File (&F)";
this.tsmi[0][2].Text = "Add (&A)";
this.tsmi[0][3].Text = "Remove (&R)";
this.tsmi[0][4].Text = "Clear (&C)";
for( int i = 0; i < this.tsmi.Length; i++)
{
this.ms.Items.Add( this.tsmi[i][0]);
for( int j = 1; j < this.tsmi[i].Length; j++)
{
this.tsmi[i][0].DropDownItems.Add( this.tsmi[i][j]);
this.tsmi[i][j].Click += new EventHandler( this.Menu_Click);
}
}
this.Controls.Add( this.ms);
this.MainMenuStrip = ms;
}
/*--------------------------------------------------*/
/* Menuのイベント処理 */
/*--------------------------------------------------*/
private void Menu_Click( object sender, EventArgs e)
{
Console.WriteLine( sender.ToString());
if( sender == this.tsmi[0][1])
{
System.Diagnostics.Process.Start( "notepad.exe", this.filename);
}
else if( sender == this.tsmi[0][2])
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "All files | *.*";
ofd.Multiselect = true;
if( ofd.ShowDialog() == DialogResult.OK)
{
this.lbx_Add( ofd.FileNames);
}
}
else if( sender == this.tsmi[0][3])
{
this.lbx_Remove();
}
else if( sender == this.tsmi[0][4])
{
this.lbx_Clear();
}
}
/*--------------------------------------------------*/
/* コントロールの作成 */
/*--------------------------------------------------*/
private void CreateCtrl()
{
this.lblPlayList = new Label();
this.lblPlayList.SetBounds( 20, 30, 240, 30);
this.lblPlayList.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
this.lblPlayList.TextAlign = ContentAlignment.MiddleLeft;
this.lblPlayList.Text = "Play List";
//this.lblPlayList.BorderStyle = BorderStyle.FixedSingle;
this.Controls.Add( this.lblPlayList);
this.lbx = new ListBox();
this.lbx.SetBounds( 20, 60, 240, 180);
this.lbx.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
this.lbx.HorizontalScrollbar = true;
this.lbx.DoubleClick += new EventHandler( this.lbx_DoubleClick);
this.Controls.Add( this.lbx);
this.pbx = new PictureBox();
this.pbx.SetBounds( 20, 240, 240, 20);
this.pbx.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
this.pbx.BorderStyle = BorderStyle.FixedSingle;
this.pbx.BackColor = Color.LightGray;
this.pbx.Paint += new PaintEventHandler( this.pbx_Paint);
this.pbx.MouseClick += new MouseEventHandler( this.pbx_MouseClick);
this.Controls.Add( this.pbx);
this.lblPosition = new Label();
this.lblPosition.SetBounds( 20, 270, 140, 30);
this.lblPosition.Anchor = AnchorStyles.Bottom;
this.lblPosition.TextAlign = ContentAlignment.MiddleLeft;
this.lblPosition.Text = "Position : ";
//this.lblPosition.BorderStyle = BorderStyle.FixedSingle;
this.Controls.Add( this.lblPosition);
this.lblVolume = new Label();
this.lblVolume.SetBounds( 160, 270, 100, 30);
this.lblVolume.Anchor = AnchorStyles.Bottom;
this.lblVolume.TextAlign = ContentAlignment.MiddleRight;
this.lblVolume.Text = "Volume : ";
//this.lblVolume.BorderStyle = BorderStyle.FixedSingle;
this.Controls.Add( this.lblVolume);
this.btnPlayStop = new Button();
this.btnPlayStop.SetBounds( 20, 300, 80, 40);
this.btnPlayStop.Anchor = AnchorStyles.Bottom;
this.btnPlayStop.Text = "Play";
this.btnPlayStop.Click += new EventHandler( this.btnPlayStop_Click);
this.Controls.Add( this.btnPlayStop);
this.btnClose = new Button();
this.btnClose.SetBounds( 100, 300, 60, 40);
this.btnClose.Anchor = AnchorStyles.Bottom;
this.btnClose.Text = "Close";
this.btnClose.Click += new EventHandler( this.btnClose_Click);
this.Controls.Add( this.btnClose);
this.btnVolumeDown = new Button();
this.btnVolumeDown.SetBounds( 160, 300, 50, 40);
this.btnVolumeDown.Anchor = AnchorStyles.Bottom;
this.btnVolumeDown.Text = "Vol.-";
this.btnVolumeDown.Click += new EventHandler( this.btnVolumeDown_Click);
this.Controls.Add( this.btnVolumeDown);
this.btnVolumeUp = new Button();
this.btnVolumeUp.SetBounds( 210, 300, 50, 40);
this.btnVolumeUp.Anchor = AnchorStyles.Bottom;
this.btnVolumeUp.Text = "Vol.+";
this.btnVolumeUp.Click += new EventHandler( this.btnVolumeUp_Click);
this.Controls.Add( this.btnVolumeUp);
}
/*--------------------------------------------------*/
/* Listの処理 */
/*--------------------------------------------------*/
private void lbx_Add( string[] filenames)
{
for( int i = 0; i < filenames.Length; i++)
{
Console.WriteLine( filenames[i]);
this.lst.Add( filenames[i]);
this.lbx.Items.Add( Path.GetFileName( filenames[i]));
}
}
private void lbx_Remove()
{
if( this.lbx.SelectedIndex != -1)
{
this.lst.RemoveAt( this.lbx.SelectedIndex);
this.lbx.Items.RemoveAt( this.lbx.SelectedIndex);
}
}
private void lbx_Clear()
{
this.lst.Clear();
this.lbx.Items.Clear();
}
/*--------------------------------------------------*/
/* Buttonのイベント処理 */
/*--------------------------------------------------*/
private void btnPlayStop_Click( object sender, EventArgs e)
{
Console.WriteLine( "btnPlayStop_Click");
if( this.mst == MCIStatus.None)
{
this.OpenPlay();
}
else if( this.mst == MCIStatus.Playing)
{
this.mciStop();
this.mst = MCIStatus.Stopped;
this.btnPlayStop.Text = "Play";
this.tmr.Enabled = false;
this.timer_Tick( null, null);
}
else if( this.mst == MCIStatus.Stopped)
{
this.mciPlay();
this.mst = MCIStatus.Playing;
this.btnPlayStop.Text = "Stop";
this.tmr.Enabled = true;
this.timer_Tick( null, null);
}
}
private void btnClose_Click( object sender, EventArgs e)
{
Console.WriteLine( "btnClose_Click");
this.StopClose();
}
/*--------------------------------------------------*/
/* ListBoxのイベント処理 */
/*--------------------------------------------------*/
private void lbx_DoubleClick( object sender, EventArgs e)
{
Console.WriteLine( "lbx_DoubleClick");
this.StopClose();
this.OpenPlay();
}
/*--------------------------------------------------*/
/* Notify Event */
/* 再生中に、曲が終了して、次の曲があれば、再生する */
/*--------------------------------------------------*/
protected override void WndProc( ref Message m)
{
base.WndProc( ref m);
if( m.Msg == 0x03B9) //MM_MCINOTIFY message
{
Console.WriteLine( "Notify " + this.mst.ToString());
if( this.mst == MCIStatus.None)
{
return;
}
this.position = this.mciPosition();
if( this.position < this.length)
{
return;
}
this.StopClose();
if( ( this.lbx.SelectedIndex < 0) || ( this.lbx.Items.Count - 1 <= this.lbx.SelectedIndex))
{
return;
}
this.lbx.SelectedIndex++;
this.OpenPlay();
}
}
/*--------------------------------------------------*/
/* PictureBoxのイベント処理 */
/*--------------------------------------------------*/
private void pbx_MouseClick( object sender, MouseEventArgs e)
{
Console.WriteLine( "pbx_MouseClick");
if( this.mst == MCIStatus.None)
{
return;
}
if( 0 < this.pbx.Width)
{
Console.WriteLine( this.position);
this.position = this.length * e.X / this.pbx.Width;
Console.WriteLine( this.position);
this.mciSeek( this.position);
if( this.mst == MCIStatus.Playing)
{
this.mciPlay();
}
this.timer_Tick( null, null);
}
}
/*--------------------------------------------------*/
/* Volume */
/*--------------------------------------------------*/
private void btnVolumeDown_Click( object sender, EventArgs e)
{
Console.WriteLine( "btnVolumeDown_Click");
this.volume = Math.Max( 1, this.volume - 1);
if( this.mst != MCIStatus.None)
{
this.mciSetVolume( this.volume);
}
this.timer_Tick( null, null);
}
private void btnVolumeUp_Click( object sender, EventArgs e)
{
Console.WriteLine( "btnVolumeUp_Click");
this.volume = Math.Min( this.volume + 1, 5);
if( this.mst != MCIStatus.None)
{
this.mciSetVolume( this.volume);
}
this.timer_Tick( null, null);
}
/*--------------------------------------------------*/
/* タイマーイベント (表示の更新) */
/*--------------------------------------------------*/
private void timer_Tick( object sender, EventArgs e)
{
Console.WriteLine( "timer_tick");
if( this.mst != MCIStatus.None)
{
this.position = this.mciPosition();
}
this.pbx.Invalidate();
this.lblPosition.Text = "Pos : " + this.position.ToString() + " / " + this.length.ToString();
this.lblVolume.Text = "Vol : " + ( this.volume * this.volume * 40).ToString();
}
/*--------------------------------------------------*/
/* ピクチャーボックスの描画の更新 */
/*--------------------------------------------------*/
private void pbx_Paint( object sender, PaintEventArgs e)
{
Console.WriteLine( "pbx_Paint");
Graphics g = e.Graphics;
if( 0 < this.length)
{
g.FillRectangle( Brushes.Gray, 0, 0, this.pbx.Width * this.position / this.length, this.pbx.Height);
}
}
/*--------------------------------------------------*/
private void StopClose()
{
this.mciStop();
this.mciClose();
this.mst = MCIStatus.None;
this.btnPlayStop.Text = "Play";
this.tmr.Enabled = false;
this.timer_Tick( null, null);
}
private void OpenPlay()
{
if( this.lbx.SelectedIndex == -1)
{
return;
}
/*--------------------------------------------------*/
try
{
this.mciOpen( this.lst[this.lbx.SelectedIndex]);
}
catch( Exception err)
{
MessageBox.Show( err.ToString());
return;
}
/*--------------------------------------------------*/
this.length = this.mciLength();
this.position = 0;
/*--------------------------------------------------*/
this.mciSetVolume( this.volume);
/*--------------------------------------------------*/
this.mciPlay();
this.mst = MCIStatus.Playing;
this.btnPlayStop.Text = "Stop";
this.tmr.Enabled = true;
this.timer_Tick( null, null);
}
/*--------------------------------------------------*/
/* MCI Functions */
/*--------------------------------------------------*/
private void mciOpen( string filename)
{
string cmd = "open " + "\"" + filename + "\"" + " alias " + MusicPlayer.DeviceID;
int ret = mciSendString( cmd, null, 0, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
}
private void mciPlay()
{
string cmd = "play " + MusicPlayer.DeviceID + " notify";
int ret = mciSendString( cmd, null, 0, this.Handle);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
}
private void mciStop()
{
string cmd = "stop " + MusicPlayer.DeviceID;
int ret = mciSendString( cmd, null, 0, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
}
private void mciClose()
{
string cmd = "close " + MusicPlayer.DeviceID;
int ret = mciSendString( cmd, null, 0, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
}
private void mciSetVolume( int v)
{
string cmd;
int ret;
StringBuilder retStr = new StringBuilder( 256);
cmd = "status " + MusicPlayer.DeviceID + " volume";
ret = mciSendString( cmd, retStr, (uint) retStr.Capacity, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
cmd = "setaudio " + MusicPlayer.DeviceID + " volume to " + ( v * v * 40).ToString();
ret = mciSendString( cmd, null, 0, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
cmd = "status " + MusicPlayer.DeviceID + " volume";
ret = mciSendString( cmd, retStr, (uint) retStr.Capacity, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
}
private void mciSeek( int position)
{
string cmd = "seek " + MusicPlayer.DeviceID + " to " + position.ToString() + " wait";
int ret = mciSendString( cmd, null, 0, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
}
private int mciLength()
{
string cmd;
int ret;
StringBuilder retStr = new StringBuilder( 256);
cmd = "set " + MusicPlayer.DeviceID + " time format milliseconds";
ret = mciSendString( cmd, retStr, (uint) retStr.Capacity, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
cmd = "status " + MusicPlayer.DeviceID + " length";
ret = mciSendString( cmd, retStr, (uint) retStr.Capacity, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
return Convert.ToInt32( retStr.ToString());
}
private int mciPosition()
{
StringBuilder retStr = new StringBuilder( 256);
string cmd = "status " + MusicPlayer.DeviceID + " position";
int ret = mciSendString( cmd, retStr, (uint) retStr.Capacity, IntPtr.Zero);
Console.WriteLine( "cmd : " + cmd);
Console.WriteLine( "ret : " + ret.ToString());
return Convert.ToInt32( retStr.ToString());
}
}