提到播放方式经常听歌的朋友一定不会陌生,常见的播放方式有顺序播放,单曲循环,列表循环,随机播放,
在写代码前我先介绍我的思路:
在实现这些播放方式中一定要一个前提就是要保证歌曲能够连续播放,为了实现歌曲的连续播放,我用到了定时器和回调函数用于判断歌曲是否播放完毕
首先我定义了一个定时器 SetTimer(hwnd,1,1000,MusicNowTime),并且定义了一个回调函数MusicNowTime,
并且在MusicNowTime中放一个if语句用于判断当前歌曲的播放状态,当歌曲播放完成后,就播放下一曲,
因为使用了回调函数所以每隔1秒会判断一次,直到播放完毕就播放下一曲
有了思路后就开始写代码
首先在PlayMusic函数中添加一段定时器的代码
SetTimer(hwnd,1,1000,MusicNowTime);//用于处理播放时间
然后定义一个全局变量用于实现歌曲的连续播放
/*************************************************************************** 显示播放歌曲的时间所需的全局变量 ****************************************************************************/ static char curTime[256];//当前歌曲播放的位置
最后定义一个回调函数MusicNowTime实现歌曲的连续播放并且实现播放方式和显示播放时间
/*************************************************************************** 函数名: MusicNowTime 函数功能: 显示当前歌曲的播放时间 *****************************************************************************/ void CALLBACK MusicNowTime(HWND hwnd,UINT message,UINT iTimerId,DWORD dwTime) { TCHAR Position[256];//保存歌曲的播放位置 TCHAR cmd[256];//保存得到歌曲的播放位置的命令 //打印得到歌曲的播放位置的命令 wsprintf(cmd,"status %s position",OpenMusicFile); //发送得到歌曲播放时间的命令 mciSendString(cmd, Position, sizeof(Position)/sizeof(TCHAR), NULL); int Time = atoi(Position)/1000;//保存歌曲的播放时间(秒) int Minute = Time/60;//分钟 int Second = Time - 60*Minute;//秒 //打印播放时间 wsprintf(curTime,"%02d:%02d",Minute,Second); //显示播放时间 SetDlgItemText(hwnd,IDC_BEGIN_TIME,curTime); TCHAR mode[MAX_PATH];//保存的到当前的播放状态 //打印得到状态的命令 wsprintf(cmd,"status %s mode",OpenMusicFile); //发送得到状态的命令 mciSendString(cmd,mode,sizeof(mode)/sizeof(TCHAR),NULL); //判断一首歌是否播完 if(0 == strcmp(mode,TEXT("stopped"))) { switch(iLoopType) { case 0://列表循环 { //下一曲 JumpMusic(hwnd, 1); } break; case 1://顺序播放 { if(numPlayMusicNow == totalMusicCount-1) { //停止 StopMusic(hwnd); } else { //下一曲 JumpMusic(hwnd, 1); } } break; case 2://单曲循环 { PlayMusic(hwnd); } break; case 3://随机播放 { //下一曲 JumpMusic(hwnd, 1); } break; default: break; } } }
实现了连续播放后还需要实现播放方式的自由切换,使用菜单可以实现播放方式的自由切换
/****************************************************************************** 函数名; void PlayTypeMenuSet(HWND hwnd,int indexs) 函数功能: 播放模式菜单设定 *******************************************************************************/ void PlayTypeMenuSet(HWND hwnd,int indexs) { //该函数取得分配给指定窗口的菜单的句柄 HMENU hMenu = GetMenu(hwnd); switch(indexs) { case 0://列表循环 { CheckMenuItem(hMenu,ID_MENUORDER,MF_CHECKED); CheckMenuItem(hMenu,ID_MENUCIRCULATION,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENURANDOM,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENUITEM40017,MF_UNCHECKED); } break; case 1://顺序播放 { CheckMenuItem(hMenu,ID_MENUORDER,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENUCIRCULATION,MF_CHECKED); CheckMenuItem(hMenu,ID_MENURANDOM,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENUITEM40017,MF_UNCHECKED); } break; case 2://单曲循环 { CheckMenuItem(hMenu,ID_MENUORDER,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENUCIRCULATION,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENURANDOM,MF_CHECKED); CheckMenuItem(hMenu,ID_MENUITEM40017,MF_UNCHECKED); } break; case 3://随机播放 { CheckMenuItem(hMenu,ID_MENUORDER,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENUCIRCULATION,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENURANDOM,MF_UNCHECKED); CheckMenuItem(hMenu,ID_MENUITEM40017,MF_CHECKED); } break; default: break; } }
运行结果