MFC-添加背景音乐(2)-封装了mciSendCommand的简单MCI类
2010-11-12 21:21
393 查看
封装了mciSendCommand的简单MCI类 2006-10-22 10:08 前阵子写了篇mciSendCommand简介的文章,大家看得比较多,说明大家需要这方面的东西哈。今天有空写了个简单的MCI类给大家贴出来。这个类很简单,只实现了简单的文件打开、播放、暂停、继续、关闭几个功能,供大家学习研究哈。如果哪位高手把这个类扩展了也请给我一份哈,以备不时之需哈。 这个类必须在MFC支持下才能使用,因为用了MFC 的CString。请在编译的时候链接上winmm.lib 类的代码如下: //////////////////////////// //CMCI.h ////////////////////////////////////////////////////// #include <mmsystem.h> class CMCI { public: void Resume(); void Pause(); void Close(); void Play(UINT From,UINT To); UINT m_iDeviceType; CMCI(CString FilePath,CString DeviceType); virtual ~CMCI(); }; //////////////////////// //cMCI.cpp ///////////////////////////// #include "stdafx.h" #include "CMCI.h" #pragma comment(lib, "winmm.lib ") CMCI::CMCI(CString FilePath,CString DeviceType="MPEGAudio") { MCI_OPEN_PARMS pm; pm.dwCallback=NULL; pm.lpstrAlias=NULL; pm.lpstrDeviceType=DeviceType; pm.lpstrElementName=FilePath; pm.wDeviceID=NULL; if(0==mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_ELEMENT,(DWORD)&pm)) { this->m_iDeviceType=pm.wDeviceID; } } CMCI::~CMCI() { if(this->m_iDeviceType) Close(); } void CMCI::Play(UINT From, UINT To) { MCI_PLAY_PARMS pm; pm.dwCallback=0; pm.dwFrom=From; pm.dwTo=To; if(!this->m_iDeviceType) return; mciSendCommand(this->m_iDeviceType, MCI_PLAY, MCI_NOTIFY, (DWORD)&pm); } void CMCI::Close() { if(this->m_iDeviceType) { MCI_GENERIC_PARMS gp; gp.dwCallback=NULL; mciSendCommand(this->m_iDeviceType, MCI_CLOSE, MCI_WAIT, (DWORD)&gp); this->m_iDeviceType=NULL; } } void CMCI::Pause() { if(this->m_iDeviceType ) { MCI_GENERIC_PARMS gp; gp.dwCallback=NULL; mciSendCommand(this->m_iDeviceType, MCI_PAUSE, MCI_WAIT, (DWORD)&gp); } } void CMCI::Resume() { if(this->m_iDeviceType ) { MCI_GENERIC_PARMS gp; gp.dwCallback=NULL; mciSendCommand(this->m_iDeviceType, MCI_RESUME, MCI_WAIT, (DWORD)&gp); } } 这个类的用法: 1、在CXXDlg.h中加入成员变量 CMCI *mymci; 2、在某个消息中构建CMCI的实例并播放文件 CString str1="e://1.mp3";//路径 mymci=new CMCI(str1);//构建对象实例 mymci->Play();//调用方法 3、在适当的时候(通常是程序退出)关闭对象 mymci->Close(); 请注意,不要在堆栈中写这样的代码: CMCI mci; mci.Play() 这样并不会播放某个文件,因为在这段代码结束的时候,刚才定义的对象已经释放销毁了。 成员列表: void Resume(); //继续播放 void Pause();//暂停播放 void Close();//关闭该对象(文件) void Play(UINT From,UINT To);//开始播放 UINT m_iDeviceType;//该文件(对象)的mciSendCommand中的MciDevice CMCI(CString FilePath,CString DeviceType);//构造器,初始化该对象(文件) virtual ~CMCI();//销毁该对象 源文档 <http://www.cnblogs.com/witxjp/archive/2010/5/6.html> // Midi.h /* CMidi类的使用方法: 1、直接把MIDI.h和MIDI.cpp文件复制到你程序目录下,工程中加入这两个 文件。 2、单击“工程-> 设置-> Link”,在“对象/库模块”中连接库winmm.lib 3、在你工程的头文件中包含头文件,#include "MIDI.H " 4、在工程中定义一个CMidi类的对象,如:CMidi m_Music; 5、在工程的初始化文件中,初始化歌曲列表路径,m_Music.InitPath(), 再打开列表,m_Misic.OpenList();下面就可以在各个对应的消息函数中处 理它了 如: 播放:m_Misic.Play(); 停止:m_Misic.Stop(); 上一首:m_Misic.Per(); 下一首:m_Misic.Next(); 打开:m_Misic.OpenFiles(); 保存歌曲列表:m_Misic.SaveList(); //保存列表我没有放在打开函数中,如果打开的文件比较多,那样会在 打开过一会儿才能播放音乐,不舒服,你自己到工程的OnDestroy()中保存吧 循环播放:m_Misic.OnTimer(); //它需要在主程序中打开一个定时器,SetTimer(0,500,NULL);然后在主程序 中重载OnTimer()函数,在该函数体内,先判断是否正在播放, m_Misic.PlayingFalg是否为真,真,则调用循环播放函数。如下: { if(m_Misic.PlayingFalg) m_Misic.OnTimer(); } */ #ifndef __MIDI_H__ #define __MIDI_H__ #include <mmsystem.h> class CMidi { public: bool Play();//播放初始化函数(打开设备并初始化) CMidi(); ~CMidi(); public: void OnTimer();//循环播放函数 bool InitPath();//初始化路径,取得播放曲目列表文件的全路径 bool OpenFiles();//打开文件对话框,获取歌曲列表 bool OpenList();//读取文件中的歌曲列表 bool SaveList();//保存列表 void Per();//上一首 void Next();//下一首 void Stop();//停止函数,在播放以前先停止 void Display( CString& );//显示播放列表 DWORD getinfo(DWORD item);//获取歌曲长度信息 DWORD m_count; DWORD cdlen,cdfrom,cdto; int m_totalFiles;//保存歌曲的首数 int fr;//当前已播放的歌曲数 CString m_FileList[256];//歌曲路径列表数组 CString m_MusicFilePath;//保存歌曲列表文件的路径 bool PlayingFalg;//正在播放标志,以便定时器判断 }; #endif // Midi.cpp #include "stdafx.h " #include "Midi.h " CMidi::CMidi() { m_totalFiles=0; fr=0; cdfrom=0; m_MusicFilePath= " "; PlayingFalg=false; } CMidi::~CMidi() { } //------------播放--------------------- bool CMidi::Play() { if(m_FileList[fr]== " ") {//如果读取路径为空,则弹出打开对话框 OpenFiles(); } else { PlayingFalg=true;//标志为正在播放 MCI_OPEN_PARMS mciopenparms;//打开 MCI_PLAY_PARMS mciplayparms;//播放 //以下用fr做下标,能在停止再播放时恢复上次的位置 mciopenparms.lpstrElementName=m_FileList[fr];//播放路径 mciopenparms.lpstrDeviceType=NULL;//文件类型为NULL,就可以支持全部类型 mciSendCommand(0,MCI_OPEN,MCI_DEVTYPE_WAVEFORM_AUDIO, (DWORD)(LPVOID)&mciopenparms);//向MCI设备发送命令消息 m_count=mciopenparms.wDeviceID; mciplayparms.dwCallback=NULL;//窗口拥有者句柄 cdlen=getinfo(MCI_STATUS_LENGTH);//得到曲目长度 cdto=MCI_MAKE_HMS(MCI_HMS_HOUR(cdlen),MCI_HMS_MINUTE(cdlen), MCI_HMS_SECOND(cdlen));//根据长度计算出时、分、秒 mciplayparms.dwFrom=MCI_MAKE_HMS(0,0,0);//表示从哪儿开始播放吧 mciplayparms.dwTo=cdto;//表示放到哪儿为止 mciSendCommand(m_count,MCI_PLAY,MCI_TO|MCI_FROM, (DWORD)(LPVOID)& mciplayparms); //发送播放消息 } return true; } //---------------获取歌曲信息(长度,已播放长度)------ DWORD CMidi::getinfo(DWORD item) { MCI_STATUS_PARMS mcistatusparms; mcistatusparms.dwCallback=NULL; /* //接受传入的命令参数,这是关键。命令参数如下: 获取歌曲长度: MCI_STATUS_LENGTH 获取当前已播放的长度:MCI_STATUS_POSITION */ mcistatusparms.dwItem=item;//接受命令参数的地方 mcistatusparms.dwReturn=0;//返回值 mciSendCommand(m_count,MCI_STATUS,MCI_STATUS_ITEM,(DWORD)&mcistatusparms); return mcistatusparms.dwReturn; } //-------------------停止------------------- void CMidi::Stop() { PlayingFalg=false;//关闭正在播放标志 cdfrom=MCI_MAKE_HMS(0,0,0);//播放位置归文件开头 mciSendCommand(m_count,MCI_CLOSE,0,NULL);//发出关闭消息 m_count=0; } //-------------------下一首---------------- void CMidi::Next() { fr++; if(fr> =m_totalFiles) { //让fr指向下一个音乐文件,fr是从0下标开始 //m_totalFiles为总文件数 fr=fr%m_totalFiles; } Stop(); Play(); } //----------上一首------------------ void CMidi::Per() { fr--; if(fr==-1) {//指向最后一首歌,但fr是从0下标开始的,而m_totalFiles是从1开始 fr=m_totalFiles-1; } Stop(); Play();//播放fr指向的位置 } //----------保存曲目列表----------------- bool CMidi::SaveList() { CFile fileList;//文件对象 if(!fileList.Open(m_MusicFilePath,CFile::modeCreate|CFile::modeWrite)) return FALSE;//打开文件,不存在则创建,写文件 char fileName[256]; for(int i=0;i <m_totalFiles;i++) {//m_totalFiles为打开对话框中获取的歌曲总数 strcpy(fileName,m_FileList[i]);//取出一条曲目路径 fileList.Write(fileName,strlen(fileName));//写入文件 fileList.Write( "/r/n ",2);//写入一行结束和换行符 } fileList.Write( "---- ",4);//写入文件最后标志 fileList.Close();//关闭文件 return TRUE; } //----------读取曲目路径列表----------------- bool CMidi::OpenList() { CFile fileList; if(!fileList.Open(m_MusicFilePath,CFile::modeNoTruncate|CFile::modeRead)) return FALSE;//以只读模式打开,不覆盖原有文件,m_MusicFilePath为列表文件的路径 char ch; while(1) { CString fileName; fileList.Read(&ch,1);//读入一个字符 if(ch== '- ') break; //如文件是最后返回,-是文件最后的标志 fileName+=ch;//否则存入 while(1) {//读入一行 fileList.Read(&ch,1); if(ch== '/r ') {//这儿可以判断是一行了 m_totalFiles++;//曲目首数计数 fileList.Read(&ch,1); break; } fileName+=ch; } //下面这句把路径加入列表中,用字符串数组代替 //m_totalFiles前面已经加一了,所以这儿要少一个 m_FileList[m_totalFiles-1]=fileName; } fileList.Close(); return TRUE; } //----------打开对话框,获取曲目列表----------------- bool CMidi::OpenFiles() { CFileDialog f(true);//打开对话框对象 f.m_ofn.Flags |=512;//OFN_ALLOWMULTISELECT;目录列表方式 f.m_ofn.lpstrFilter= "所有媒体类型/0*.*/0/0 "; if(f.DoModal()!=IDOK) return FALSE;//用户单击了“取消” POSITION pos=f.GetStartPosition();//获取第一个文件位置 int i=0; while(pos) { m_FileList[i]=f.GetNextPathName(pos);//读取文件到曲目路径列表 i++; } m_totalFiles=i;//保存曲目总数 Stop(); Play();//播放打开的文件 return TRUE; } //-------------------获得播放列表文件的路径------------ bool CMidi::InitPath() {//初始化路径,取得播放曲目列表文件的全路径 TCHAR path[256];//保存文件路径 GetModuleFileName(NULL,path,sizeof(path)) ;//获取当前程序路径 TCHAR * p = _tcsrchr(path,_T( '// ')) ;//查找最后一个 '// '字符 if(p) lstrcpy(p,_T( "//MPlayer.mdr "));//替换成要查找的完整路径 m_MusicFilePath=path;//保存到路径变量中,以便用它来打开列表文件 return true; } //----------------------循环播放------------------ void CMidi::OnTimer() {//循环播放 if(getinfo(MCI_STATUS_POSITION)==cdlen) {//如当前播放的长度等于歌曲的长度,说明已经播放完毕 Next();//指向下一首 } } //----------------------循环播放------------------ void CMidi::Display( CString& output ) { int i; output.Empty(); for( i=0;i <m_totalFiles;++i ) { output += m_FileList[i]; output += "/r/n "; } } 源文档 <http://topic.csdn.net/t/20050622/16/4099738.html>
相关文章推荐
- MFC-添加背景音乐(2)-封装了mciSendCommand的简单MCI类 .
- 封装mciSendCommand的简单MCI类
- MFC界面中添加简单动画的思路
- OkHttp简单封装,添加泛型
- MFC为简单对话框程序添加菜单并加上响应事件
- C/C++/MFC中添加背景音乐 用的MCI 源码 和 方法说明 添加曲目路径即可用
- 简单的iOS通讯录操作封装(添加联系人、检查号码是否存在)
- JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(推荐七)
- MFC----MFC添加excel类库ole库,执行简单读写
- 刚封装的基于jquery的一个简单的、可过滤可添加的下拉框控件
- 简单的iOS通讯录操作封装(添加联系人、检查号码是否存在
- MFC-添加背景音乐(1) PlaySound函数应用
- 在MFC中添加背景音乐
- MFC添加背景音乐
- MFC 简单封装word, office操作。
- MFC中简单的数据库文件操作(添加,修改,查找,删除)
- mfc工具条上简单添加下拉框
- MFC为简单对话框程序添加菜单并加上响应事件
- Archie OSG Step By Step⑦MFC修改鼠标,制作半透明窗口,视口全屏以及添加背景音乐。
- 为基于MFC的对话框添加ToolTip的简单方法