VC课程设计.docx
《VC课程设计.docx》由会员分享,可在线阅读,更多相关《VC课程设计.docx(13页珍藏版)》请在冰豆网上搜索。
![VC课程设计.docx](https://file1.bdocx.com/fileroot1/2023-1/12/f0d9a8f6-8d65-4fc7-b872-523f1df47b57/f0d9a8f6-8d65-4fc7-b872-523f1df47b571.gif)
VC课程设计
一、课程设计要求:
设计题目三:
基于MFC的多媒体播放器系统实现
1.制作一个具有自己设计风格的媒体播放器。
2.要求能随机选取要播放的文件,实现前进,回退,暂停,循环播放,音量大小调节等基本功能。
3.要求能播放多种格式(至少三种以上)的音频视频格式文件。
4.可以实现其它附加功能(不在要求范围之内)
5.界面良好,功能完善
二、系统的简单操作及功能说明
1.简单操作
a.浏览按钮:
打开程序后点击浏览按钮后会弹出一个窗口,用于添加歌曲,使用者自己找到歌曲的路径并打开。
每次只能添加一首歌曲,并把歌曲的路径及其名字等放入播放列表中,并把歌曲的名字放入最近添加的编辑框中。
添加成功后,播放、暂停、停止键均由不可选变为可选状态。
b.播放按钮:
点击播放按钮后,自动执行load函数,并把当前窗口句柄传给load函数。
Load函数的主要作用是把音乐文件关联到设备。
关联前会清空上一次播放的设备,并将音乐路径传递给设备。
然后执行play播放函数。
当播放文件错误时会提示错误。
c.暂停按钮:
点击暂停按钮,执行onpause函数,设备会先获取按钮状态,若显示“暂停”时,执行pause函数,返回暂停消息。
并改变按钮状态到“恢复”。
如果获取到按钮状态为“恢复”时,则执行resume函数,并把按钮状态改为“暂停”。
d.停止按钮:
点击停止按钮,执行onstop函数,首先执行stop函数,把所有信息都清除,即终止音乐播放。
然后将暂停键上的状态重置为“暂停”,并将播放和暂停键均置为不可选状态。
e.上一曲按钮:
点击后执行onupper函数,首先获取当前列表框中选中项的下标,若下标为0,即选中列表框中第一项,则获得列表框中总项数,然后将最后一项的名称(路径名)传给设备,然后执行播放按钮的函数,并将列表框选中项选为当前播放的音乐文件(选中项下标判断)。
f.下一曲按钮:
点击后执行onnext函数。
获取当前选中项的下一项的下标,当为最后一项时,则返回第一项,并把该项的路径传递给设备,然后只想播放函数,然后将选中项更新为当前播放项。
g.音量滑块:
滑块用于音量控制,滑块被等分为1000,而实际使用时则作为整数100使用,打开时滑块默认位置是在50,即音量为50,通过滑块的滑动控制音量的大小,并将结果显示在滑块前的编辑框内。
h.播放列表:
每次添加歌曲时都会添加到播放列表中,列表中有一个参数和函数,实现在列表框中双击歌曲名字能够播放功能。
2.功能说明
本软件只能用于音频文件的播放,且只支持MP3WAVWMA三种格式,通过手动添加歌曲,且每次只能添加一首歌曲,添加后不能直接播放,需要点击播放按钮或者双击播放列表中的歌曲名字。
当播放列表中有大于一首歌时,点击上一曲/下一曲能够快捷切换播放歌曲,点击后会直接播放,直接在播放列表中双击某首歌曲的名字也会直接播放。
点击停止后,播放、暂停键均变为不可选状态,并且把暂停键重置为暂停。
软件通过滑动块控制声音,默认初始为50(满音量为100),当滑动滑块时会在前面的编辑框中显示音量数值。
三、分模块介绍
本程序主要分为添加歌曲、播放控制、列表控制三个模块。
1.添加歌曲即调用Onfilechoice函数,打开一个窗口,手动添加一首歌曲,将歌曲的路径关联到设备,为播放功能提供对象。
2.播放控制分为播放、暂停、恢复、停止、上/下一曲、音量控制子功能。
播放及调用Onplay函数,每次播放都是从0开始,返回消息MCI_PLAY。
每次点击播放都会从头播放,当正在播放某首歌曲时点击播放也会从头播放,这也是一个问题。
暂停及调用Onpause函数,返回消息MCI_PAUSE,并把暂停键标题改为恢复,以便执行恢复功能。
恢复即暂停后的继续播放,执行resume函数,点击后会将恢复重置为暂停。
停止即停止所播放歌曲,执行Onstop函数,然后将暂停或者恢复标题重置为暂停,并把播放和暂停键均置为不可选状态。
当播放列表中大于一首歌时可以使用按钮上/下一曲快捷切歌,且点击后不用点击播放而是直接播放,并将列表框中的光标标记到当前播放歌曲的位置。
如果在添加第一首歌后没有在列表框中双击播放而是直接点击播放按钮,列表框中的光标没有选中当前播放歌曲,这时点击下一曲时并不会换歌曲,而是把光标置为当前播放位置。
音量通过滑块控制,将滑块分为1000份,对应响应的音量大小,而实际调节时则将滑块的调节范围除以10,使之更易调节。
滑块默认在50,即相对应音量为50。
在调节音量的同时,相对应音量大小的数值则显示在前面的编辑框中,使调节更人性化。
3.列表控制即列表框内的控制。
列表框中有一个参数m_list,并有一个函数OnDblclkList1实现对列表框中歌曲双击能够播放功能。
列表框中光标位置还能为上一曲/下一曲功能提供位置标记。
另外背景图片是通过添加位图实现的,但有部分失真。
四、各模块源程序及注释
1.头文件及全局变量:
#include"stdafx.h"
#include"音乐播放器.h"
#include"音乐播放器Dlg.h"
#include"Mmsystem.h"
#include"Digitalv.h"
#pragmacomment(lib,"Winmm.lib")
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
//定义三个全局变量
HWNDm_hWnd;
DWORDDeviceID;
MCI_OPEN_PARMSmciopenparms;
CStringstrFilepath;
2.其他关键代码:
voidLoad(HWNDhWnd,CStringstrFilepath)
{
m_hWnd=hWnd;
mciSendCommand(DeviceID,MCI_CLOSE,0,0);//在加载文件前先清空上一次3.播放的设备
mciopenparms.lpstrElementName=strFilepath;//将音乐文件路径传给设备
DWORDdwReturn;
if(dwReturn=mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_ELEMENT|MCI_WAIT,(DWORD)(LPVOID)&mciopenparms))
{
//如果打开文件失败,则将出错信息储存在buffer,并显示出错警告
charbuffer[256];
mciGetErrorString(dwReturn,buffer,256);
MessageBox(hWnd,buffer,"出错警告!
",MB_ICONHAND|MB_ICONERROR|MB_ICONSTOP);
}
DeviceID=mciopenparms.wDeviceID;//打开文件成功就关联文件到设备
}
voidplay()//播放函数
{
MCI_PLAY_PARMSmciplayparms;//MCI_PLAY_PARMS包含定位信息的mci_play命令
mciplayparms.dwCallback=(DWORD)m_hWnd;
mciplayparms.dwFrom=0;//每次播放都是从0开始播放
mciSendCommand(DeviceID,MCI_PLAY,MCI_FROM|MCI_NOTIFY,(DWORD)(LPVOID)&mciplayparms);//MCI命令消息接口,传递播放MCI_PLAY命令
}
voidpause()//暂停函数
{
mciSendCommand(DeviceID,MCI_PAUSE,0,0);//返回暂定消息MCI_PAUSE
}
voidresume()//恢复函数
{
mciSendCommand(DeviceID,MCI_RESUME,0,0);//返回消息MCI_RESUME
}
voidstop()//停止函数
{
mciSendCommand(DeviceID,MCI_STOP,0,0);
mciSendCommand(DeviceID,MCI_CLOSE,0,0);
//当点击停止按钮时,将所有的信息都清除掉
}
DWORDsetvolume(DWORDvol)
{
MCI_DGV_SETAUDIO_PARMSsetvolume;//这是设置音量的参数数据结构
setvolume.dwCallback=NULL;
setvolume.dwItem=MCI_DGV_SETAUDIO_VOLUME;//动作是设置音量
setvolume.dwValue=vol;//音量值是vol
mciSendCommand(DeviceID,MCI_SETAUDIO,MCI_DGV_SETAUDIO_ITEM|MCI_DGV_SETAUDIO_VALUE,(DWORD)(LPVOID)&setvolume);
return0;
}
4.添加歌曲:
voidCMyDlg:
:
Onfilechoice()//打开文件添加音乐
{
charszFileFilter[]="mp3文件(*.mp3)|*.mp3|"
"wma文件(*.wma)|*.wma|"
"wav文件(*.wav)|*.wav|"
"所有文件(*.*)|*.*|";
CFileDialogdlg(true,NULL,NULL,OFN_HIDEREADONLY,szFileFilter);//打开一个对话框
POSITIONpos=dlg.GetStartPosition();//取第一个迭代器
if(dlg.DoModal()==IDOK)//弹出了对话框
{
while(pos!
=NULL)
{
CStringm_pathname=dlg.GetNextPathName(pos);
m_list.AddString(m_pathname);//将路径名传给列表框的路径
strFilepath=dlg.GetPathName();
CStringstrFilename=dlg.GetFileName();//将打开文件的名字传给编辑框
SetDlgItemText(IDC_filename,strFilename);
//Load(this->m_hWnd,strFilepath);
//GetDlgItem(IDC_play)->EnableWindow(true);//文件读取成功时所有按钮变可选的
//GetDlgItem(IDC_pause)->EnableWindow(true);
//GetDlgItem(IDC_stop)->EnableWindow(true);
}//将选中的文件加入到播放列表中//TODO:
AddyourcontrolnotificationhandlercodehereTODO:
Addyourcontrolnotificationhandlercodehere
}
}
5.播放:
voidCMyDlg:
:
Onplay()
{
Load(this->m_hWnd,strFilepath);
play();//TODO:
Addyourcontrolnotificationhandlercodehere
}
6.暂停:
voidCMyDlg:
:
Onpause()
{
CStringstrtemp;
GetDlgItemText(IDC_pause,strtemp);//获取按钮状态
if(strtemp.Compare("暂停")==0)//TODO:
Addyourcontrolnotificationhandlercodehere
{
pause();//执行暂停函数
SetDlgItemText(IDC_pause,"恢复");//将按钮置为恢复
}
if(strtemp.Compare("恢复")==0)
{
resume();
SetDlgItemText(IDC_pause,"暂停");
}
}
7.停止:
voidCMyDlg:
:
Onstop()
{
stop();//执行停止函数
SetDlgItemText(IDC_pause,"暂停");//将暂停或者恢复重置为暂停
GetDlgItem(IDC_play)->EnableWindow(false);//当stop按钮按下时,播放和暂停应该均不可用
GetDlgItem(IDC_pause)->EnableWindow(false);//TODO:
Addyourcontrolnotificationhandlercodehere
}
8.上一曲:
voidCMyDlg:
:
Onupper()
{
CStringstr;
Intindex=m_list.GetCurSel();//获得当前在列表框中所选项的下标
if(index==0)
index=m_list.GetCount();//如果下标为0表明为第一项,则将获得列表框中总项数
m_list.GetText(index-1,str);
mciopenparms.lpstrElementName=str;//将音乐文件路径传给设备
Load(this->m_hWnd,str);//以当前句柄和音乐文件路径为参数执行函数
play();
m_list.SetCurSel(index-1);//将下标置为上一项,即选中所播放的音乐TODO:
Addyourcontrolnotificationhandlercodehere
}
9.下一曲:
voidCMyDlg:
:
Onnext()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CStringstr;
intindex=m_list.GetCurSel()+1;//光标加一
if(index>=m_list.GetCount())
index=0;//如果播放完最后一曲就自动播放第一首
m_list.GetText(index,str);//获得当前光标所指的路径字符串
mciopenparms.lpstrElementName=str;//将音乐文件路径传给设备
Load(this->m_hWnd,str);
play();
m_list.SetCurSel(index);//自动置光标
}
10.音量控制:
voidCMyDlg:
:
OnCustomdrawSlider(NMHDR*pNMHDR,LRESULT*pResult)
{
UpdateData(true);
m_int=m_slider.GetPos()/10;//将滑块的值除以10后赋给编辑框的参数
setvolume(m_slider.GetPos());//调节声音
UpdateData(false);//TODO:
Addyourcontrolnotificationhandlercodehere
*pResult=0;
}
11.列表框:
voidCMyDlg:
:
OnDblclkList1()
{
CStringstr;
intindex=m_list.GetCurSel();//获取选择的行数
m_list.GetText(index,str);
mciopenparms.lpstrElementName=str;//将音乐文件路径传给设备
Load(this->m_hWnd,str);
play();
CStringstrFilepath=str;
//SetTimer(1,1000,NULL);//TODO:
Addyourcontrolnotificationhandlercodehere
}
五、程序界面截图
1.程序运行时的界面
2.添加音乐的界面
3.播放界面
4.暂停界面
5.停止界面
6.音量调节及上/下曲界面
7.出错界面
六、遇到问题及解决方法
1.调试错误:
a.
原因:
忘记将strFilepath设置为全局变量。
StrFilepath是存储文件路径的变量。
b.无法添加歌曲后无法正常播放音乐。
原因:
在Onplay函数中直接调用play函数,没有提前调用load函数,没有将音乐路径传递给设备,致使播放函数找不到文件,使得无法播放。
c.滑块无法正常控制音量大小
原因:
在滑块的函数中没有使用UpdataData函数,致使滑块滑动后音量没有更新,导致无法实时控制音量。
d.
原因:
丢掉了头文件#include"Digitalv.h"引起错误
e.添加背景图片不成功
原因:
除了要引入位图外还要再Onpaint函数中添加代码将原函数中else部分改为
else
{
//CDialog:
:
OnPaint();
CPaintDCdc(this);
CRectrect;
GetClientRect(&rect);
CDCdcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmapbmpBackground;
bmpBackground.LoadBitmap(IDB_BITMAP2);
BITMAPbitmap;
bmpBackground.GetBitmap(&bitmap);
CBitmap*pbmpOld=dcMem.SelectObject(&bmpBackground);
dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
}
七、参考文献
《基于MFC的简单音乐播放器》