一个VC写的音乐播放器

    以前,一直想写一个音乐播放器,但VC还没有完全学完,有些东西还练的很少,实力还不够,这是学完VC后,练习了很多东西,看了不少VC的知识,所以才决定写的。

    这是2013年3月份写的,当时没有写在博客中,现在,将它写下来与大家分享,共同进步。

    1.首先,音乐播放器最基本的还是如何播放音乐,解决了这个问题,即使不用界面,也能播放音乐了。VC中的MCI可以播放音乐。(MCI(Media Control Interface)媒体控制接口是MircroSoft提供的一组多媒体设备和文件的标准接口它的好处是可以方便地控制绝大多数多媒体设备包括音频、视频、影碟、录像等多媒体设备而不需要知道它们的内部工作状况。但是古人云成也萧何败也萧何。MCI虽然看上去高大全但对于一些高级应用来说它是远远不够的。  上面的话也不是我说的但低级中级应用是完全凑合的。  MCI向Windows程序提供了在高层次上控制媒体设备接口的能力。程序不必关心具体设备就可以对激光唱机CD、视盘机、波形音频设备、视频播放设备和MIDI设备等媒体设备进行控制。对于程序员来说可以把MCI理解为设备面板上的一排按键通过选择不同的按键发送不同的MCI命令可以让设备完成各种功能而不必关心设备内部实现。比如对于play视盘机和CD机有不同的反应一个是播放视频一个播放音频而对用户来说却只需要按同一按钮。)

   2.其次,就是界面的设计,这可以仿照酷狗或QQ之类的播放器。

      1)显示音乐列表。(我用Access记录音乐文件的位置,这样方便查找歌曲,采用ADO方式访问数据库)

      2)播放暂停、前一首后一首、音量、歌词等按钮或控件。

      3)搜索音乐,将文件中的歌曲添加到音乐列表等。

      4)显示歌词。

截个图看看先:

                                  一个VC写的音乐播放器_第1张图片

由于当时的水平有限,虽然界面看起来还可以,但实际内部架构设计的不合理,没能很好地分类及应用好的设计模式(当时还没咋学设计模式),具体的代码就不传了。只将关键的技术或知识用代码让大家看一下:

1)由于要访问数据库,所以必须设计数据库的访问,这里我采用ADO的方式访问数据库,将其单独写在一个数据库连接类中(ADOConn)。

     该类只负责连接数据库,读取数据库中的数据、写数据并跟新到数据库中及关闭数据库链接等。这个类写好之后,只要是用ADO方式连接数据库,都可以直接拿去使用,复用性很好。

部分代码:

class ADOConn  
{
public:
	ADOConn();
	virtual ~ADOConn();
	void OnInitADOConn();
	void ExitConnect();
	_RecordsetPtr &GetRecordSet(_bstr_t bstrSQL);
	BOOL  ExecuteSQL(_bstr_t bstrSQL);
    _ConnectionPtr m_pConnection;
	_RecordsetPtr  m_pRecordset;
	
};

void ADOConn::OnInitADOConn()
{
	CMuscicPlayerApp *app=(CMuscicPlayerApp*)AfxGetApp();
	CString strpath=app->strPath;
	
	HRESULT hr;

   ::CoInitialize(NULL);       //初始化OLE/COM环境
	hr=m_pConnection.CreateInstance("ADODB.Connection");  //创建connection对象
	
	// 在ADO操作中建议语句中要常用try...catch()来捕获错误信息, 
	// 因为它有时会经常出现一些意想不到的错误。
	try                 
	{    
		if(SUCCEEDED(hr))
		{
			CString dbPath="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+strpath+"SongData.mdb";
	        hr=m_pConnection->Open(_bstr_t(dbPath),"","",adModeUnknown);
		}
	//	_bstr_t strConnect="Provider=SQLOLEDB;Server=LENOVO-PC;DataBase=Study;uid=sa;pwd=zyc123";
	//	m_pConnection->Open(strConnect,"","",adModeUnknown);
	} 
    //捕获异常
	catch(_com_error e)
	{
		AfxMessageBox(e.Description());
	}

}

void ADOConn::ExitConnect()
{
	//关闭记录集和连接
   if(m_pRecordset!=NULL)
		m_pRecordset->Close();
	m_pConnection->Close();
	//释放环境
	::CoUninitialize();

}
_RecordsetPtr& ADOConn::GetRecordSet(_bstr_t bstrSQL)
{
  try
  {
	  //连接数据库,如果conection对象为空,则重新连接数据库
	  if(m_pConnection==NULL)
		  OnInitADOConn();
	  //创建记录集对象
	  m_pRecordset.CreateInstance(__uuidof(Recordset));
	  //取得表中的记录
	  m_pRecordset->Open(bstrSQL,m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
  }
  catch(_com_error e)
  {
	  e.Description();
  }
  //返回记录集
  return m_pRecordset;
}
BOOL ADOConn::ExecuteSQL(_bstr_t _bstrSQL)
{
	_variant_t RecordsAffected;
	try
	{
		//是否已连接数据库
		if(m_pConnection==NULL)
			OnInitADOConn();
		m_pConnection->Execute(_bstrSQL,NULL,adCmdText);
		return true;
	}
	catch(_com_error e)
	{
		e.Description();
		return false;
	}
}


 

2)MCI播放音乐

代码:

//必要的参数声明
    MCI_OPEN_PARMS mciOpen;
    MCI_PLAY_PARMS mciPlay;
    MCI_DGV_SETAUDIO_PARMS mciSetAudioPara;
    UINT DeviceID;
    DWORD Volume;
    DWORD CdLen,Cdfrom;
                  //打开MCI
                  char buf[128]={0}; 
		MCIERROR mciError; 
		mciOpen.lpstrDeviceType = "mpegvideo"; 
		mciOpen.lpstrElementName = strFilePath;//播放文件的地址,支持格式mp3 
		mciError = mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,(DWORD)&mciOpen); 
		if(mciError) 
		{ 
			mciGetErrorString(mciError,buf,128); 
		} 
                  //播放
	           DeviceID = mciOpen.wDeviceID ; 
		CdLen = Getinfo(MCI_STATUS_LENGTH);
	         Cdfrom=MCI_MAKE_HMS(0,0,0);
		SetVolume();
		mciError = mciSendCommand(DeviceID,MCI_PLAY,0 ,(DWORD)&mciPlay); 
		if(mciError) 
		{ 
			MessageBox("send MCI_PLAY command failed!") ;
		}
                  //暂停
                      dwReturn = mciSendCommand(DeviceID,MCI_PAUSE,0 ,(DWORD)&mciPlay);
		if (dwReturn) {
			MessageBox("MCI stop error");
		}
                  //停止
	           DWORD dwReturn = 0;
                   dwReturn = mciSendCommand(DeviceID,MCI_STOP,0 ,(DWORD)&mciPlay);
                   //关闭MCI
                   dwReturn = mciSendCommand(DeviceID,MCI_CLOSE,0 ,(DWORD)&mciPlay);

3.读歌词,这部分实际就是读文件,只要将歌词文件中的时间读出来,然后与当前歌曲的播放时间进行比较,就可以确定显示哪一行歌词。

这是我写的读歌词代码,不是很好,但能读:

BOOL CMuscicPlayerDlg::OpenLyric()
{
       	double minute=0,second=0;
		int Length,i=0;
		
		CString strminute,strsecond;
        int nSongName=0,nSinger=0,al=0,by=0;

        CStdioFile file;   
		CFileException fileException;
		if(!file.Open(strLyricPath,CFile::modeRead,&fileException))    //逐行读取字符串 
		{
			//MessageBox("找不到该歌词文件");
			return FALSE;
		}
		while( file.ReadString( szLine ) )   
		{   
			//strText +="\n";
			//strText += szLine;   
           
			nSongName=szLine.Find("ti:");
			nSinger=szLine.Find("ar:");
			al=szLine.Find("al:");
			by=szLine.Find("by:");
			if(1==nSongName||1==nSinger||1==al||1==by)
			{
			Length=szLine.GetLength();
			szLine=szLine.Right(Length-4);
			Length=szLine.GetLength();
			szLine=szLine.Left(Length-1);
			minute=second=0.0;
			}
			else
			{
			   Length=szLine.GetLength();
               szLine=szLine.Right(Length-1);
               strminute=szLine.Left(2);
			   Length=szLine.GetLength();
			   szLine=szLine.Right(Length-3);
			   strsecond=szLine.Left(5);
               szLine=szLine.Right(Length-9);
			   minute=atof(strminute);
			   second=atof(strsecond);
			}
			StrLyric[i].strLyric=szLine;
			StrLyric[i].time=(DWORD)(minute*60+second)*1000;
			LyricLine=i;
			i++;		
		}   
		return TRUE;
}



 

你可能感兴趣的:(VC,音乐播放器)