基于MFC的音乐播放工具.docx
《基于MFC的音乐播放工具.docx》由会员分享,可在线阅读,更多相关《基于MFC的音乐播放工具.docx(22页珍藏版)》请在冰点文库上搜索。
基于MFC的音乐播放工具
《Windows编程》大作业
题目:
基于MFC的音乐播放工具
姓名:
学号:
班级:
专业:
软件工程
院系:
计算机与信息工程系
指导教师:
1、题目介绍:
基本要求:
1、播放常用音频格式
2、基本基本操作功能,例如开始,停止,声音调节等
3、具有播放列表,实现循环播放,顺序播放等
4、界面布局合理、美观;
2、系统分析:
我们本次的课程设计就是利用MFC强大而全面的类库,结合ActiveX控件资源开发一款简单而实用的音乐播放软件。
本次课程设计制作的多媒体播放器是利用Windows系统自带的WindowsMediaPlayer控件,可以分别通过按钮和菜单实现*.mp3、*.mid、*.avi、*.wmv、*.mpeg等媒体文件的打开、播放、暂停、全屏、音量调节、快进、快退、关闭等功能。
同时具备自制的播放列表,可以按照列表的顺序实现上一曲、下一曲的播放。
所要实现的功能,以及各个控件的功能特点设计软件的流程图。
可以实现打开播放器、初始化、打开文件、播放、暂停继续、停止、关闭、保存/清空列表、全屏、音量调节、快进快退、上/下一曲、关闭播放器等操作。
3、功能实现:
1.设计界面如下图所示,其中基本操作按钮有播放、暂停、快进、快退、音量增大、音量减小、上一曲、下一曲;播放模式按钮有单曲播放、单曲循环、循环播放、顺序播放;列表操作有删除歌曲、清空列表。
表1控件ID和变量关联表
控件
ID
变量类型
变量名
WMPlayer
IDC_OCX1
CWMPPlayer4
m_player
ListBox
IDC_MUSIC
CListBox
m_music
Button
IDC_PLAYMODE
CButton
m_playmode
表2按钮控件的ID和对应响应函数
控件Caption
ID
响应函数名
播放
IDC_PLAY
OnPlay()
暂停/继续
IDC_PAUSE
OnPause()
快进
IDC_SPEEDUP
OnSpeedup()
快退
IDC_SPEEDDOWN
OnSpeeddown()
->(音量增大)
IDC_ADDVOL
OnAddvol()
<-(音量减小)
IDC_DECVOL
OnDecvol()
上一曲
IDC_UPMUSIC
OnUpmusic()
下一曲
IDC_DOWNMUSIC
OnDownmusic()
单曲播放
IDC_SINGLEPLAY
OnSingleplay()
单曲循环
IDC_SINGLECYCLE
OnSingleclycle()
顺序播放
IDC_ORDERPLAY
OnOrderplay()
循环播放
IDC_CYCLEPLAY
OnCycleplay()
删除歌曲
IDC_DELETEMUSIC
OnDeletemusic()
清除列表
IDC_CLEARLIST
OnClearlist()
菜单如图:
2.代码实现
A.让程序只有一个实例:
BOOLCEllipseWndApp:
:
InitInstance()
{
//用应用程序名创建信号量
HANDLEhSem=CreateSemaphore(NULL,1,1,m_pszExeName);
//信号量已存在?
//信号量存在,则程序已有一个实例运行
if(GetLastError()==ERROR_ALREADY_EXISTS)
{
//关闭信号量句柄
CloseHandle(hSem);
//寻找先前实例的主窗口
HWNDhWndPrevious=:
:
GetWindow(:
:
GetDesktopWindow(),GW_CHILD);
while(:
:
IsWindow(hWndPrevious))
{
//检查窗口是否有预设的标记?
//有,则是我们寻找的主窗
if(:
:
GetProp(hWndPrevious,m_pszExeName))
{
//主窗口已最小化,则恢复其大小
if(:
:
IsIconic(hWndPrevious))
:
:
ShowWindow(hWndPrevious,SW_RESTORE);
//将主窗激活
:
:
SetForegroundWindow(hWndPrevious);
//将主窗的对话框激活
:
:
SetForegroundWindow(:
:
GetLastActivePopup(hWndPrevious));
//退出本实例
returnFALSE;
}
//继续寻找下一个窗口
hWndPrevious=:
:
GetWindow(hWndPrevious,GW_HWNDNEXT);
}
//前一实例已存在,但找不到其主窗
//可能出错了
//退出本实例
returnFALSE;
}
AfxEnableControlContainer();
//Standardinitialization
//Ifyouarenotusingthesefeaturesandwishtoreducethesize
//ofyourfinalexecutable,youshouldremovefromthefollowing
//thespecificinitializationroutinesyoudonotneed.
#ifdef_AFXDLL
Enable3dControls();//CallthiswhenusingMFCinasharedDLL
#else
Enable3dControlsStatic();//CallthiswhenlinkingtoMFCstatically
#endif
CEllipseWndDlgdlg;
m_pMainWnd=&dlg;
intnResponse=dlg.DoModal();
if(nResponse==IDOK)
{
//TODPlacecodeheretohandlewhenthedialogis
//dismissedwithOK
}
elseif(nResponse==IDCANCEL)
{
//TODPlacecodeheretohandlewhenthedialogis
//dismissedwithCancel
}
//Sincethedialoghasbeenclosed,returnFALSEsothatweexitthe
//application,ratherthanstarttheapplication'smessagepump.
returnFALSE;
}
intCEllipseWndDlg:
:
OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CDialog:
:
OnCreate(lpCreateStruct)==-1)
return-1;
//设置寻找标记
:
:
SetProp(m_hWnd,AfxGetApp()->m_pszExeName,(HANDLE)1);
return0;
}
voidCEllipseWndDlg:
:
OnDestroy()
{
CDialog:
:
OnDestroy();
//删除寻找标记
:
:
RemoveProp(m_hWnd,AfxGetApp()->m_pszExeName);
}
B.添加文件到播放列表:
voidCMusicplayDlg:
:
OnOpen()
{
//TODO:
Addyourcommandhandlercodehere
BROWSEINFObi;
charname[MAX_PATH];
ZeroMemory(&bi,sizeof(BROWSEINFO));
bi.hwndOwner=AfxGetMainWnd()->GetSafeHwnd();
bi.pszDisplayName=name;
bi.lpszTitle="选择文件夹目录";
bi.ulFlags=BIF_RETURNFSANCESTORS;
LPITEMIDLISTidl=SHBrowseForFolder(&bi);
CStringstrDirectoryPath;
if(idl!
=NULL)
{
SHGetPathFromIDList(idl,strDirectoryPath.GetBuffer(MAX_PATH));
strDirectoryPath.ReleaseBuffer();
if(!
strDirectoryPath.IsEmpty())
{
if(strDirectoryPath.Right
(1)!
="\\")
{
strDirectoryPath+="//";
strDirectoryPath.Replace("\\","//");
}
}
}
musicmymusic;
intindex;
CFileFindfinder;
BOOLbWorking=finder.FindFile(strDirectoryPath+"*.mp3");
while(bWorking)
{
bWorking=finder.FindNextFile();
mymusic.pathName=(CString)finder.GetFilePath();
mymusic.name=(CString)finder.GetFileName();
if((m_music.FindStringExact(-1,mymusic.name))!
=LB_ERR)
continue;
index=m_music.AddString(mymusic.name);
m_music.SetItemDataPtr(index,newmusic(mymusic));
index++;
}
Invalidate(false);
}
C.添加单首歌曲:
voidCMusicplayDlg:
:
OnAddmusic()
{
//TODO:
Addyourcommandhandlercodehere
CFileDialogdlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,_T("mp3文件(*.mp3)|*.mp3|打开所有文件(*.*)|*.*||"),this);
if(dlg.DoModal()==IDOK)
{
musicmymusic;
mymusic.pathName=dlg.GetPathName();
mymusic.name=dlg.GetFileName();
if((m_music.FindStringExact(-1,mymusic.name))!
=LB_ERR)
{
MessageBox("歌曲已存在!
!
");
return;
}
intindex=m_music.AddString(mymusic.name);
m_music.SetItemDataPtr(index,newmusic(mymusic));
index++;
}
}
D.播放歌曲:
主要获取选中的歌曲的pathName,运用m_player.SetUrl(PathName->pathName)函数来实现并且判断暂停按钮是否是继续,如是则改为暂停。
voidCMusicplayDlg:
:
OnPlay()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
if(m_music.GetCount()<=0)
{
MessageBox("请添加一首歌曲!
!
!
");
return;
}
if(m_music.GetCurSel()<0)
{
m_music.SetCurSel(0);
music*PathName=(music*)m_music.GetItemDataPtr(0);
if(PathName->pathName!
="")
{
m_player.SetUrl(PathName->pathName);
SetTimer(0,1000,NULL);
}
}
else
{
intindex=m_music.GetCurSel();
count=index;
music*PathName=(music*)m_music.GetItemDataPtr(count);
if(PathName->pathName!
="")
m_player.SetUrl(PathName->pathName);
}
CStringstrtemp;
GetDlgItemText(IDC_PAUSE,strtemp);
if(strtemp.Compare("继续")==0)
{
m_player.GetControls().play();
SetDlgItemText(IDC_PAUSE,"暂停");
}
UpdateData(false);
}
E.上一曲/下一曲:
(以上一曲为例)
主要通过count来记录当前播放歌曲,通过count来获取上一曲或下一曲的路径运用SetUrl()来实现歌曲的切换。
voidCMusicplayDlg:
:
OnUpmusic()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
if(count==0&&playMode==2)
count=m_music.GetCount()-1;
else
if(count!
=0)
{
count--;
}
else
return;
{
m_music.SetCurSel(count);
music*PathName=(music*)m_music.GetItemDataPtr(count);
if(PathName->pathName!
="")
m_player.SetUrl(PathName->pathName);
}
}
F.快进/快退:
(以快进为例)
voidCMusicplayDlg:
:
OnSpeedup()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
m_player.GetControls().fastReverse();
}
G.暂停/继续:
voidCMusicplayDlg:
:
OnPause()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CStringstrtemp;
if((m_player.GetPlayState()==2)||(m_player.GetPlayState()==3))
{
GetDlgItemText(IDC_PAUSE,strtemp);
if(strtemp.Compare("暂停")==0)
{
m_player.GetControls().pause();
SetDlgItemText(IDC_PAUSE,"继续");
}
if(strtemp.Compare("继续")==0)
{
m_player.GetControls().play();
SetDlgItemText(IDC_PAUSE,"暂停");
}
}
Invalidate(false);
}
H.加减声音:
(以加声音为例)
voidCMusicplayDlg:
:
OnAddvol()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
m_player.GetSettings().SetVolume(m_player.GetSettings().GetVolume()+10);
}
I.播放模式:
(以顺序播放为例)
用playmode来记录播放模式,利用OnTimer()函数来监控歌曲是否结束,根据模式来决定count的变化,来实现歌曲的播放模式。
voidCMusicplayDlg:
:
OnOrderplay()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
playMode=3;
m_playmode.SetWindowText("播放设置:
顺序播放");
UpdateData(false);
}
voidCMusicplayDlg:
:
OnTimer(UINTnIDEvent)
{
//TODO:
Addyourmessagehandlercodehereand/orcalldefault
if(m_player.GetPlayState()==1)
{
switch(playMode)
{
case0:
break;
case1:
if(count{
music*PathName=(music*)m_music.GetItemDataPtr(count);
if(PathName->pathName!
="")
m_player.SetUrl(PathName->pathName);
}
break;
case2:
if(count+1count++;
else
count=0;
{
m_music.SetCurSel(count);
music*PathName=(music*)m_music.GetItemDataPtr(count);
if(PathName->pathName!
="")
m_player.SetUrl(PathName->pathName);
}
break;
case3:
if(count+1count++;
else
break;
{
m_music.SetCurSel(count);
music*PathName=(music*)m_music.GetItemDataPtr(count);
if(PathName->pathName!
="")
m_player.SetUrl(PathName->pathName);
}
break;
}
}
CDialog:
:
OnTimer(nIDEvent);
}
J.保存歌曲:
voidCMusicplayDlg:
:
AddList()
{
CStdioFile*fsp=newCStdioFile(".\\myfile.txt",CFile:
:
modeRead);
CStringstr;
inti=0,index=-1;
musicmymusic;
while(fsp->ReadString(str))
{
if(i%2==0)
{
index++;
m_music.AddString(str);
mymusic.name=str;
}
else
{
mymusic.pathName=str;
m_music.SetItemDataPtr(index,newmusic(mymusic));
}
i++;
}
fsp->Close();
}
K.删除歌曲:
voidCMusicplayDlg:
:
OnDeletemusic()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
intindex=m_music.GetCurSel();
if(index!
=LB_ERR)
{
delete(music*)m_music.GetItemDataPtr(index);
m_music.DeleteString(index);
}
if(index!
=0)
{
m_music.SetCurSel(index-1);
}
else
m_music.SetCurSel(index);
}
L.删除所有歌曲:
voidCMusicplayDlg:
:
OnClearlist()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
if(AfxMessageBox("是否删除列表?
",MB_OKCANCEL,0)==IDOK)
for(intindex=m_music.GetCount()-1;index>=0;index--)
{
delete(music*)m_music.GetItemDataPtr(index);
m_music.DeleteString(index);
}
OnSavelist();
Invalidate(false);
}
M.背景图片:
boolCMusicplayDlg:
:
DrawBackground()
{
CClientDCdc(this);
CBitmapbit;
bit.LoadBitmap(IDB_BITMAP2);
CDCmdc;
mdc.CreateCompatibleDC(&dc);
CBitmap*oldbitmap=mdc.SelectObject(&bit);
CRectrect;
GetClientRect(&rect);
d