
设计题目:五子棋的设计
学院、系:电子与信息工程学院
专业班级:计算机09-2
学生姓名:于洋
指导教师:滕薇龙艳彬
成绩:
2011年7 月8 日摘要
本播放软件主要实现MP3 、wav媒体文件的播放,包括包括播放、循环播放多个媒体文件、暂停、返回、上一首、下一首、导入单个文件、导入文件夹、删除选择的文件、滑块显示和设置播放进度、滑块显示和设置音量,显示播放列表,可以直接双击列表框文件打开文件等功能。本软件还有一个特殊功能,如果播放文件不是播放器所支持的类型,则播放器自动将自动把不能播放的文件移除,播放器采用了贴图进行界面的美化。
目录
1 第一章绪论
1.1 开发背景
1.2 目的
1.3 意义
1.4 开发工具简介
2 第二章需求分析
2.1 系统要处理的信息
2.2 对信息要求处理的功能
3 第三章总体设计
3.1 系统功能模块层次图
3.2 功能简介
3.3 主要功能的流程图
4 第四章详细设计与实现
4.1 总要窗体界面
4.2 核心代码
5 第五章测试
5.1 测试方法
5.2 测试用例
5.3 测试结论
6 结论7 致谢
8 参考文献关键词:MFC、CPlayerDlg、播放、导入
第一章绪论
1.1 开发背景
音乐具有陶冶人情操的作用,要实现音乐的播放,就得有一个音乐播放器。
1.2 目的
实现音乐的播放,掌握MFC 的一些应用,提升编程能力。1.3 意义
了解音乐接口函数的使用,提升管理程序框架的能力。
1.4 开发工具简介
Microsoft® Visual C++ 6.0 是微软公司开发的一款应用C++开发软件的编辑、编译,调试软件,包涵强大的MFC。
第二章需求分析
2.1 系统要处理的信息
1、检查当前选择的音乐
2、检测当前音乐是否播放完
3、将音乐文件解码
2.2 对信息要求处理的功能
1、当按播放音乐时检查当前选择的音乐
2、当播放音乐时检测音乐是否播放完
3、将音乐数据由系统函数导入并音乐文件解码第三章总体设计
3.1 系统功能模块层次图
导入模块
显示模块
操作模块
系统播放模块
3.2 功能简介
1、打开文件:打开单个文件
2、导入文件夹:导入文件夹里可播放的所有文件
3、播放列表:显示当前导入的文件,双击可播放
4、选择音乐:单击要选择的音乐
5、删除:删除选择的音乐
6、播放:播放选择的音乐
7、暂停:暂停正在播放的音乐
8、返回:返回到打开音乐的开端
9、下一首:播放下一首歌
10、上一首:播放上一首歌
3.3 主要功能的流程图
第四章 详细设计与实现
4.1 总要窗体界面
如图
4.1
图4.1 打开文件 导入文件夹
形成播放列表 选择音乐 播放 暂停 返回 下一首 上一首 删除
1、初始化界面,主要将一些按键绘上图标
2、BOOL CPlayerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
RePlay=false;
i_PlayTime=0;
m_SetV olume.SetRange(0,1000); //进度条.SetRange(0,255)
m_SetV olume.SetPos(m_Music.GetV olume());//音量控件同步
m_StopReFrist.ModifyStyle(0,0,IDB_BITMAP2);//控件2载入位图,设置按钮风格
m_StopReFrist.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRES OURCE(IDB_BITMAP2))); //加载位图
m_Play.ModifyStyle(0,0,IDB_BITMAP1);//控件2载入位图,设置按钮风格m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP1))); //加载位图
m_rePlay.ModifyStyle(0,0,IDB_BITMAP4);//控件2载入位图,设置按钮风格m_rePlay.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOUR CE(IDB_BITMAP4))); //加载位图
m_UpPlay.ModifyStyle(0,0,IDB_BITMAP5);//控件2载入位图,设置按钮风格m_UpPlay.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOU RCE(IDB_BITMAP5))); //加载位图
m_DowmPlay.ModifyStyle(0,0,IDB_BITMAP6);//控件2载入位图,设置按钮风格
m_DowmPlay.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRES OURCE(IDB_BITMAP6))); //加载位图
SetTimer(1,500,NULL);
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMe nu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small iconreturn TRUE; // return TRUE unless you set the focus to a control
}
void CPlayerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
2、绘制桌面函数,主要实现桌面背景载入图片
void CPlayerDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (IsIconic())
{
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
HBITMAP bmpHandle =(HBITMAP)LoadImage(NULL,"F:\\\\c++\\\\项目\\\\位图5\\\\2.bmp
CBitmap bmpPicture;
CDC mdcPicture;
CBitmap *bmpFromHandle=bmpPicture.FromHandle(bmpHandle);
CRect rectPicture;
rectPicture.left=20;rectPicture.right=100;
rectPicture.bottom=100;
rectPicture.top=10;
mdcPicture.CreateCompatibleDC(&dc);
CBitmap *bmpPrevious=mdcPicture.SelectObject(bmpFromHandle);
ScreenToClient(&rectPicture);
dc.BitBlt(0,0,800,500,&mdcPicture,0,0,SRCCOPY);
dc.SelectObject(bmpHandle);
}
HCURSOR CPlayerDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
3、响应单击返回按钮,当单击时改变播放按钮的图标并停止播放
void CPlayerDlg::OnStopReFirst()
{
// TODO: Add your control notification handler code here
m_Play.ModifyStyle(0,0,IDB_BITMAP1);//控件1载入位图,设置按钮风格m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP1))); //控件1加载位图
m_Music.Play(m_Music.GetV olume(),0,1);
m_Music.Stop();
i_PlayTime=0;
}
void CPlayerDlg::OnReleasedcaptureSetShowLongth(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
if(m_Music.GetPlayState())
{
i_PlayTime= 2 * m_SetShowLongth.GetPos();
m_Music.SetPlayto(1000 * i_PlayTime);
}
*pResult = 0;
}
4、定时器响应函数,每隔0.5S调用一次此函数,它主要实现检测播放进度,更新播放进度滑块的显示,和检测播放的状态实现循环播放
void CPlayerDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
nIDEvent=1;
if(m_Music.GetPlayState())
{char szCommand[50];
sprintf(szCommand," Status %ld fgfdg %d
if(i_PlayTime/2 i_PlayTime++; } else { OnStopReFirst() ; i_PlayTime=0; } m_Play.ModifyStyle(0,0,IDB_BITMAP3);//载入位图,设置按钮风格m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP3))); //加载位图 } else { m_Play.ModifyStyle(0,0,IDB_BITMAP1);//载入位图,设置按钮风格m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP1))); //加载位图 } m_SetShowLongth.SetPos(i_PlayTime/2); if(RePlay) { if(!m_Music.GetPlayState()) { fr++; m_list.SetCurSel(fr); if(fr m_list.GetText(fr,szPath); i_PlayTime=0; if(!m_Music.OPen(szPath.GetBuffer(NULL)) ) { m_list.DeleteString(fr); } m_Music.Play(m_Music.GetV olume(),0,1); } else { fr=0; } } } } 5、音量控制滑块,移动滑块条响应音乐音量的控制 void CPlayerDlg::OnReleasedcaptureV olume(NMHDR* pNMHDR, LRESULT* pResult) { m_Music.SetV olume(m_SetV olume.GetPos()); *pResult = 0; } void CPlayerDlg::OnPlay() { // TODO: Add your control notification handler code here RePlay=false; if(b_PlayOrStop) { m_Play.ModifyStyle(0,0,IDB_BITMAP3);//载入位图,设置按钮风格m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP3))); //加载位图 if(i_PlayTime==0) { fr=m_list.GetCurSel() ; m_list.GetText(fr,szPath); if(!m_Music.OPen(szPath.GetBuffer(NULL))) { m_list.DeleteString(fr); fr++; if(fr>=m_list.GetCount()) { fr=0; } m_list.SetCurSel(fr); } } m_Music.Play(m_Music.GetV olume(),0,0); i_MusicLongth = m_Music.GetLongth(); m_SetShowLongth.SetRange(0,i_MusicLongth/1000); //进度条.SetRange(0,255) m_SetShowLongth.SetPos(i_PlayTime); //进度控件同步 b_PlayOrStop=false; } else { m_Play.ModifyStyle(0,0,IDB_BITMAP1);//载入位图,设置按钮风格 m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP1))); //加载位图 m_Music.Stop(); b_PlayOrStop=true; } } 6、打开文件,打开某个需要播放的文件,如果文件被打开则更新按钮的图标,如文件不能被设备打开此文件,则移除此文件,更新播放列表 void CPlayerDlg::OnOnSthing() { CFileDialog openDlg(true,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT| OFN_EXPLORER); if(openDlg.DoModal()==IDOK) { i_PlayTime=0; CString path =openDlg.GetPathName(); m_list.AddString (path) ; fr=m_list.GetCurSel() ; szPath=path;"; i_PlayTime=0; m_Music.OPen(szPath.GetBuffer(NULL)); m_Music.Play(m_Music.GetV olume(),0,0); i_MusicLongth = m_Music.GetLongth(); m_SetShowLongth.SetRange(0,i_MusicLongth/1000);//进度条.SetRange(0,255) m_SetShowLongth.SetPos(i_PlayTime); //进度控件同步 m_Play.ModifyStyle(0,0,IDB_BITMAP3);//载入位图,设置按钮风格m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP3))); //加载位图 } } 7、响应双击列表框某个文件,并播放双击的文件,如果文件被打开则更新按钮的图标。 void CPlayerDlg::OnDblclkList3() { // TODO: Add your control notification handler code here fr=m_list.GetCurSel () ; m_list.GetText(fr,szPath); i_PlayTime=0; m_Music.OPen(szPath.GetBuffer(NULL)); m_Music.Play(m_Music.GetV olume(),0,0);i_MusicLongth = m_Music.GetLongth(); m_SetShowLongth.SetRange(0,i_MusicLongth/1000); //进度条.SetRange(0,255) m_SetShowLongth.SetPos(i_PlayTime); //进度控件同步 m_Play.ModifyStyle(0,0,IDB_BITMAP3);//载入位图,设置按钮风格 m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP3))); //加载位图 } 8、响应导入按钮,可导入文件夹下的MP3、wav文件,并且更新播放列表void CPlayerDlg::OnDaoRu() { CString strInitFolder = _T(""); TCHAR szPath[MAX_PA TH] = _T(""); LPMALLOC lpMalloc = NULL; CString strFolder = _T(""); BROWSEINFO sInfo; LPITEMIDLIST lpidlBrowse = NULL; if (::SHGetMalloc(&lpMalloc) != NOERROR) AfxMessageBox("错误!"); ::ZeroMemory(&sInfo, sizeof(BROWSEINFO)); sInfo.pidlRoot = 0; sInfo.pszDisplayName = szPath; sInfo.lpszTitle = _T("请选择您需要的目的文件夹:"); sInfo.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS; sInfo.lpfn = NULL; // 显示文件夹选择对话框 lpidlBrowse = ::SHBrowseForFolder(&sInfo); if (lpidlBrowse != NULL) { // 取得文件夹名 if (::SHGetPathFromIDList(lpidlBrowse, szPath)) { strFolder = szPath; CFileFind m_CFile; CFileFind m_CFile1; int CallNum=0; CString m_szDir1=strFolder; CString m_szDir=strFolder; if(m_szDir1.Right(1)!="\\\\") m_szDir1+="\\\\";m_szDir1+= "*.wav"; //查找的类型"*.* BOOL res1=m_CFile1.FindFile(m_szDir1); if(m_szDir.Right(1)!="\\\\") m_szDir+="\\\\"; m_szDir+= "*.mp3"; //查找的类型"*.* BOOL res=m_CFile.FindFile(m_szDir); while(res) { res=m_CFile.FindNextFile();//下一文件夹 CString m_path=m_CFile.GetFilePath(); m_list.AddString(m_path); } while(res1) { res=m_CFile1.FindNextFile();//下一文件夹 CString m_path=m_CFile1.GetFilePath(); m_list.AddString(m_path); } } } if (lpidlBrowse != NULL) { ::CoTaskMemFree(lpidlBrowse); } lpMalloc->Release(); } 9、响应重复播放按钮,使列表里的文件按次序循环播放 void CPlayerDlg::OnReplay() { // TODO: Add your control notification handler code here RePlay=true; } 10、响应删除按键,单击则删除选择的文件 void CPlayerDlg::OnDelete() { // TODO: Add your control notification handler code here int n=m_list.GetCurSel(); m_list.DeleteString(n); } 11、响应播放上一首歌,如果文件不被设备支持则移除文件,否则更新播放按钮void CPlayerDlg::OnUpPlay() { // TODO: Add your control notification handler code hereif(m_list.GetCount()>0) { fr=m_list.GetCurSel(); fr--; if(fr<1) { fr=m_list.GetCount()-1; } m_list.GetText(fr,szPath); if(szPath.GetLength()>0) { m_list.SetCurSel(fr); i_PlayTime=0; if(!m_Music.OPen(szPath.GetBuffer(NULL))) { m_list.DeleteString(fr); fr--; if(fr<1) { fr=m_list.GetCount()-1; } m_list.SetCurSel(fr); } m_Music.Play(m_Music.GetV olume(),0,0); i_MusicLongth = m_Music.GetLongth(); m_SetShowLongth.SetRange(0,i_MusicLongth/1000); //进度条.SetRange(0,255) m_SetShowLongth.SetPos(i_PlayTime); //进度控件同步 m_Play.ModifyStyle(0,0,IDB_BITMAP3);//载入位图,设置按钮风m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP3))); //加载位图 } else { AfxMessageBox("没有选择播放的音乐"); } } else { AfxMessageBox("没有可选择播放的音乐"); } } 12、响应播放下一首歌,如果文件不被设备支持则移除文件,否则更新播放按钮void CPlayerDlg::OnDownPlay(){ if(m_list.GetCount()>0) { fr=m_list.GetCurSel(); fr++; if(fr>=m_list.GetCount()) { fr=0; } m_list.GetText(fr,szPath); if(szPath.GetLength()>0) { m_list.SetCurSel(fr); i_PlayTime=0; if(!m_Music.OPen(szPath.GetBuffer(NULL))) { m_list.DeleteString(fr); fr++; if(fr>=m_list.GetCount()) { fr=0; } m_list.SetCurSel(fr); } m_Music.Play(m_Music.GetV olume(),0,0); i_MusicLongth = m_Music.GetLongth(); m_SetShowLongth.SetRange(0,i_MusicLongth/1000); //进度条.SetRange(0,255) m_SetShowLongth.SetPos(i_PlayTime); //进度控件同步 m_Play.ModifyStyle(0,0,IDB_BITMAP3);//载入位图,设置按钮风m_Play.SetBitmap(LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURC E(IDB_BITMAP3))); //加载位图 } else { AfxMessageBox("没有选择播放的音乐"); } } else { AfxMessageBox("没有可选择播放的音乐"); } } 第五章测试5.1 测试方法 操作所以功能按钮,看能否实现其功能 5.2 测试用例 导入音乐文件夹music 选择列表框中的一首歌 单击播放,或双击歌名 点击上一首,下一首,暂停,播放、返回,查看功能实现 5.3 测试结论 如果操作正确,基本功能使用正常 结论 此播放器如果操作正确,则一切功能都能基本实现 致谢 感谢我的父母,没有您们的包容和支持,就不会有我的今天。 感谢微软公司,为我无偿提供了开发环境。 感谢龙艳彬老师,为我做了制导。 参考文献 [1]MSDN for Visual Studio 6.0 [2]设计模式——可复用面向对象软件的基础,Erich Gamma/Richard Helm/Ralph Johnson/John Vlissides著,李英军/马晓星/蔡敏/刘建中等译,机械工业出版社 [3]深入浅出MFC(第2版),侯俊杰著,华中科技大学出版社 [4]Windows程序设计,Charles Petzold著,北京博彦科技发展有限公司译, 北京大学出版社 [5] 你必须知道的204个Visual C++开发问题,范立锋,李世欣著,人民邮电出 版社 [6] C++编程思想,Bruce Eckel著,刘宗田/邢大红/孙慧杰等译,机械工业 出版社
