所有的准备工作做完了后,就可以实现播放音乐的功能了吗,NO,在实现播放音乐之前还需要处理音乐文件,就是对音乐文件的增删改查
首先我们需要知道OPENFILENAME结构和GetFileName函数
OPENFILENAME结构是一个文件处理结构
参数:
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCTSTR lpstrFilter;
LPTSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPTSTR lpstrFile;
DWORD nMaxFile;
LPTSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCTSTR lpstrInitialDir;
LPCTSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCTSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
由于OPENFILENAME结构的参数过多,我就不一一介绍,在后面程序中使用时,我再介绍
还需要一个函数GetOpenFileName用于打开文件夹,GetOpenFileName只用一个参数,OPENFILENAME的地址
在使用时还需要定义一些全局变量为了减少变量的使用
/************************************************************************ 处理音乐文件时所需的全局变量 *************************************************************************/ static OPENFILENAME ofn;//打开文件对话框的文件结构 static char szOpenFileName[80*MAX_PATH];//保存文件名 static char szFileName[80*MAX_PATH];//保存歌曲的全路径 static char szPath[80*MAX_PATH];//储存路径 static char OpenMusicFile[MAX_PATH];//保存路径(用于操作音乐)
为了处理音乐文件还需要定义几个函数
void FileInit(HWND hwnd)
/********************************************************************** 函数名: FileInit(HWND hwnd) 函数功能: 打开文件初始化文件对话框 ****************************************************************************/ void FileInit(HWND hwnd) { //文件结构清零 ZeroMemory(&ofn,sizeof(ofn)); //文件结构的大小 ofn.lStructSize = sizeof(ofn); //文件路径 ofn.lpstrFile = szOpenFileName; ofn.lpstrFile[0] = TEXT('\0'); ofn.nMaxFile = sizeof(szOpenFileName); //过滤器 ofn.lpstrFilter = TEXT("所有支持文件(*.wav,*.mp3,*.wma)\0*.wav;*.mp3;*.wma\0wave文件(*.wav)\0*.wav\0mp3文件(*.mp3)\0*.mp3\0wma文件(*.wma)\0*.wma\0"); ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.hwndOwner = hwnd; ofn.Flags = OFN_EXPLORER |OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT; }
int OpenFileDlg(void)
/********************************************************************** 函数名: bool OpenFileDlg(void) 函数功能: 打开文件对话框 ************************************************************************/ int OpenFileDlg(void) { return GetOpenFileName(&ofn); }
/********************************************************************** 函数名: void AddFile(HWND hwnd) 函数功能: 添加文件 ***********************************************************************/ void AddFile(HWND hwnd) { TCHAR *p;//用于遍历音乐文件 int len = 0; FileInit(hwnd);//文件初始化 if(OpenFileDlg()) { /*把第一个文件名复制到szPath 如果只选了一个文件,就复制到最后一个'\' 如果选了多个文件,就复制到第一个NULL字符*/ lstrcpyn(szPath, szOpenFileName, ofn.nFileOffset); /*当只选了一个文件时,下面的NULL是必须的 这是不区别待选了一个和多个文件情况 */ szPath[ofn.nFileOffset] = '\0'; len = lstrlen(szPath); if(szPath[len - 1] != '\\') { lstrcat(szPath,TEXT("\\")); } p = szOpenFileName + ofn.nFileOffset; ZeroMemory(szFileName, sizeof(szFileName)); HWND hwndList = GetDlgItem(hwnd, IDC_LIST1); while(*p) { lstrcat(szFileName, szPath);/*给文件名加上路径*/ lstrcat(szFileName, p);/*加上文件名*/ ListBox_InsertString(hwndList, -1, p); lstrcat(szFileName, TEXT("\n"));/*换行*/ p += lstrlen(p) + 1;/*移到下一个文件*/ } } }
void AddFolder(HWND hwnd)
/************************************************************************************ 函数名: AddFolder(HWND hwnd) 函数功能: 添加文件夹 ****************************************************************************/ void AddFolder(HWND hwnd) { //保存文件夹的路径 TCHAR szFile[MAX_PATH]; TCHAR pBuffer_Directory[MAX_PATH];//存放文件信息 BROWSEINFO sBrowseInfo;//文件夹结构 LPCITEMIDLIST lpitem;//用于判断是否选择了一个文件夹 WIN32_FIND_DATA sfd;//文件的全部属性结构 //对文件夹结构清零 ZeroMemory(&sBrowseInfo,sizeof(BROWSEINFO)); //浏览文件夹对话框的父窗体句柄。 sBrowseInfo.hwndOwner=hwnd; //该浏览文件夹对话框对话框的显示文本,用来提示该浏览文件夹对话框的功能、作用和目的。 sBrowseInfo.lpszTitle="请选择文件夹"; //文件夹对话框的选项 sBrowseInfo.ulFlags=BIF_RETURNONLYFSDIRS; //BIF_RETURNFSANCESTORS:返回文件系统的一个节点。仅仅当选中的是有意义的节点时,“OK”按钮才可以使用。 //显示一个选择文件夹的对话框 lpitem=SHBrowseForFolder(&sBrowseInfo); //判断是否选择了文件夹 if(NULL==lpitem) { return; } //获得文件夹的路径 SHGetPathFromIDList(lpitem,pBuffer_Directory); strcpy(szFile,pBuffer_Directory); //枚举过滤条件(只实现MP3) lstrcat(pBuffer_Directory,"\\*.mp3"); /*得到第一个文件(第一首歌)的句柄*/ HANDLE hfindfile = FindFirstFile(pBuffer_Directory,&sfd); if(INVALID_HANDLE_VALUE==hfindfile)//判断文件是否有效 { return; } do { if (sfd.cFileName[0]=='.') { continue; } lstrcat(szFileName,szFile); lstrcat(szFileName,TEXT("\\")); lstrcat(szFileName,sfd.cFileName); lstrcat(szFileName,TEXT("\n")); //得到ListBox控件的句柄 HWND hwndList = GetDlgItem(hwnd,IDC_LIST1); //将音乐文件的文件名(歌曲名)添加到播放列表中 ListBox_InsertString(hwndList,-1,sfd.cFileName); }while (FindNextFile(hfindfile,&sfd)); /*只要没遍历到文件夹中的最后一个文件就一直添加*/ }
在void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)中添加下面的代码
/*添加歌曲到列表中*/ case ID_MENUADD: { AddFile(hwnd); } break; /*添加歌曲到播放列表中*/ case IDC_ADD: { AddFile(hwnd); } break;
删除列表中的歌曲,删除列表中的歌曲主要使用ListBox_DeleteString函数
ListBox_DeleteString有两个参数
int ListBox_DeleteString(
HWND hwndCtl,
int index
);
一个是ListBox控件的句柄,一个是删除的歌曲的索引
在删除歌曲中需要定义一个函数void DeleteMusic(HWND hwnd)用于删除选定的歌曲
/************************************************************************* 函数名: void DeleteMusic(HWND hwnd) 函数功能: 删除选定的歌曲 **************************************************************************/ void DeleteMusic(HWND hwnd) { GetMusic(hwnd);//选定歌曲 //得到ListBox控件的句柄 HWND hwndList = GetDlgItem(hwnd,IDC_LIST1); //得到选择的歌曲的序号 int CurSel = ListBox_GetCurSel(hwndList); //下一曲 JumpMusic(hwnd,1); //删除选定的歌曲 ListBox_DeleteString(hwndList,CurSel); }
在void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)中添加下面的代码
//删除歌曲 case IDC_DELETE: { DeleteMusic(hwnd); } break;
删除"美丽的神话"
删除前
删除后
清空列表框中的歌曲,清空列表框中的歌曲和删除歌曲的方法类似,只是循环删除,直到列表框中没有歌曲
老规矩先定义一个函数用于清空播放列表
void DeleteList(HWND hwnd)函数用于清空列表框中的歌曲
/************************************************************************** 函数名: void DeleteList(HWND hwnd) 函数功能: 清空播放列表 **************************************************************************/ void DeleteList(HWND hwnd) { HWND hwndList = GetDlgItem(hwnd,IDC_LIST1); //得到播放列表中歌曲的数量 int Count = ListBox_GetCount(hwndList); for(int i=Count-1;i>=0;i--) { ListBox_DeleteString(hwndList,i); }
在void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)中添加下面的代码
//清空播放列表 case IDC_DELETE_LIST: { DeleteList(hwnd); } break;
测试音乐播放器
执行清空列表前
清空播放列表后