使用MCI接口编写能播放MP3,WAV格式的音频文件

程序信息:
程序名称:My Music Player
作者 :CodeMore
编译时间:2016年1月31日 星期日
版本: 1.0
程序原理:使用Windows中的MCI接口
编译环境: Win 10 64位专业版 和VC2010旗舰版
本播放器有以下特点:
1.程序能播放MP3, WAV格式的音频文件,采用Windows系统的MCI(媒体控制接口)进行播放。
2.播放MP3音频文件时,能够在歌曲信息区域显示文件的tag信息(歌手,专辑,发行年份等)。采用id3lib库进行开发获取,详细见源码。
3.播放器支持4种播放模式(顺序播放、单曲循环、单曲播放、随机播放)。
4.播放列表控件支持双击播放操作,支持单击项目显示歌曲信息等功能。
5.在Win7和10 平台上支持任务栏上显示音频播放进度,xp平台未测试。
致谢:
MP3FileInfo类来源于CodeProject网上的大神(Christian Richardt)。

程序界面:

程序的各个控件ID值:

程序代码:
**1.标准应用程序框架
stdafx.h**


// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件#pragma once#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
#endif#include "targetver.h"#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
#define _AFX_ALL_WARNINGS#include <afxwin.h>         // MFC 核心组件和标准组件
#include <afxext.h>         // MFC 扩展#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>             // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT#include <afxcontrolbars.h>     // 功能区和控件条的 MFC 支持#include <MMSystem.h>       //MCI支持的头文件
#include <Digitalv.h>
#pragma comment (lib,"winmm.lib")// MP3FileInfo
#include <assert.h>
#include <stdio.h>
#include "MP3FileInfo.h"//支持windows 7的visual style
//Unicode版本
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
//多字节版本
#ifdef _MBCS
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif

stdafx的实现文件:


// stdafx.cpp : 只包括标准包含文件的源文件
// My Music Player.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息#include "stdafx.h"

NiceSlider头文件(主要是用于滑块的精确移动)

/****************
*类名:CNiceSliderCtrl
*功能:支持滑块滑动功能,做到精确无误。
*/#ifndef NiceSlider_h
#define NiceSlider_h// Class that provides better mouse click handling for the standard windows slider control
class CNiceSliderCtrl : public CSliderCtrl
{
public:DECLARE_DYNAMIC(CNiceSliderCtrl)CNiceSliderCtrl() : m_bDragging(false), m_bDragChanged(false) {}
protected://{{AFX_MSG(CRoundSliderCtrl)afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);//}}AFX_MSGDECLARE_MESSAGE_MAP()
private:bool SetThumb(const CPoint& pt);void PostMessageToParent(const int nTBCode) const;bool m_bDragging;bool m_bDragChanged;
};
#endif // NiceSlider_h

NiceSlider的实现文件

/****************
*类名:CNiceSliderCtrl
*功能:实现文件
*文件名:NiceSlider.cpp
*/
#include "stdafx.h"
#include "NiceSlider.h"IMPLEMENT_DYNAMIC(CNiceSliderCtrl, CSliderCtrl)BEGIN_MESSAGE_MAP(CNiceSliderCtrl, CSliderCtrl)//{{AFX_MSG_MAP(CNiceSliderCtrl)ON_WM_LBUTTONDOWN()ON_WM_MOUSEMOVE()ON_WM_LBUTTONUP()//}}AFX_MSG_MAP
END_MESSAGE_MAP()void CNiceSliderCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{m_bDragging = true;m_bDragChanged = false;SetCapture();SetFocus();if (SetThumb(point)){m_bDragChanged = true;PostMessageToParent(TB_THUMBTRACK);}
}void CNiceSliderCtrl::OnMouseMove(UINT nFlags, CPoint point)
{if (m_bDragging){if (SetThumb(point)){m_bDragChanged = true;PostMessageToParent(TB_THUMBTRACK);}}else{CSliderCtrl::OnMouseMove(nFlags, point);}
}void CNiceSliderCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{if(m_bDragging){m_bDragging = false;::ReleaseCapture();if (SetThumb(point)){PostMessageToParent(TB_THUMBTRACK);m_bDragChanged = true;}if (m_bDragChanged){PostMessageToParent(TB_THUMBPOSITION);m_bDragChanged = false;}}else{CSliderCtrl::OnLButtonUp(nFlags, point);}
}bool CNiceSliderCtrl::SetThumb(const CPoint& point)
{const int nMin = GetRangeMin();const int nMax = GetRangeMax()+1;CRect rc;GetChannelRect(rc);double dPos;double dCorrectionFactor = 0.0;if (GetStyle() & TBS_VERT) {// note: there is a bug in GetChannelRect, it gets the orientation of the rectangle mixed updPos = (double)(point.y - rc.left)/(rc.right - rc.left);}else{dPos = (double)(point.x - rc.left)/(rc.right - rc.left);}// This correction factor is needed when you click inbetween tick marks// so that the thumb will move to the nearest onedCorrectionFactor = 0.5 *(1-dPos) - 0.5 *dPos;int nNewPos = (int)(nMin + (nMax-nMin)*dPos + dCorrectionFactor);const bool bChanged = (nNewPos != GetPos());if(bChanged){SetPos(nNewPos);}return bChanged;
}void CNiceSliderCtrl::PostMessageToParent(const int nTBCode) const
{CWnd* pWnd = GetParent();if(pWnd) pWnd->PostMessage(WM_HSCROLL, (WPARAM)((GetPos() << 16) | nTBCode), (LPARAM)GetSafeHwnd());
}

**MP3FileInfo头文件
主要用于获取Mp3的tag信息**

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MP3FileInfo 1.0-----------------------MP3FileInfo is a wrapper class for id3lib, a library capableof reading and writing ID3 Tags of MP3 Files. It has asimple interface and provides all data as public members.Written by Christian Richardt (cr@whizer.net).Release history:Mai 31, 2003: Version 1.0. First release.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*//**\file    MP3FileInfo.h\brief   Reads Header and ID3 Tags of MP3 Files\date    2003-05-31\author  Christian Richardt (cr@whizer.net)
**/#ifndef MP3FILEINFO_H
#define MP3FILEINFO_H/* ---- use id3lib ---- */// "If you use id3lib.dll (you link dynamic) you should add//  ID3LIB_LINKOPTION=3 to your preprocessor definitions of your project."#define ID3LIB_LINKOPTION 3#include <id3/tag.h>#pragma comment(lib, "id3lib.lib")/**\brief   Reads Header and ID3 Tags of MP3 FilesMP3FileInfo is a wrapper class for id3lib, a library capableof reading and writing ID3 Tags of MP3 Files. It has asimple interface and provides all data as public members.How to use MP3FileInfo:\codeMP3FileInfo obj; // don't use at this point!if(!obj.Init("some-file.mp3")){ ... error ... }... use MP3FileInfo ...\endThe object frees all allocated memory if deleted. AlwaysInitalize this class by calling Init(). It returns false ifan error occured. You can call Init() as often as you want.All data is being freed before the data of the new file isextracted.Always call isOK() to check whether the class is all right!**/class MP3FileInfo{public:inline MP3FileInfo(void) :m_bOK(true),m_id3tag(0),m_mp3header(0),// FileinfoszFilename(0), nFileSize(-1),bHasLyrics(false), bHasV1Tag(false), bHasV2Tag(false),// HeaderinfonBitRate(0), nCbrBitRate(0), nVbrBitRate(0), nSampleRate(0), nLength(0),szBitRate(0), szMpegLayer(0), szMpegVersion(0), szChannelMode(0),// ID3V1 Tag elementsszArtist(0), szAlbum(0), szGenre(0), szTitle(0), szYear(0), szComment(0), szTrack(0),// ID3V2 Tag elementsszComposer(0), szCopyright(0), szEncodedBy(0), szOriginalArtist(0), szURL(0){// nothing to do; use Init() instead}virtual ~MP3FileInfo(void) { Free(); }bool Init(const char* cszFilename);void Free(void);inline bool isOK(void) const { return m_bOK; }/* Fileinfo */char* szFilename;bool  bHasLyrics, bHasV1Tag, bHasV2Tag;int   nFileSize;/* Headerinfo */int nCbrBitRate, nVbrBitRate, nBitRate, nSampleRate, nLength;char* szBitRate;char* szMpegLayer;char* szMpegVersion;char* szChannelMode;/* V1 up */char* szArtist;char* szTitle;char* szAlbum;char* szComment;char* szTrack; int nTrack;char* szYear; int nYear;char* szGenre;/* V2 only */char* szComposer;char* szCopyright;char* szEncodedBy;char* szOriginalArtist;char* szURL;void  ShowAllFrames(void);protected:bool m_bOK;ID3_Tag* m_id3tag;const Mp3_Headerinfo* m_mp3header;void m_parseFile(void);void m_parseHeader(void);void m_parseGenre(void);bool  m_getString(ID3_FrameID fid, char* szBuffer);char* m_getNewString(ID3_FrameID fid);};
#endif // MP3FILEINFO_H

MP3FileInfo的实现文件

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MP3FileInfo 1.0-----------------------MP3FileInfo is a wrapper class for id3lib, a library capableof reading and writing ID3 Tags of MP3 Files. It has asimple interface and provides all data as public members.Written by Christian Richardt (cr@whizer.net).Release history:Mai 31, 2003: Version 1.0. First release.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*//**\file    MP3FileInfo.cpp\brief   Reads Header and ID3 Tags of MP3 Files\date    2003-05-31\author  Christian Richardt (cr@whizer.net)
**/#include "stdafx.h"#include <assert.h>#include <stdio.h>/* ----------------------- Init and Free ------------------------ *//**\brief   Initialize and parse all dataAlways Initalize this class by calling Init(). It returnsfalse if an error occured.You can call Init() as often as you want. All data is beingfreed before extracting the data of the new file.**/bool MP3FileInfo::Init(const char* cszFilename){Free();m_bOK = true;// copy filenameszFilename = new char[strlen(cszFilename)+1];strcpy_s(szFilename, strlen(cszFilename)+1, cszFilename);m_id3tag = new ID3_Tag;m_id3tag->Link(szFilename);/* Fileinfo */bHasLyrics = m_id3tag->HasLyrics();bHasV1Tag  = m_id3tag->HasV1Tag();bHasV2Tag  = m_id3tag->HasV2Tag();nFileSize  = (int)m_id3tag->GetFileSize();/* Headerinfo */m_parseHeader();if(!m_bOK) { Free(); return m_bOK; }/* V1 up */szAlbum   = m_getNewString(ID3FID_ALBUM);szArtist  = m_getNewString(ID3FID_LEADARTIST);szComment = m_getNewString(ID3FID_COMMENT);szTitle   = m_getNewString(ID3FID_TITLE);szTrack   = m_getNewString(ID3FID_TRACKNUM);szYear    = m_getNewString(ID3FID_YEAR);/* V2 */szComposer        = m_getNewString(ID3FID_COMPOSER);szCopyright       = m_getNewString(ID3FID_COPYRIGHT);szEncodedBy       = m_getNewString(ID3FID_ENCODEDBY);szOriginalArtist  = m_getNewString(ID3FID_ORIGARTIST);szURL             = m_getNewString(ID3FID_WWWUSER);m_parseGenre();if(szYear)  sscanf_s(szYear,  "%i", &nYear);if(szTrack) sscanf_s(szTrack, "%i", &nTrack);return m_bOK;}/**\brief   Free all allocated ressourcesYou can call Free() as often as you want.No error is raised.**/void MP3FileInfo::Free(void){if(m_bOK) // only free if OK{m_bOK = false;if(m_id3tag!=0){// in rare cases (e.g. if file is corrupt)// "delete m_id3tag" fails ...try { delete m_id3tag; } catch(...) {}m_id3tag = 0;}/* fileinfo */delete[] szFilename; szFilename = 0; nFileSize = -1;bHasLyrics = false; bHasV1Tag = false; bHasV2Tag = false;/* headerinfo */m_mp3header = 0;nVbrBitRate = 0; nBitRate = 0; nCbrBitRate = 0;nSampleRate = 0; nLength  = 0;delete[] szBitRate;     szBitRate = 0;delete[] szMpegLayer;   szMpegLayer = 0;delete[] szMpegVersion; szMpegVersion = 0;delete[] szChannelMode; szChannelMode = 0;/* ID3V1 Tag elements */nTrack = 0; nYear = 0;delete[] szArtist;  szArtist  = 0;delete[] szTitle;   szTitle   = 0;delete[] szAlbum;   szAlbum   = 0;delete[] szComment; szComment = 0;delete[] szTrack;   szTrack   = 0;delete[] szYear;    szYear    = 0;delete[] szGenre;   szGenre   = 0;/* V2 up */delete[] szComposer;        szComposer= 0;delete[] szCopyright;       szCopyright= 0;delete[] szEncodedBy;       szEncodedBy= 0;delete[] szOriginalArtist;  szOriginalArtist= 0;delete[] szURL;             szURL= 0;}}/* ---------------- public member functions ---------------- *//// prints all frames the file containsvoid MP3FileInfo::ShowAllFrames(void){assert(m_bOK);// all FrameIDsID3_FrameID fids[] = { ID3FID_NOFRAME,          ID3FID_AUDIOCRYPTO,     ID3FID_PICTURE,             ID3FID_AUDIOSEEKPOINT,  ID3FID_COMMENT,ID3FID_COMMERCIAL,       ID3FID_CRYPTOREG,       ID3FID_EQUALIZATION2,       ID3FID_EQUALIZATION,    ID3FID_EVENTTIMING,ID3FID_GENERALOBJECT,    ID3FID_GROUPINGREG,     ID3FID_INVOLVEDPEOPLE,      ID3FID_LINKEDINFO,      ID3FID_CDID,ID3FID_MPEGLOOKUP,       ID3FID_OWNERSHIP,       ID3FID_PRIVATE,             ID3FID_PLAYCOUNTER,     ID3FID_POPULARIMETER,ID3FID_POSITIONSYNC,     ID3FID_BUFFERSIZE,      ID3FID_VOLUMEADJ2,          ID3FID_VOLUMEADJ,       ID3FID_REVERB,ID3FID_SEEKFRAME,        ID3FID_SIGNATURE,       ID3FID_SYNCEDLYRICS,        ID3FID_SYNCEDTEMPO,     ID3FID_ALBUM,ID3FID_BPM,              ID3FID_COMPOSER,        ID3FID_CONTENTTYPE,         ID3FID_COPYRIGHT,       ID3FID_DATE,ID3FID_ENCODINGTIME,     ID3FID_PLAYLISTDELAY,   ID3FID_ORIGRELEASETIME,     ID3FID_RECORDINGTIME,   ID3FID_RELEASETIME,ID3FID_TAGGINGTIME,      ID3FID_INVOLVEDPEOPLE2, ID3FID_ENCODEDBY,           ID3FID_LYRICIST,        ID3FID_FILETYPE,ID3FID_TIME,             ID3FID_CONTENTGROUP,    ID3FID_TITLE,               ID3FID_SUBTITLE,        ID3FID_INITIALKEY,ID3FID_LANGUAGE,         ID3FID_SONGLEN,         ID3FID_MUSICIANCREDITLIST,  ID3FID_MEDIATYPE,       ID3FID_MOOD,ID3FID_ORIGALBUM,        ID3FID_ORIGFILENAME,    ID3FID_ORIGLYRICIST,        ID3FID_ORIGARTIST,      ID3FID_ORIGYEAR,ID3FID_FILEOWNER,        ID3FID_LEADARTIST,      ID3FID_BAND,                ID3FID_CONDUCTOR,       ID3FID_MIXARTIST,ID3FID_PARTINSET,        ID3FID_PRODUCEDNOTICE,  ID3FID_PUBLISHER,           ID3FID_TRACKNUM,        ID3FID_RECORDINGDATES,ID3FID_NETRADIOSTATION,  ID3FID_NETRADIOOWNER,   ID3FID_SIZE,                ID3FID_ALBUMSORTORDER,  ID3FID_PERFORMERSORTORDER,ID3FID_TITLESORTORDER,   ID3FID_ISRC,            ID3FID_ENCODERSETTINGS,     ID3FID_SETSUBTITLE,     ID3FID_USERTEXT,ID3FID_YEAR,             ID3FID_UNIQUEFILEID,    ID3FID_TERMSOFUSE,          ID3FID_UNSYNCEDLYRICS,  ID3FID_WWWCOMMERCIALINFO,ID3FID_WWWCOPYRIGHT,     ID3FID_WWWAUDIOFILE,    ID3FID_WWWARTIST,           ID3FID_WWWAUDIOSOURCE,  ID3FID_WWWRADIOPAGE,ID3FID_WWWPAYMENT,       ID3FID_WWWPUBLISHER,    ID3FID_WWWUSER,             ID3FID_METACRYPTO,      ID3FID_METACOMPRESSION,ID3FID_LASTFRAMEID};// a frame usually contains one field of the following fields:ID3_FieldID fiids[] = { ID3FN_NOFIELD, ID3FN_TEXTENC, ID3FN_TEXT, ID3FN_URL, ID3FN_DATA, ID3FN_DESCRIPTION, ID3FN_OWNER, ID3FN_EMAIL, ID3FN_RATING, ID3FN_FILENAME, ID3FN_LANGUAGE, ID3FN_PICTURETYPE, ID3FN_IMAGEFORMAT, ID3FN_MIMETYPE, ID3FN_COUNTER, ID3FN_ID, ID3FN_VOLUMEADJ, ID3FN_NUMBITS, ID3FN_VOLCHGRIGHT, ID3FN_VOLCHGLEFT, ID3FN_PEAKVOLRIGHT, ID3FN_PEAKVOLLEFT, ID3FN_TIMESTAMPFORMAT, ID3FN_CONTENTTYPE, ID3FN_LASTFIELDID};char*       idesc[] = { "No field.", "Text encoding (unicode or ASCII).", "Text field.", "A URL.", "Data field.", "Description field.", "Owner field.", "Email field.", "Rating field.", "Filename field.", "Language field.", "Picture type field.", "Image format field.", "Mimetype field.", "Counter field.", "Identifier/Symbol field.", "Volume adjustment field.", "Number of bits field.", "Volume chage on the right channel.", "Volume chage on the left channel.", "Peak volume on the right channel.", "Peak volume on the left channel.", "SYLT Timestamp Format.", "SYLT content type.", "Last field placeholder."};int i=0;char* buf = 0;ID3_Frame* frame = 0;ID3_Field* field = 0;while(i<96){if(i==2 || i==10) // picture and encapsulated object often fail{printf("%2i. Skipping\n", i);i++; continue;}try { frame = m_id3tag->Find(fids[i]); }catch(...){printf("ERROR: SKIPPING FILE (i=%i)\n", i);Free();return;}if(frame==0) { i++; continue; } // Frame not foundprintf("%2i. %-35s : ", i, frame->GetDescription());buf = m_getNewString(fids[i]);if(buf){printf("\"%s\"\n", buf);delete[] buf;frame = 0;i++; continue;}printf("No Text found, but:\n", buf);for(int k=1; k<24; k++){try{if(frame->Contains(fiids[k])){ printf("%-43s- %s\n", "", idesc[k]); }}catch(...){printf("%-42sERROR: SKIPPING FILE (i=%i; k=%i)\n", "", i, k);Free();return;}}printf("\n");frame = 0;i++; continue;}printf("\n");}/* ---------------- protected member functions ---------------- *//**\brief   parses the genre of the fileIn ID3V1 Tags, the genre is a simple byte and needs to beconverted to a string first, but ID3V2 allows arbitrarygenre descriptions.**/void MP3FileInfo::m_parseGenre(void){if(bHasV2Tag) // Use V2 if present{szGenre = m_getNewString(ID3FID_CONTENTTYPE);return;}char buf[10];if(!m_getString(ID3FID_CONTENTTYPE, buf)){szGenre = 0;return;}int gid;sscanf_s(buf, "(%i)", &gid); // filter Genre IDif(gid >= ID3_NR_OF_V1_GENRES) // genre ID too large{szGenre = new char[strlen(buf)+1];strcpy_s(szGenre,strlen(buf)+1, buf);return;}szGenre = new char[strlen(ID3_V1GENRE2DESCRIPTION(gid))+1];strcpy_s(szGenre, strlen(ID3_V1GENRE2DESCRIPTION(gid))+1, ID3_V1GENRE2DESCRIPTION(gid));}/// parses header infomationvoid MP3FileInfo::m_parseHeader(void){assert(m_bOK);m_mp3header = m_id3tag->GetMp3HeaderInfo();if(!m_mp3header){//printf("\n[Error]:\nGetMp3HeaderInfo() failed!\n(file: %s)\n\n", szFilename);Free();return;}nCbrBitRate = m_mp3header->bitrate;nVbrBitRate = m_mp3header->vbr_bitrate;nSampleRate = m_mp3header->frequency;nLength     = m_mp3header->time;szBitRate = new char[20];if(nVbrBitRate>0){sprintf_s(szBitRate, 20,  "%i kbit/s (VBR)", nVbrBitRate/1000);nBitRate = nVbrBitRate;}else{sprintf_s(szBitRate, 20, "%i kbit/s", nCbrBitRate/1000);nBitRate = nCbrBitRate;}// MPEG LayerszMpegLayer = new char[10];switch(m_mp3header->layer){case MPEGLAYER_UNDEFINED: strcpy_s(szMpegLayer,strlen("UNDEFINED")+1, "UNDEFINED"); break;case MPEGLAYER_III:       strcpy_s(szMpegLayer, strlen("Layer III")+1,"Layer III"); break;case MPEGLAYER_II:        strcpy_s(szMpegLayer, strlen("Layer II")+1,"Layer II");  break;case MPEGLAYER_I:         strcpy_s(szMpegLayer, strlen("Layer I")+1,"Layer I");   break;default:                  szMpegLayer = 0;}// MPEG VersionszMpegVersion = new char[10];switch(m_mp3header->version){case MPEGVERSION_2_5: strcpy_s(szMpegVersion, strlen("MPEG 2.5")+1, "MPEG 2.5"); break;case MPEGVERSION_2:   strcpy_s(szMpegVersion, strlen("MPEG 2")+1, "MPEG 2");   break;case MPEGVERSION_1:   strcpy_s(szMpegVersion, strlen("MPEG 1")+1, "MPEG 1");   break;default:              szMpegVersion = 0;}// Channel ModeszChannelMode = new char[15];switch(m_mp3header->channelmode){case MP3CHANNELMODE_STEREO:         strcpy_s(szChannelMode,strlen("Stereo")+1,  "Stereo");         break;case MP3CHANNELMODE_JOINT_STEREO:   strcpy_s(szChannelMode, strlen("Joint Stereo")+1, "Joint Stereo");   break;case MP3CHANNELMODE_DUAL_CHANNEL:   strcpy_s(szChannelMode, strlen("Dual Channel")+1, "Dual Channel");   break;case MP3CHANNELMODE_SINGLE_CHANNEL: strcpy_s(szChannelMode, strlen("Single Channel")+1, "Single Channel"); break;default:                            szChannelMode = 0;}}/// extracts a stringbool MP3FileInfo::m_getString(ID3_FrameID fid, char* szBuffer){assert(m_bOK);ID3_Frame* frame = m_id3tag->Find(fid); // frameif(frame==0){strcpy_s(szBuffer, strlen("[Not Found]") + 1, "[Not Found]");return false;}if(!frame->Contains(ID3FN_TEXTENC)){strcpy_s(szBuffer, strlen("[Contains No Text]") + 1, "[Contains No Text]");return false;}ID3_Field* field = 0;if(frame->Contains(ID3FN_TEXT)){ field = frame->GetField(ID3FN_TEXT); }// String is an URLif(frame->Contains(ID3FN_URL) && (field==0)){ field = frame->GetField(ID3FN_URL); }if(field==0){delete frame;strcpy_s(szBuffer, strlen("[Error]") + 1, "[Error]");return false;}field->SetEncoding(ID3TE_ISO8859_1);const char* res = field->GetRawText(); // GetRawUnicodeTextif(res==0){delete frame;strcpy_s(szBuffer, strlen("[Empty]") + 1, "[Empty]");return false;}strcpy_s(szBuffer, strlen(res) + 1, res);return true;}/// extracts a stringchar* MP3FileInfo::m_getNewString(ID3_FrameID fid){assert(m_bOK);ID3_Frame* frame = m_id3tag->Find(fid); // find frameif(frame==0) { return 0; }if(!frame->Contains(ID3FN_TEXTENC)){ delete frame; return 0; } // frame contains no text// look for field typeID3_Field* field = 0;if(frame->Contains(ID3FN_TEXT)) // Text field{ field = frame->GetField(ID3FN_TEXT); }if(frame->Contains(ID3FN_URL) && (field==0)) // URL field{ field = frame->GetField(ID3FN_URL); }if(field==0) { delete frame; return 0; } // no field foundfield->SetEncoding(ID3TE_ISO8859_1); // use Latin-1 charsetconst char* res = field->GetRawText(); // TODO: GetRawUnicodeTextchar* buf = new char[strlen(res)+1]; // new string// copystrcpy_s(buf, strlen(res) + 1, res);return buf;}

My Music Player的头文件
主程序


// My Music Player.h : PROJECT_NAME 应用程序的主头文件
//#pragma once#ifndef __AFXWIN_H__#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif#include "resource.h"       // 主符号// CMyMusicPlayerApp:
// 有关此类的实现,请参阅 My Music Player.cpp
//class CMyMusicPlayerApp : public CWinAppEx
{
public:CMyMusicPlayerApp();// 重写public:virtual BOOL InitInstance();// 实现DECLARE_MESSAGE_MAP()};extern CMyMusicPlayerApp theApp;

My Music Player的实现文件


// My Music Player.cpp : 定义应用程序的类行为。
//#include "stdafx.h"
#include "My Music Player.h"
#include "My Music PlayerDlg.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// CMyMusicPlayerAppBEGIN_MESSAGE_MAP(CMyMusicPlayerApp, CWinAppEx)ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()// CMyMusicPlayerApp 构造CMyMusicPlayerApp::CMyMusicPlayerApp()
{// TODO: 在此处添加构造代码,// 将所有重要的初始化放置在 InitInstance 中
}// 唯一的一个 CMyMusicPlayerApp 对象CMyMusicPlayerApp theApp;// CMyMusicPlayerApp 初始化BOOL CMyMusicPlayerApp::InitInstance()
{CWinAppEx::InitInstance();// 标准初始化// 如果未使用这些功能并希望减小// 最终可执行文件的大小,则应移除下列// 不需要的特定初始化例程// 更改用于存储设置的注册表项// TODO: 应适当修改该字符串,// 例如修改为公司或组织名SetRegistryKey(_T("应用程序向导生成的本地应用程序"));CMyMusicPlayerDlg dlg;m_pMainWnd = &dlg;INT_PTR nResponse = dlg.DoModal();if (nResponse == IDOK){// TODO: 在此放置处理何时用//  “确定”来关闭对话框的代码}else if (nResponse == IDCANCEL){// TODO: 在此放置处理何时用//  “取消”来关闭对话框的代码}// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,//  而不是启动应用程序的消息泵。INITCOMMONCONTROLSEX InitCtrls;InitCtrls.dwSize = sizeof(InitCtrls);InitCtrls.dwICC = ICC_WIN95_CLASSES;InitCommonControlsEx(&InitCtrls);return FALSE;
}

My Music Player Dlg的头文件(主对话框)

/********************************
*类名:CMyMusicPlayerDlg
*功能:函数定义及变量声明
*文件名:My Music PlayerDlg.h
*********************************/// My Music PlayerDlg.h : 头文件
///********************************
*常量和枚举型定义
*********************************/
const int ID_PLAYTIMER = 1;         //定时器IDtypedef enum _tagPlayMode           //各个播放模式的枚举值
{SEQUENCE_MODE = 0,              //顺序播放RANDOM_MODE   = 1,              //随机播放SINGLE_LOOP   = 2,              //单曲循环SINGLE_PLAY   = 3               //单曲播放}PLAYMODE;typedef enum _tagColumnWidth        //列表控件中每个列的宽度值
{SERIALNUMBERWIDTH = 40,         //序号FILENAMEWIDTH     = 150,        //文件名FILEPATHWIDTH     = 250,        //文件路径FILEDURATIONWIDTH = 100         //文件时长}COLUMNWIDTH;typedef enum _tagColumnIndex        //列表控件中各个列的索引值
{ID_SERIALNUMBER = 0,            //序号ID_FILENAME = 1,                //文件名ID_FILEPATH = 2,                //文件路径ID_FILEDURATION = 3             //文件时长
}COLUMNINDEX;#pragma once
#include "afxcmn.h"
#include "afxwin.h"
#include "NiceSlider.h"
#include "MP3FileInfo.h"// CMyMusicPlayerDlg 对话框
class CMyMusicPlayerDlg : public CDialog
{
// 构造
public:CMyMusicPlayerDlg(CWnd* pParent = NULL);        // 标准构造函数// 对话框数据enum { IDD = IDD_MYMUSICPLAYER_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();                        //对话框初始化函数afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()//成员变量
protected:CEdit m_edtSongTitle;                                   //显示歌曲文件名的编辑框CEdit m_edtArtist;                                      //显示歌曲艺术家的编辑框CEdit m_edtAlbum;                                       //显示歌曲专辑的编辑框CEdit m_edtYear;                                        //显示歌曲发行年份的编辑框CEdit m_edtSongBitrate;                                 //显示歌曲文件名的编辑框CEdit m_edtSongGenre;                                   //显示歌曲文件名的编辑框CNiceSliderCtrl m_position;                             //显示播放进度控件CNiceSliderCtrl sliderVol;                              //音量控制CListCtrl m_myListCtrl;                                 //显示播放列表控件CComboBox m_playmode;                                   //显示播放模式的组合框CMenu* pMainMenu;                                       //主菜单CMenu* pSubPlayMenu;                                    //播放控制菜单(用于更新菜单项)MP3FileInfo mp3info;                                    //获取mp3的tag信息 对象ITaskbarList3* pTaskbar;                                //用于支持任务栏显示播放进度HACCEL  hAccel;                                         //键盘加速键句柄WORD    m_wDeviceID;                                    //MCI设备IDTCHAR   strMciError[MAX_PATH];                          //用于保存mci设备错误代码CString m_strFilePath;                                  //当前播放文件路径CString m_strFileName;                                  //当前播放文件名称CString m_strFileDuration;                              //当前播放文件的时长CString m_strTotalLength;                               //文件总时长(字符串)CString m_strCurrentLength;                             //文件当前播放时间(字符串)CString m_strSongTitle;                                 //歌曲名称CString m_strArtist;                                    //艺术家CString m_strAlbum;                                     //专辑CString m_strYear;                                      //发行年CString m_strSongBitrate;                               //比特率CString m_strSongGenre;                                 //流派DWORD   dCurrentPos;                                    //当前播放位置(毫秒为单位)DWORD   m_dLength;                                      //音频文件的长度(毫秒为单位)int     m_nPlayMode;                                    //播放模式索引int     m_nCurrentSelection;                            //列表控件当前位置的索引值BOOL    bPause ;                                        //暂停标记//功能函数
public:BOOL InitControls(void);                                 //初始化界面控件BOOL InitMyMenu(void);                                   //初始化菜单BOOL InitComboxBox(void);                                //初始化播放模式组合框BOOL InitMyListCtrl(void);                               //初始化播放列表void TaskBarInit(void);                                  //任务栏初始化BOOL LoadFile(void);                                     //打开文件函数void GetMp3Info(CString strFilePath);                    //获得音频的ID3 TagBOOL PlayFile(CString szFileName);                       //播放文件函数void PauseMe();                                          //暂停函数void SetWindowTitle(CString fileName, int nPlayingFlag); // 设置窗口标题void GoPrevious(void);                                   //上一曲函数void GoNext(void);                                       //下一曲函数void GoAhead(void);                                      //快进函数void GoBack(void);                                       //快退函数void AddFileToPlayList(void);                            //增加项目函数void DeleteItem(void);                                   //删除项目函数void SetVolume(int Vol);                                 //设置音量大小函数 void UpdateCurrentPosText(void);                         //更新播放位置void SetPlayMode(void);                                  //设置各个播放模式CString ConvertTimeToString(int );                       //将文件毫秒数转换为分钟和秒void GetCurrentSelection(void);                          //当前列表控件选中位置的索引int  ParseFilePath(CString strFilePath);                 //从文件路径中分析出文件名//支持函数
public:virtual BOOL PreTranslateMessage(MSG* pMsg);                                 //处理ESCAPE键和Enter键退出对话框afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); //使对话框支持菜单项更新命令 (Code from MSDN)afx_msg void OnTimer(UINT_PTR nIDEvent);                                    //定时器:用于更新播放进度的位置afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);    //处理播放进度滑块和音量调节滑块位置变化afx_msg void OnDropFiles(HDROP hDropInfo);                                 //拖放afx_msg void OnClose();                                                    //关闭
//按钮映射函数
public:afx_msg void OnBnClickedBtnopen();                   //载入并播放按钮afx_msg void OnBnClickedBtnpause();                  //暂停按钮afx_msg void OnBnClickedBtnoprevious();              //上一曲afx_msg void OnBnClickedBtnnext();                   //下一曲afx_msg void OnBnClickedBtnahead();                  //快进按钮afx_msg void OnBnClickedBtnback();                   //快退按钮afx_msg void OnBnClickedBtnadd();                    //增加歌曲   afx_msg void OnBnClickedBtndelete();                 //删除歌曲//菜单项的映射函数
public:afx_msg void OnFileOpen();afx_msg void OnFileAddfolder();afx_msg void OnAppExit();afx_msg void OnHelpAbout();afx_msg void OnControlPlay();afx_msg void OnControlPause();afx_msg void OnControlPrevious();afx_msg void OnControlNext();afx_msg void OnControlAhead();afx_msg void OnControlBack();afx_msg void OnModeSequence();                      afx_msg void OnModeRandom();afx_msg void OnModeSingleloop();afx_msg void OnModeSingleplay();//播放模式菜单项更新afx_msg void OnUpdateModeSequence(CCmdUI *pCmdUI);afx_msg void OnUpdateModeRandom(CCmdUI *pCmdUI);afx_msg void OnUpdateModeSingleloop(CCmdUI *pCmdUI);afx_msg void OnUpdateModeSingleplay(CCmdUI *pCmdUI);
//播放列表控件右键菜单逻辑
public:afx_msg void OnContextmenuPlayfile();afx_msg void OnContextmenuPause();afx_msg void OnContextmenuPrevious();afx_msg void OnContextmenuNext();afx_msg void OnContextmenuLoadfile();afx_msg void OnContextmenuDeleteitem();afx_msg void OnContextmenuOpenfolder();//列表控件和播放模式组合框控件的消息映射
public:afx_msg void OnNMRClickPlaylist(NMHDR *pNMHDR, LRESULT *pResult);   //右键列表控件消息映射afx_msg void OnNMDblclkPlaylist(NMHDR *pNMHDR, LRESULT *pResult);   //双击列表控件消息afx_msg void OnNMClickPlaylist(NMHDR *pNMHDR, LRESULT *pResult);    //单击列表控件消息afx_msg void OnCbnSelchangeComplaymode();                           //播放模式组合框内容变化afx_msg void OnLvnItemchangedPlaylist(NMHDR *pNMHDR, LRESULT *pResult); //播放列表控件项目变化,用于更新歌曲数目
};

My Music Player Dlg的实现文件

/****************
*类名:CMyMusicPlayerDlg
*功能:绘制程序界面,实现各个功能函数。
*文件名:My Music PlayerDlg.cpp
*/// My Music PlayerDlg.cpp : 实现文件
//#include "stdafx.h"
#include "My Music Player.h"
#include "My Music PlayerDlg.h"
#include "resource.h"
#include "afxcmn.h"
#include "AboutDlg.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// CMyMusicPlayerDlg 对话框CMyMusicPlayerDlg::CMyMusicPlayerDlg(CWnd* pParent /*=NULL*/): CDialog(CMyMusicPlayerDlg::IDD, pParent), dCurrentPos(0), m_dLength(0), bPause(FALSE), m_strFileName(_T("")), m_strFilePath(_T("")) , pMainMenu(NULL), pTaskbar(NULL), m_nPlayMode(0), m_nCurrentSelection(0), m_strSongTitle(_T("")), m_strArtist(_T("")), m_strAlbum(_T("")), m_strYear(_T("")), m_strSongBitrate(_T(""))
{m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);}void CMyMusicPlayerDlg::DoDataExchange(CDataExchange* pDX)
{CDialog::DoDataExchange(pDX);DDX_Control(pDX, IDC_SLIDERPOS, m_position);DDX_Control(pDX, IDC_SLIDERVOL, sliderVol);DDX_Control(pDX, IDC_COMPLAYMODE, m_playmode);DDX_Control(pDX, IDC_PLAYLIST, m_myListCtrl);DDX_Control(pDX, IDC_EDIT_SONGTITLE, m_edtSongTitle);DDX_Control(pDX, IDC_EDIT_ARTIST, m_edtArtist);DDX_Control(pDX, IDC_EDIT_ALBUM, m_edtAlbum);DDX_Control(pDX, IDC_EDIT_YEAR, m_edtYear);DDX_Control(pDX, IDC_EDIT_SONGBITRATE, m_edtSongBitrate);DDX_Control(pDX, IDC_EDIT_GENRE, m_edtSongGenre);
}BEGIN_MESSAGE_MAP(CMyMusicPlayerDlg, CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()//}}AFX_MSG_MAPON_WM_INITMENUPOPUP()ON_WM_TIMER()ON_WM_HSCROLL()ON_WM_DROPFILES()ON_WM_CLOSE()ON_BN_CLICKED(IDC_BTNOPEN, &CMyMusicPlayerDlg::OnBnClickedBtnopen)ON_BN_CLICKED(IDC_BTNPAUSE, &CMyMusicPlayerDlg::OnBnClickedBtnpause)ON_BN_CLICKED(IDC_BTNPREVIOUS, &CMyMusicPlayerDlg::OnBnClickedBtnoprevious)ON_BN_CLICKED(IDC_BTNNEXT, &CMyMusicPlayerDlg::OnBnClickedBtnnext)  ON_BN_CLICKED(IDC_BTNAHEAD, &CMyMusicPlayerDlg::OnBnClickedBtnahead)ON_BN_CLICKED(IDC_BTNBACK, &CMyMusicPlayerDlg::OnBnClickedBtnback)ON_BN_CLICKED(IDC_BTNADD, &CMyMusicPlayerDlg::OnBnClickedBtnadd)ON_BN_CLICKED(IDC_BTNDELETE, &CMyMusicPlayerDlg::OnBnClickedBtndelete)ON_COMMAND(IDM_FILE_OPEN, &CMyMusicPlayerDlg::OnFileOpen)ON_COMMAND(IDM_FILE_ADDFOLDER, &CMyMusicPlayerDlg::OnFileAddfolder)ON_COMMAND(IDM_APP_EXIT, &CMyMusicPlayerDlg::OnAppExit)ON_COMMAND(IDM_HELP_ABOUT, &CMyMusicPlayerDlg::OnHelpAbout) ON_COMMAND(IDM_CONTROL_PLAY, &CMyMusicPlayerDlg::OnControlPlay)ON_COMMAND(IDM_CONTROL_PAUSE, &CMyMusicPlayerDlg::OnControlPause)ON_COMMAND(IDM_CONTROL_PREVIOUS, &CMyMusicPlayerDlg::OnControlPrevious)ON_COMMAND(IDM_CONTROL_NEXT, &CMyMusicPlayerDlg::OnControlNext)ON_COMMAND(IDM_CONTROL_AHEAD, &CMyMusicPlayerDlg::OnControlAhead)ON_COMMAND(IDM_CONTROL_BACK, &CMyMusicPlayerDlg::OnControlBack) ON_COMMAND(ID_MODE_SEQUENCE, &CMyMusicPlayerDlg::OnModeSequence)ON_COMMAND(ID_MODE_RANDOM, &CMyMusicPlayerDlg::OnModeRandom)ON_COMMAND(ID_MODE_SINGLELOOP, &CMyMusicPlayerDlg::OnModeSingleloop)ON_COMMAND(ID_MODE_SINGLEPLAY, &CMyMusicPlayerDlg::OnModeSingleplay)ON_UPDATE_COMMAND_UI(ID_MODE_SEQUENCE, &CMyMusicPlayerDlg::OnUpdateModeSequence)ON_UPDATE_COMMAND_UI(ID_MODE_RANDOM, &CMyMusicPlayerDlg::OnUpdateModeRandom)ON_UPDATE_COMMAND_UI(ID_MODE_SINGLELOOP, &CMyMusicPlayerDlg::OnUpdateModeSingleloop)ON_UPDATE_COMMAND_UI(ID_MODE_SINGLEPLAY, &CMyMusicPlayerDlg::OnUpdateModeSingleplay)ON_COMMAND(IDM_CONTEXTMENU_PLAYFILE, &CMyMusicPlayerDlg::OnContextmenuPlayfile)ON_COMMAND(IDM_CONTEXTMENU_PAUSE, &CMyMusicPlayerDlg::OnContextmenuPause)ON_COMMAND(IDM_CONTEXTMENU_PREVIOUS, &CMyMusicPlayerDlg::OnContextmenuPrevious)ON_COMMAND(IDM_CONTEXTMENU_NEXT, &CMyMusicPlayerDlg::OnContextmenuNext)ON_COMMAND(IDM_CONTEXTMENU_LOADFILE, &CMyMusicPlayerDlg::OnContextmenuLoadfile)ON_COMMAND(IDM_CONTEXTMENU_DELETEITEM, &CMyMusicPlayerDlg::OnContextmenuDeleteitem)ON_COMMAND(IDM_CONTEXTMENU_OPENFOLDER, &CMyMusicPlayerDlg::OnContextmenuOpenfolder)ON_CBN_SELCHANGE(IDC_COMPLAYMODE, &CMyMusicPlayerDlg::OnCbnSelchangeComplaymode)ON_NOTIFY(NM_RCLICK, IDC_PLAYLIST, &CMyMusicPlayerDlg::OnNMRClickPlaylist)ON_NOTIFY(NM_DBLCLK, IDC_PLAYLIST, &CMyMusicPlayerDlg::OnNMDblclkPlaylist)ON_NOTIFY(NM_CLICK, IDC_PLAYLIST, &CMyMusicPlayerDlg::OnNMClickPlaylist)ON_NOTIFY(LVN_ITEMCHANGED, IDC_PLAYLIST, &CMyMusicPlayerDlg::OnLvnItemchangedPlaylist)
END_MESSAGE_MAP()// CMyMusicPlayerDlg 消息处理程序BOOL CMyMusicPlayerDlg::OnInitDialog()
{CDialog::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);         // 设置大图标SetIcon(m_hIcon, FALSE);        // 设置小图标// TODO: 对话框其他初始化代码InitControls();                 //初始化控件InitMyMenu();                   //初始化菜单InitComboxBox();                //初始化组合框控件InitMyListCtrl();               //初始化列表控件return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}void CMyMusicPlayerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}
}// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。void CMyMusicPlayerDlg::OnPaint()
{if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中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;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialog::OnPaint();}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMyMusicPlayerDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}/************************************************************************/
/* 函数名:InitControls
/* 参数:无     返回值:初始化成功返回TRUE
/* 描述:用于初始化对话框标题、对话框中按钮、播放进度滑块的数值并加载快捷键                                      */
/************************************************************************/BOOL CMyMusicPlayerDlg::InitControls(void)
{/************************************************************************//* 初始化每个控件内容和位置                                                        */            /************************************************************************/  this->SetWindowText(TEXT("My Music Player"));this->SetDlgItemText(IDC_CURRENT_POS, TEXT("00:00"));this->SetDlgItemText(IDC_TOTAL_LENGTH, TEXT("00:00"));m_position.SetPos(0);                //初始化播放进度控件滑块值sliderVol.SetRange(0,100);           //设置音量控件的范围sliderVol.SetPos(0);                //初始化音量控件滑块值hAccel = ::LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));return TRUE;
}
/************************************************************************/
/* 函数名:InitMyMenu
/* 参数:无     返回值:初始化成功返回TRUE
/* 描述:初始化并加载主菜单,同时并获得播放控制菜单的句柄,用于更新菜单项状态   */
/************************************************************************/
BOOL CMyMusicPlayerDlg::InitMyMenu(void)
{pMainMenu  =  new CMenu();pMainMenu->LoadMenu(IDR_MAINFRAME);         //  IDR_MAINFRAME为菜单IDpSubPlayMenu = pMainMenu->GetSubMenu(1);    //得到播放控制菜单的句柄,索引从0开始SetMenu(pMainMenu);pMainMenu->Detach();return TRUE;
}
/************************************************************************/
/* 函数名:InitComboxBox
/* 参数:无     返回值:初始化成功返回TRUE
/* 描述:初始化播放模式组合框的项目                                        */
/************************************************************************/
BOOL CMyMusicPlayerDlg::InitComboxBox(void)
{m_playmode.InsertString(-1,TEXT("顺序播放"));m_playmode.InsertString(-1,TEXT("随机播放"));m_playmode.InsertString(-1,TEXT("单曲循环"));m_playmode.InsertString(-1,TEXT("单曲播放"));m_playmode.SetCurSel(0);return TRUE;
}
/************************************************************************/
/* 函数名:InitMyListCtrl
/* 参数:无     返回值:初始化成功返回TRUE
/* 描述:初始化列表控件的风格,并初始化列表控件的列内容                                      */
/************************************************************************/
BOOL CMyMusicPlayerDlg::InitMyListCtrl(void)
{m_myListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT );m_myListCtrl.ModifyStyle(0,LVS_REPORT|LVS_SHOWSELALWAYS|LVS_SINGLESEL);LVCOLUMN lvc;lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH ;lvc.fmt  = LVCFMT_CENTER ;lvc.cx   = SERIALNUMBERWIDTH ;lvc.pszText = _T("序号");m_myListCtrl.InsertColumn(ID_SERIALNUMBER, &lvc);lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;lvc.fmt = LVCFMT_LEFT;lvc.cx = FILENAMEWIDTH;lvc.pszText = _T("文件名");m_myListCtrl.InsertColumn(ID_FILENAME, &lvc);lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;lvc.fmt = LVCFMT_LEFT;lvc.cx = FILEPATHWIDTH;lvc.pszText = _T("文件路径");m_myListCtrl.InsertColumn(ID_FILEPATH, &lvc);lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;lvc.fmt = LVCFMT_CENTER;lvc.cx = FILEDURATIONWIDTH;lvc.pszText = _T("时长");m_myListCtrl.InsertColumn(ID_FILEDURATION, &lvc);return 0;
}
/************************************************************************/
/* 函数名:TaskBarInit
/* 参数:无     返回值:无
/* 描述:初始化COM组件,主要用于在任务栏上显示歌曲播放进度。                                      */
/************************************************************************/
void CMyMusicPlayerDlg::TaskBarInit(void)
{CoInitialize(0);        //初始化COM组件。CoCreateInstance(CLSID_TaskbarList , NULL , CLSCTX_INPROC_SERVER , IID_PPV_ARGS (&pTaskbar));pTaskbar->HrInit();
}/************************************************************************/
/* 函数名:LoadFile
/* 参数:无     返回值:成功加载返回TRUE,否则返回FALSE
/* 描述:用于打开选择文件对话框,加载文件。                                 */
/************************************************************************/BOOL CMyMusicPlayerDlg::LoadFile(void)
{//打开文件对话框支持的文件扩展名LPCTSTR szFilters = TEXT("支持的音频文件(*.wav;*mp3;*.wma) |*.wav;*mp3;*.wma|所有文件 (*.*)|*.*||");//创建一个打开文件对话框对象CFileDialog FileDlg(TRUE,TEXT("mp3"),NULL,OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST , szFilters );if(IDCANCEL == FileDlg.DoModal()){return FALSE;}else {m_strFilePath = FileDlg.GetPathName();                  //文件路径名m_strFileName = FileDlg.GetFileTitle();                 //文件名GetMp3Info(m_strFilePath);                              //获取mp3的tag信息this->SetWindowText(m_strFileName + TEXT(" 状态:播放")); //设置对话框窗口标题return TRUE;}return FALSE;
}
/************************************************************************/
/* 函数名:GetMp3Info
/* 参数:文件路径
/* 描述:用于获取音频文件的歌手,艺术家,专辑,发行时间等信息,支持ID3v1, ID3V2的tag信息读取 */
/************************************************************************/
void CMyMusicPlayerDlg::GetMp3Info(CString strFilePath)
{//由于MP3Info类只支持多字节,所以将宽字节转换为多字节int len = WideCharToMultiByte( CP_ACP , 0 , strFilePath , strFilePath.GetLength() , NULL , 0 , NULL , NULL );char* pAscii =new char[len+1];len = WideCharToMultiByte( CP_ACP , 0 , strFilePath , strFilePath.GetLength() , pAscii , len +1 , NULL ,NULL );pAscii[len] = 0;if(!mp3info.Init(pAscii)){return ;}else{m_strSongTitle =  mp3info.szTitle;      m_strArtist = mp3info.szArtist;m_strAlbum = mp3info.szAlbum;m_strYear = mp3info.szYear;m_strSongBitrate = mp3info.szBitRate;m_strSongGenre = mp3info.szGenre;mp3info.Free();m_edtSongTitle.SetWindowText(m_strSongTitle);m_edtArtist.SetWindowText(m_strArtist);m_edtAlbum.SetWindowText(m_strAlbum);m_edtYear.SetWindowText(m_strYear);m_edtSongBitrate.SetWindowText(m_strSongBitrate);m_edtSongGenre.SetWindowText(m_strSongGenre);UpdateData(FALSE);}}/************************************************************************/
/* 函数名:PlayFile
/* 参数:歌曲文件的路径
/* 描述:播放音频文件                                */
/************************************************************************/BOOL CMyMusicPlayerDlg::PlayFile(CString szFilePath)
{bPause = FALSE;                    //初始化暂停标记为TRUESetTimer(ID_PLAYTIMER,1000,NULL); //初始化定时器,用于显示播放进度mciSendCommand(m_wDeviceID,MCI_CLOSE, 0, NULL); //在打开新文件之前,先关闭之前的文件MCI_OPEN_PARMS mciOpen; //打开参数MCI_PLAY_PARMS mciPlay; //播放参数mciOpen.lpstrElementName = szFilePath.GetBuffer(szFilePath.GetLength()); //设置播放路径szFilePath.ReleaseBuffer(szFilePath.GetLength());//发送打开命令MCIERROR err = mciSendCommand(NULL,MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)(LPVOID)&mciOpen);/*MCI_OPEN_ELEMENT 表示MCI_OPEN_PARMS的lpstrElementName有效 MCI_OPEN_TYPE表示MCI_OPEN_PARMS的lpstrDeviceType有效 MCI_WAIT表示命令发送后会一直等待,直到操作完成 (如果是MCI_NOTIFY,则表示发送命令后会立即返回,当操作真正完毕后发出通告消息)*/if (err) {mciGetErrorString(err,strMciError,sizeof(strMciError));if (IDOK == AfxMessageBox(strMciError, MB_OK | MB_ICONERROR)){return FALSE ;} }else {m_wDeviceID = mciOpen.wDeviceID ;      //保存设备ID    MCI_STATUS_PARMS mciStatus;            //声明保存文件信息的结构体mciStatus.dwItem = MCI_STATUS_LENGTH ; //需要获取的项mciSendCommand(m_wDeviceID,MCI_STATUS,MCI_WAIT |  MCI_STATUS_ITEM,(DWORD)(LPVOID)&mciStatus); //MCI_STATUS_ITEM 表示MCI_STATUS_PARMS的dwItem有效//mciSendCommand发送MCI_STATUS命令获得MIC_STATUS_LENGTH信息,并将信息保存在变量mciStatus中。m_dLength = mciStatus.dwReturn ; // The dwReturn member is set to the total media length. (From MSDN)    mciSendCommand(m_wDeviceID,MCI_PLAY,0 ,(DWORD)(LPVOID)&mciPlay); //发送播放命令pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PLAY,MF_CHECKED);//打开文件后初始化各个控件的数值pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PAUSE, MF_UNCHECKED);m_position.SetRange(0,m_dLength);             //设置播放进度控件的范围m_position.SetPos(0);                         //设置播放进度控件的初始值sliderVol.SetPos(50);                         //初始化音量控件的滑块位置CString strVolume;strVolume.Format(TEXT("%d"),50);this->SetDlgItemText(IDC_EDITVOL,strVolume);SetVolume(50);                                //设置音频的初始音量大小m_strTotalLength = ConvertTimeToString(m_dLength);this->SetDlgItemText(IDC_TOTAL_LENGTH,m_strTotalLength);UpdateData(FALSE);TaskBarInit();                                //初始化TaskbarbPause = TRUE;                                //暂停标记return TRUE;} return FALSE ;
}/************************************************************************/
/* 函数名:PauseMe
/* 参数:无
/* 描述:暂停当前播放文件。                                             */
/************************************************************************/void CMyMusicPlayerDlg::PauseMe()
{if (bPause)                          //如果bPause为真{bPause = FALSE ; //toggle itSetWindowTitle(m_strFileName, bPause);MCI_GENERIC_PARMS mciPause; //mci暂停参数mciSendCommand(m_wDeviceID,MCI_PAUSE,0,(DWORD)(LPVOID)&mciPause);//发送暂停命令SetDlgItemText(IDC_BTNPAUSE,TEXT("播放"));//设置播放列表中菜单项 暂停 为选中pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PAUSE,MF_CHECKED);//设置播放列表中菜单项 播放 为不选中pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PLAY,MF_UNCHECKED);}else{bPause = TRUE ;SetWindowTitle(m_strFileName, bPause);MCI_PLAY_PARMS mciPlay;mciSendCommand(m_wDeviceID,MCI_PLAY,0,(DWORD)(LPVOID)&mciPlay);//发送播放命令SetDlgItemText(IDC_BTNPAUSE,TEXT("暂停"));pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PLAY,MF_CHECKED);pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PAUSE,MF_UNCHECKED);}
}
// 设置窗口标题
void CMyMusicPlayerDlg::SetWindowTitle(CString fileName, int nPlayingFlag)
{if (nPlayingFlag){this->SetWindowText(fileName + TEXT(" 状态:播放"));return ;}else{this->SetWindowText(fileName + TEXT(" 状态:暂停"));return ;}}/************************************************************************/
/* 函数名:GoPrevious
/* 参数:无
/* 描述:上一曲功能函数                                */
/************************************************************************/void CMyMusicPlayerDlg::GoPrevious(void)
{if (0 == m_myListCtrl.GetItemCount()){mciSendCommand(NULL, MCI_CLOSE, 0, 0);return ;}else {GetCurrentSelection();if (m_nCurrentSelection == 0) //如果在第一个位置{m_nCurrentSelection = m_myListCtrl.GetItemCount() - 1; //把选中项倒置到最后}else{m_nCurrentSelection = m_nCurrentSelection - 1; }m_myListCtrl.SetFocus();m_myListCtrl.SetItemState(m_nCurrentSelection, LVIS_SELECTED, LVIS_SELECTED);   //设置选中行m_strFileName = m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILENAME); //获得文件名m_strFilePath = m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILEPATH); //得到选中位置的文本PlayFile(m_strFilePath);            //播放文件GetMp3Info(m_strFilePath);                                   SetWindowTitle(m_strFileName, bPause);}}
/************************************************************************/
/* 函数名:GoNext
/* 参数:无
/* 描述:下一曲功能函数                                */
/************************************************************************/
void CMyMusicPlayerDlg::GoNext(void)
{if (0 == m_myListCtrl.GetItemCount()){mciSendCommand(NULL, MCI_CLOSE, 0 , 0);return ;}else {GetCurrentSelection();                              //获得当前播放列表的选中项位置if (m_nCurrentSelection ==  m_myListCtrl.GetItemCount() - 1) //如果在最后一个位置{m_nCurrentSelection = 0 ; //把当前索引移到第一个位置}else{m_nCurrentSelection = m_nCurrentSelection + 1;}m_myListCtrl.SetFocus();m_myListCtrl.SetItemState(m_nCurrentSelection, LVIS_SELECTED, LVIS_SELECTED);m_strFileName = m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILENAME);m_strFilePath = m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILEPATH); //得到选中位置的文本//播放文件PlayFile(m_strFilePath);GetMp3Info(m_strFilePath);SetWindowTitle(m_strFileName, bPause);}}
/************************************************************************/
/* 函数名:GoAhead
/* 参数:无
/* 描述:快进5秒功能函数                                */
/************************************************************************/void CMyMusicPlayerDlg::GoAhead(void)
{int iPosition = m_position.GetPos(); //得到slider控件的滑块位置MCI_SEEK_PARMS mciSeek;             //mci设备查找参数MCI_PLAY_PARMS mciPlay;mciSeek.dwTo = iPosition;           //设置seek的位置mciSeek.dwTo += 5000;               //增加5秒mciPlay.dwFrom = mciSeek.dwTo ;     //设置播放的位置dwFrommciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO,(DWORD)(LPVOID)&mciSeek);mciSendCommand(m_wDeviceID,MCI_PLAY,MCI_FROM | MCI_NOTIFY, (DWORD)(LPVOID)&mciPlay);//MCI_FROM 使dwForm有效m_position.SetPos(mciPlay.dwFrom); //设置滑块的新位置}
/************************************************************************/
/* 函数名:GoBack
/* 参数:无
/* 描述:快退5秒功能函数                                */
/************************************************************************/void CMyMusicPlayerDlg::GoBack(void)
{int iPosition = m_position.GetPos(); //得到slider控件的滑块位置MCI_SEEK_PARMS mciSeek;  MCI_PLAY_PARMS mciPlay;mciSeek.dwTo = iPosition; //设置跳转后的位置mciSeek.dwTo -= 5000;mciPlay.dwFrom = mciSeek.dwTo ; //设置播放位置mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO,(DWORD)(LPVOID)&mciSeek);mciSendCommand(m_wDeviceID,MCI_PLAY,MCI_FROM | MCI_NOTIFY, (DWORD)(LPVOID)&mciPlay);m_position.SetPos(mciPlay.dwFrom);
}/************************************************************************/
/* 函数名:AddFileToPlayList
/* 参数:无
/* 描述:增加歌曲函数,同时在列表控件增加项目。                                 */
/************************************************************************/
void CMyMusicPlayerDlg::AddFileToPlayList(void)
{LVITEM  item;            int     nIndex;              //当前索引位置(行)CString strTmp; item.mask = LVIF_TEXT;  item.iSubItem = 0;//If 'm_listListOperations.GetItemCount() <= 0' evaluates to TRUE then 0, //else  value returned by 'm_listListOperations.GetItemCount()'//iItem holds the current indexitem.iItem = (m_myListCtrl.GetItemCount() <= 0) ? 0 : m_myListCtrl.GetItemCount(); strTmp.Format(TEXT("%d"), ++item.iItem);                //格式化当前索引item.pszText = strTmp.GetBuffer(strTmp.GetLength());    //在第一列插入序号nIndex = m_myListCtrl.InsertItem(&item);                //在第一列插入序号m_myListCtrl.SetItemText(nIndex, ID_FILENAME, m_strFileName);   //second column of the ListCtrlm_myListCtrl.SetItemText(nIndex, ID_FILEPATH, m_strFilePath);m_myListCtrl.SetItemText(nIndex, ID_FILEDURATION, m_strTotalLength);m_myListCtrl.SetFocus();m_myListCtrl.SetItemState(nIndex, LVIS_SELECTED, LVIS_SELECTED);
}/************************************************************************/
/* 函数名:DeleteItem
/* 参数:无
/* 描述:删除歌曲项目,同时在列表控件删除文本。                                 */
/************************************************************************/
void CMyMusicPlayerDlg::DeleteItem(void)
{CString strTmp;GetCurrentSelection();strTmp = m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILEPATH);if (strTmp == m_strFilePath){m_myListCtrl.DeleteItem(m_nCurrentSelection);mciSendCommand(m_wDeviceID, MCI_STOP, 0, 0);InitControls();}else {m_myListCtrl.DeleteItem(m_nCurrentSelection);m_nCurrentSelection--;m_myListCtrl.SetFocus();m_myListCtrl.SetItemState(m_nCurrentSelection, LVIS_SELECTED, LVIS_SELECTED);}
}
/************************************************************************/
/* 函数名:SetVolume
/* 参数: 音量值:Vol, 类型:int
/* 描述:增加歌曲函数,同时在列表框增加文本。                                 */
/************************************************************************/void CMyMusicPlayerDlg::SetVolume(int Vol)
{MCI_DGV_SETAUDIO_PARMS mciSetAudioPara; //设置音量参数mciSetAudioPara.dwItem = MCI_DGV_SETAUDIO_VOLUME; mciSetAudioPara.dwCallback = (DWORD_PTR)this->GetSafeHwnd();//设置音量大小mciSetAudioPara.dwValue = Vol * 10; //here is the value of the Volume(0--1000) mciSendCommand(m_wDeviceID, MCI_SETAUDIO, MCI_DGV_SETAUDIO_VALUE | MCI_DGV_SETAUDIO_ITEM, (DWORD)(LPVOID)&mciSetAudioPara);
}/************************************************************************/
/* 函数名:UpdatePosition
/* 参数:无
/* 描述:更新播放时间控件中的文本                                          */
/************************************************************************/
void CMyMusicPlayerDlg::UpdateCurrentPosText(void)
{MCI_STATUS_PARMS mciStatus;mciStatus.dwItem = MCI_STATUS_POSITION;mciSendCommand(m_wDeviceID,MCI_STATUS,MCI_WAIT|MCI_STATUS_ITEM,(DWORD)(LPVOID)&mciStatus);int dCurrentPos = mciStatus.dwReturn;m_strCurrentLength = ConvertTimeToString(dCurrentPos);  //将得到的毫秒转换为分钟和秒SetDlgItemText(IDC_CURRENT_POS,m_strCurrentLength);
}
/************************************************************************/
/* 函数名:SetPlayMode
/* 参数:无
/* 描述:设置播放模式并播放文件                                               */
/************************************************************************/
void CMyMusicPlayerDlg::SetPlayMode(void)
{srand((unsigned int)time(NULL));    //初始化随机种子int randNum = 0;int nCurrentSel;switch (m_nPlayMode){case SEQUENCE_MODE:GoNext();break;case RANDOM_MODE:randNum = rand() % m_myListCtrl.GetItemCount();m_myListCtrl.SetFocus();m_myListCtrl.SetItemState(randNum,LVIS_SELECTED,  LVIS_SELECTED);nCurrentSel  =  m_myListCtrl.GetNextItem  (-1,  LVNI_SELECTED); //得到选中行的索引位置m_strFilePath =  m_myListCtrl.GetItemText(nCurrentSel,ID_FILEPATH);m_strFileName =  m_myListCtrl.GetItemText(nCurrentSel, ID_FILENAME);PlayFile(m_strFilePath);GetMp3Info(m_strFilePath);SetWindowTitle(m_strFileName, bPause);break;case SINGLE_LOOP:GetCurrentSelection();m_strFilePath =  m_myListCtrl.GetItemText(m_nCurrentSelection,ID_FILEPATH);m_strFileName =  m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILENAME);PlayFile(m_strFilePath);GetMp3Info(m_strFilePath);SetWindowTitle(m_strFileName, bPause);break;case SINGLE_PLAY:mciSendCommand(m_wDeviceID, MCI_STOP, NULL, NULL);InitControls();break;default:break;}
}
/************************************************************************/
/* 函数名:ConvertTimeToString
/* 参数:时间:time(毫秒为单位), 类型:int
/* 描述:增加歌曲函数,同时在列表框增加文本。                                 */
/************************************************************************/CString CMyMusicPlayerDlg::ConvertTimeToString(int time)
{CString strTmp;int nTotalSecond = 0 ;int nTotalMinute = 0;nTotalSecond = time / 1000; //先将毫秒转换为秒if (nTotalSecond < 60)     //如果秒数小于1分钟{nTotalMinute = 0;strTmp.Format(TEXT("%02d:%02d"),nTotalMinute,nTotalSecond);return strTmp;}else {nTotalMinute = nTotalSecond / 60;  //得到分钟数nTotalSecond = nTotalSecond % 60;  //得到总秒数strTmp.Format(TEXT("%02d:%02d"),nTotalMinute,nTotalSecond);return strTmp;}
}
/************************************************************************/
/* 函数名:GetCurrentSelection
/* 参数:无
/* 描述:获得当前列表控件选中项的位置                                 */
/************************************************************************/
void CMyMusicPlayerDlg::GetCurrentSelection(void)
{int nIndexSelection = 0;POSITION pos =  m_myListCtrl.GetFirstSelectedItemPosition();     nIndexSelection = m_myListCtrl.GetNextSelectedItem(pos); //获得当前播放列表的选中项位置m_nCurrentSelection = nIndexSelection;
}
//从文件路径中分析出文件名称(带扩展名)。
int CMyMusicPlayerDlg::ParseFilePath(CString strFilePath)
{int nFileNamePos = 0;int nFilePathLength = 0;m_strFilePath = strFilePath;nFileNamePos = strFilePath.ReverseFind(TEXT('\\'));nFilePathLength = strFilePath.GetLength();m_strFileName = strFilePath.Right(nFilePathLength - nFileNamePos - 1); //从文件路径里分析出文件名return 0;
}//支持键盘加速键并屏蔽Enter键和Esc键关闭对话框
BOOL CMyMusicPlayerDlg::PreTranslateMessage(MSG* pMsg)
{if (::TranslateAccelerator(GetSafeHwnd(), hAccel, pMsg)){return TRUE;}if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) //屏蔽掉回车键关闭对话框{return FALSE;}if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) //屏蔽掉ESC键关闭对话框{return FALSE;}return CDialog::PreTranslateMessage(pMsg);
}//使对话框支持菜单更新命令(Code From MSDN)
void CMyMusicPlayerDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{ASSERT(pPopupMenu != NULL);  CCmdUI state;  state.m_pMenu = pPopupMenu;  ASSERT(state.m_pOther == NULL);  ASSERT(state.m_pParentMenu == NULL);  HMENU hParentMenu;  if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)  state.m_pParentMenu = pPopupMenu;      else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)  {  CWnd* pParent = this;  if (pParent != NULL &&  (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)  {  int nIndexMax = ::GetMenuItemCount(hParentMenu);  for (int nIndex = 0; nIndex < nIndexMax; nIndex++)  {  if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)  {  state.m_pParentMenu = CMenu::FromHandle(hParentMenu);  break;  }  }  }  }  state.m_nIndexMax = pPopupMenu->GetMenuItemCount();  for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;  state.m_nIndex++)  {  state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);  if (state.m_nID == 0)  continue;   ASSERT(state.m_pOther == NULL);  ASSERT(state.m_pMenu != NULL);  if (state.m_nID == (UINT)-1)  {  state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);  if (state.m_pSubMenu == NULL ||  (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||  state.m_nID == (UINT)-1)  {  continue;        }  state.DoUpdate(this, TRUE);    }  else  {  state.m_pSubMenu = NULL;  state.DoUpdate(this, FALSE);  }  UINT nCount = pPopupMenu->GetMenuItemCount();  if (nCount < state.m_nIndexMax)  {  state.m_nIndex -= (state.m_nIndexMax - nCount);  while (state.m_nIndex < nCount &&  pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)  {  state.m_nIndex++;  }  }  state.m_nIndexMax = nCount;  } CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);}/************************************************************************/
/* 函数名:OnTimer
/* 参数:无
/* 描述:使用定时器来更新滑块位置                                 */
/************************************************************************/void CMyMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent)
{// TODO: 在此添加消息处理程序代码和/或调用默认值MCI_STATUS_PARMS mciStatus;mciStatus.dwItem = MCI_STATUS_POSITION;mciSendCommand(m_wDeviceID,MCI_STATUS,MCI_STATUS_ITEM,((DWORD)(LPVOID)&mciStatus));dCurrentPos = mciStatus.dwReturn ; //获得当前的播放进度m_position.SetPos(dCurrentPos);    //设置播放滑块的位置//处理任务栏上的进度显示pTaskbar->SetProgressState(this->GetSafeHwnd(), bPause ? TBPF_INDETERMINATE : TBPF_PAUSED);pTaskbar->SetProgressValue(this->GetSafeHwnd(), dCurrentPos, m_dLength);UpdateCurrentPosText();            //更新并设置当前文件播放时间文本if (m_position.GetPos() == m_dLength) //播放结束文件后跳至下个一文件{SetPlayMode();}CDialog::OnTimer(nIDEvent);
}//处理滑块拖动事件
//我花了好大功夫才弄好的
void CMyMusicPlayerDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{// TODO: 在此添加消息处理程序代码和/或调用默认值if (*pScrollBar == sliderVol){int iVol = sliderVol.GetPos();SetVolume(iVol);CString temp;temp.Format(TEXT("%d"),iVol );SetDlgItemText(IDC_EDITVOL,temp);}int iPosition = m_position.GetPos(); //得到slider控件的滑块位置MCI_SEEK_PARMS mciSeek; // MCI_PLAY_PARMS mciPlay;mciSeek.dwTo = iPosition; //设置跳转后的位置mciPlay.dwFrom = mciSeek.dwTo ; //设置播放位置mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO,(DWORD)(LPVOID)&mciSeek);mciSendCommand(m_wDeviceID,MCI_PLAY,MCI_FROM | MCI_NOTIFY, (DWORD)(LPVOID)&mciPlay);m_position.SetPos(mciPlay.dwFrom);bPause = TRUE;CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
//对话框支持拖放
void CMyMusicPlayerDlg::OnDropFiles(HDROP hDropInfo)
{// TODO: 在此添加消息处理程序代码和/或调用默认值int nFileNamePos = 0;int nFilePathLength = 0;CString m_FilePath; ::DragQueryFile(hDropInfo, 0, m_FilePath.GetBuffer(MAX_PATH), MAX_PATH); m_FilePath.ReleaseBuffer(); nFileNamePos = m_FilePath.ReverseFind(TEXT('\\'));nFilePathLength = m_FilePath.GetLength();m_strFileName = m_FilePath.Right(nFilePathLength - nFileNamePos - 1); //从文件路径里分析出文件名m_strFilePath = m_FilePath;PlayFile(m_strFilePath);GetMp3Info(m_strFilePath);ConvertTimeToString(m_dLength);AddFileToPlayList();::DragFinish(hDropInfo);   // 注意这个不能少,它用于释放Windows 为处理文件拖放而分配的内存  CDialog::OnDropFiles(hDropInfo);
}void CMyMusicPlayerDlg::OnClose()
{// TODO: 在此添加消息处理程序代码和/或调用默认值KillTimer(ID_PLAYTIMER);CDialog::OnClose();
}//
//每个按钮的逻辑
//void CMyMusicPlayerDlg::OnBnClickedBtnopen()
{if (LoadFile()){GetCurrentSelection();m_myListCtrl.SetItemState(m_nCurrentSelection,LVNI_FOCUSED | LVIS_SELECTED, LVNI_FOCUSED | LVIS_SELECTED);pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PLAY, MF_CHECKED);PlayFile(m_strFilePath);GetMp3Info(m_strFilePath);ConvertTimeToString(m_dLength);AddFileToPlayList();}else{return ;// AfxMessageBox(TEXT("你没有打开文件"),MB_ICONINFORMATION,NULL);}
}void CMyMusicPlayerDlg::OnBnClickedBtnpause()
{PauseMe();}void CMyMusicPlayerDlg::OnBnClickedBtnoprevious()
{GoPrevious();
}void CMyMusicPlayerDlg::OnBnClickedBtnnext()
{GoNext();
}void CMyMusicPlayerDlg::OnBnClickedBtnahead()
{GoAhead();
}void CMyMusicPlayerDlg::OnBnClickedBtnback()
{// TODO: 在此添加控件通知处理程序代码GoBack();
}void CMyMusicPlayerDlg::OnBnClickedBtnadd()
{if (LoadFile()){GetCurrentSelection();m_myListCtrl.SetItemState(m_nCurrentSelection,LVNI_FOCUSED | LVIS_SELECTED, LVNI_FOCUSED | LVIS_SELECTED);m_strTotalLength.Format(TEXT("%02d:%02d"), mp3info.nLength / 60, mp3info.nLength % 60);AddFileToPlayList();}else{return ;// AfxMessageBox(TEXT("你没有打开文件"),MB_ICONINFORMATION,NULL);}}void CMyMusicPlayerDlg::OnBnClickedBtndelete()
{DeleteItem();
}/************************************************************************/
/* 菜单逻辑                                                                     */
/************************************************************************/
void CMyMusicPlayerDlg::OnFileOpen()
{CMyMusicPlayerDlg::OnBnClickedBtnopen();}
void CMyMusicPlayerDlg::OnFileAddfolder()
{// TODO: 在此添加命令处理程序代码TCHAR szDisplayName[MAX_PATH] = {0};BROWSEINFO bi;CString strFindFormat;int nCounter = 0;CStringArray arrFilePath;arrFilePath.SetSize(0, 1);ZeroMemory(&bi, sizeof(BROWSEINFO));bi.hwndOwner        = this->m_hWnd ;bi.iImage           = NULL;bi.lParam           = NULL;bi.lpfn             = NULL;bi.lpszTitle        = TEXT("请选择需要添加的文件夹");bi.pidlRoot         = NULL;bi.pszDisplayName   = szDisplayName;bi.ulFlags          = BIF_NEWDIALOGSTYLE | BIF_DONTGOBELOWDOMAIN  | BIF_BROWSEFORCOMPUTER | BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS;  LPITEMIDLIST pIDList = SHBrowseForFolder(&bi);  if (pIDList != NULL)  {  memset(szDisplayName, 0, sizeof(szDisplayName));  SHGetPathFromIDList(pIDList, szDisplayName);  m_strFilePath = szDisplayName;}  strFindFormat = m_strFilePath + TEXT("\\*.mp3");CFileFind finder;BOOL bWorking;bWorking = finder.FindFile(strFindFormat);while (bWorking){bWorking = finder.FindNextFile();arrFilePath.SetAtGrow(nCounter, finder.GetFilePath());++nCounter;     }for (int i = 0; i < nCounter; i++){if (PlayFile(arrFilePath[i])){ParseFilePath(arrFilePath[i]);AddFileToPlayList();}}m_myListCtrl.SetItemState(m_myListCtrl.GetItemCount() - 1 ,LVNI_FOCUSED | LVIS_SELECTED, LVNI_FOCUSED | LVIS_SELECTED);m_myListCtrl.EnsureVisible(m_myListCtrl.GetItemCount()-1,FALSE); SetWindowTitle(m_strFileName, bPause);
}void CMyMusicPlayerDlg::OnAppExit()
{SendMessage(WM_CLOSE,0,0);
}void CMyMusicPlayerDlg::OnHelpAbout()
{CAboutDlg aboutdlg;aboutdlg.DoModal();
}
void CMyMusicPlayerDlg::OnControlPlay()
{bPause = TRUE ;MCI_PLAY_PARMS mciPlay;mciSendCommand(m_wDeviceID,MCI_PLAY,0,(DWORD)(LPVOID)&mciPlay);this->SetWindowText(m_strFileName + TEXT(" 状态:播放"));this->SetDlgItemText(IDC_BTNPAUSE,TEXT("暂停"));pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PLAY,MF_CHECKED);pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PAUSE,MF_UNCHECKED);
}void CMyMusicPlayerDlg::OnControlPause()
{// TODO: 在此添加命令处理程序代码PauseMe();this->SetDlgItemText(IDC_BTNPAUSE,TEXT("播放"));pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PAUSE,MF_CHECKED);pSubPlayMenu->CheckMenuItem(IDM_CONTROL_PLAY,MF_UNCHECKED);
}void CMyMusicPlayerDlg::OnControlPrevious()
{// TODO: 在此添加命令处理程序代码GoPrevious();
}void CMyMusicPlayerDlg::OnControlNext()
{GoNext();
}void CMyMusicPlayerDlg::OnControlAhead()
{GoAhead();
}void CMyMusicPlayerDlg::OnControlBack()
{GoBack();
}/************************************************************************/
/* 设置播放模式菜单逻辑                                                                    */
/************************************************************************/void CMyMusicPlayerDlg::OnModeSequence()
{// TODO: 在此添加命令处理程序代码m_nPlayMode = SEQUENCE_MODE;m_playmode.SetCurSel(SEQUENCE_MODE);
}void CMyMusicPlayerDlg::OnModeRandom()
{// TODO: 在此添加命令处理程序代码m_nPlayMode = RANDOM_MODE;m_playmode.SetCurSel(RANDOM_MODE);
}void CMyMusicPlayerDlg::OnModeSingleloop()
{// TODO: 在此添加命令处理程序代码m_nPlayMode = SINGLE_LOOP;m_playmode.SetCurSel(SINGLE_LOOP);
}void CMyMusicPlayerDlg::OnModeSingleplay()
{// TODO: 在此添加命令处理程序代码m_nPlayMode = SINGLE_PLAY;m_playmode.SetCurSel(SINGLE_PLAY);
}
//播放模式菜单更新逻辑
void CMyMusicPlayerDlg::OnUpdateModeSequence(CCmdUI *pCmdUI)
{// TODO: 在此添加命令更新用户界面处理程序代码pCmdUI->SetRadio(m_nPlayMode == SEQUENCE_MODE);}void CMyMusicPlayerDlg::OnUpdateModeRandom(CCmdUI *pCmdUI)
{// TODO: 在此添加命令更新用户界面处理程序代码pCmdUI->SetRadio(m_nPlayMode == RANDOM_MODE);
}void CMyMusicPlayerDlg::OnUpdateModeSingleloop(CCmdUI *pCmdUI)
{// TODO: 在此添加命令更新用户界面处理程序代码pCmdUI->SetRadio(m_nPlayMode == SINGLE_LOOP);
}void CMyMusicPlayerDlg::OnUpdateModeSingleplay(CCmdUI *pCmdUI)
{// TODO: 在此添加命令更新用户界面处理程序代码pCmdUI->SetRadio(m_nPlayMode == SINGLE_PLAY);
}
//播放列表控件菜单项逻辑
void CMyMusicPlayerDlg::OnContextmenuPlayfile()
{// TODO: 在此添加命令处理程序代码GetCurrentSelection();m_strFilePath =  m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILEPATH);PlayFile(m_strFilePath);
}
void CMyMusicPlayerDlg::OnContextmenuPause()
{// TODO: 在此添加命令处理程序代码PauseMe();
}void CMyMusicPlayerDlg::OnContextmenuPrevious()
{// TODO: 在此添加命令处理程序代码GoPrevious();
}void CMyMusicPlayerDlg::OnContextmenuNext()
{// TODO: 在此添加命令处理程序代码GoNext();
}void CMyMusicPlayerDlg::OnContextmenuLoadfile()
{// TODO: 在此添加命令处理程序代码LoadFile();if (!PlayFile(m_strFilePath)){AfxMessageBox(strMciError);return ;}AddFileToPlayList();
}void CMyMusicPlayerDlg::OnContextmenuDeleteitem()
{// TODO: 在此添加命令处理程序代码DeleteItem();
}//利用Shell来打开文件路径
void CMyMusicPlayerDlg::OnContextmenuOpenfolder()
{// TODO: 在此添加命令处理程序代码CString strFilePath;GetCurrentSelection();if (-1 != m_nCurrentSelection){strFilePath =  m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILEPATH);strFilePath = TEXT("/select,") + strFilePath;               //select选中此文件::ShellExecute( NULL, _T("open"), _T("explorer.exe"), strFilePath, NULL, SW_SHOWNORMAL );}
}//在列表控件上单击鼠标右键,显示上下文菜单。
void CMyMusicPlayerDlg::OnNMRClickPlaylist(NMHDR *pNMHDR, LRESULT *pResult)
{LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// TODO: 在此添加控件通知处理程序代码GetCurrentSelection();if (m_nCurrentSelection != -1){CMenu menu;DWORD dwPos = GetMessagePos();CPoint point( LOWORD(dwPos), HIWORD(dwPos) );VERIFY( menu.LoadMenu(IDR_CONTEXTMENU));     CMenu* popupMenu = menu.GetSubMenu(0);if (bPause){popupMenu->CheckMenuItem(IDM_CONTEXTMENU_PLAYFILE, MF_CHECKED);}else{popupMenu->CheckMenuItem(IDM_CONTEXTMENU_PAUSE, MF_CHECKED);}ASSERT( popup != NULL );popupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd()  );}*pResult = 0;
}
//在列表控件上双击某个项目
void CMyMusicPlayerDlg::OnNMDblclkPlaylist(NMHDR *pNMHDR, LRESULT *pResult)
{LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// TODO: 在此添加控件通知处理程序代码GetCurrentSelection();if (-1 != m_nCurrentSelection){m_strFileName =  m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILENAME);m_strFilePath =  m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILEPATH);GetMp3Info(m_strFilePath);PlayFile(m_strFilePath);    SetWindowTitle(m_strFileName, bPause);}*pResult = 0;
}
//在列表控件上单击项目可以显示音频文件的tag信息
void CMyMusicPlayerDlg::OnNMClickPlaylist(NMHDR *pNMHDR, LRESULT *pResult)
{LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// TODO: 在此添加控件通知处理程序代码GetCurrentSelection();if (-1 != m_nCurrentSelection){m_strFileName =  m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILENAME);m_strFilePath =  m_myListCtrl.GetItemText(m_nCurrentSelection, ID_FILEPATH);GetMp3Info(m_strFilePath);}*pResult = 0;
}
//播放模式组合框内容变化
void CMyMusicPlayerDlg::OnCbnSelchangeComplaymode()
{int nIndex = m_playmode.GetCurSel();m_nPlayMode = nIndex;
}
//列表控件项目变化
void CMyMusicPlayerDlg::OnLvnItemchangedPlaylist(NMHDR *pNMHDR, LRESULT *pResult)
{LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);// TODO: 在此添加控件通知处理程序代码CString str;int nCounter;nCounter = m_myListCtrl.GetItemCount();str.Format(TEXT("播放列表(歌曲数目: %d)"),nCounter);GetDlgItem(IDC_GROUPPLAYLIST)->SetWindowText(str);*pResult = 0;
}

AboutDlg的头文件(打开关于对话框)

#pragma once
#include "afxcmn.h"// CAboutDlg 对话框class CAboutDlg : public CDialog
{DECLARE_DYNAMIC(CAboutDlg)public:CAboutDlg(CWnd* pParent = NULL);   // 标准构造函数virtual ~CAboutDlg();// 对话框数据enum { IDD = IDD_ABOUTBOX };protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()public:afx_msg void OnNMClickSyslink(NMHDR *pNMHDR, LRESULT *pResult);
};

AboutDlg的实现文件

// AboutDlg.cpp : 实现文件
//#include "stdafx.h"
#include "My Music Player.h"
#include "AboutDlg.h"
#include "afxdialogex.h"// CAboutDlg 对话框IMPLEMENT_DYNAMIC(CAboutDlg, CDialog)CAboutDlg::CAboutDlg(CWnd* pParent /*=NULL*/): CDialog(CAboutDlg::IDD, pParent)
{}CAboutDlg::~CAboutDlg()
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{CDialog::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)ON_NOTIFY(NM_CLICK, IDC_SYSLINK, &CAboutDlg::OnNMClickSyslink)
END_MESSAGE_MAP()// CAboutDlg 消息处理程序void CAboutDlg::OnNMClickSyslink(NMHDR *pNMHDR, LRESULT *pResult)
{// TODO: 在此添加控件通知处理程序代码 PNMLINK pNMLink = (PNMLINK) pNMHDR;  // 打开我的博客::ShellExecute(GetSafeHwnd(), _T("open"), pNMLink->item.szUrl, NULL, NULL, SW_SHOWNORMAL);*pResult = 0;
}

resource头文件(资源)

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by My Music Player.rc
//
#define IDM_ABOUTBOX                    0x0010
#define IDD_ABOUTBOX                    100
#define IDS_ABOUTBOX                    101
#define IDD_MYMUSICPLAYER_DIALOG        102
#define IDR_MENU1                       130
#define IDR_MAINFRAME                   130
#define IDR_ACCELERATOR1                134
#define IDI_ICON1                       135
#define IDR_CONTEXTMENU                 137
#define IDD_DIALOG1                     138
#define IDC_SLIDER1                     1000
#define IDC_SLIDERPOS                   1000
#define IDC_PLAYLIST                    1003
#define IDC_BTNOPEN                     1004
#define IDC_BUTTON2                     1005
#define IDC_BTNEXIT                     1005
#define IDC_BTNPAUSE                    1006
#define IDC_SLIDERVOL                   1007
#define IDC_BTNOPREVIOUS                1009
#define IDC_BTNPREVIOUS                 1009
#define IDC_BTNNEXT                     1010
#define IDC_BTNDELETE                   1011
#define IDC_BTNAHEAD                    1012
#define IDC_BTNBACK                     1013
#define IDC_BTNADD                      1014
#define IDC_BTNSTOP                     1015
#define IDC_CURPOS                      1016
#define IDC_TOTAL_LENGTH                1016
#define IDC_EDIT2                       1017
#define IDC_CURRENT_POS                 1017
#define IDC_EDIT3                       1018
#define IDC_EDITVOL                     1018
#define IDC_COMPLAYMODE                 1021
#define IDC_MFCLINK1                    1022
#define IDC_EDIT_SONGTITLE              1023
#define IDC_EDIT_ARTIST                 1024
#define IDC_EDIT_ALB                    1025
#define IDC_EDIT_ALBUM                  1025
#define IDC_EDIT_ARTIST2                1026
#define IDC_EDIT_YEAR                   1026
#define IDC_SYSLINK1                    1028
#define IDC_SYSLINK                     1028
#define IDC_PROGRESS1                   1029
#define IDC_EDIT1                       1030
#define IDC_EDIT_SONGCOUNTER            1030
#define IDC_EDIT_SONGBITRATE            1031
#define IDC_EDIT_GENRE                  1032
#define IDC_GROUPSONG                   1033
#define IDC_GROUPPLAYLIST               1033
#define ID_32771                        32771
#define ID_32772                        32772
#define IDM_FILE_OPEN                   32773
#define IDM_APP_EXIT                    32774
#define ID_32775                        32775
#define IDM_HELP_ABOUT                  32776
#define ID_32777                        32777
#define ID_Menu                         32778
#define ID_32779                        32779
#define ID_32780                        32780
#define ID_32781                        32781
#define IDM_CONTROL_PLAY                32782
#define IDM_CONTROL_PAUSE               32783
#define IDM_CONTROL_STOP                32784
#define IDM_CONTROL_AHEAD               32785
#define IDM_CONTROL_BACK                32786
#define ID_32787                        32787
#define ID_32788                        32788
#define IDM_CONTROL_PREVIOUS            32793
#define IDM_CONTROL_NEXT                32794
#define ID_32802                        32802
#define ID_32803                        32803
#define ID_32804                        32804
#define ID_32805                        32805
#define ID_MODE_SEQUENCE                32806
#define ID_MODE_RANDOM                  32807
#define ID_MODE_SINGLELOOP              32808
#define ID_MODE_SINGLEPLAY              32809
#define ID__32810                       32810
#define ID__32811                       32811
#define ID__32812                       32812
#define IDM_OPENFOLDER                  32813
#define IDM_DELETECURITEM               32814
#define ID__32815                       32815
#define ID__32816                       32816
#define ID__32817                       32817
#define ID__32818                       32818
#define IDM_PLAYFILE                    32819
#define IDM_GONEXT                      32820
#define IDM_                            32821
#define IDM_GOPREVIOUS                  32822
#define ID__ADDFILE                     32823
#define ID__DELETEITEM                  32824
#define IDM__ADDFILE                    32825
#define IDM__DELETEITEM                 32826
#define IDM__LOADFILE                   32827
#define IDM_DELETEITEM                  32828
#define IDM_LOADFILE                    32829
#define IDM_PAUSE                       32830
#define ID_Menu32831                    32831
#define IDM_PREVIOUS                    32832
#define ID_32833                        32833
#define IDM_NEXT                        32834
#define IDM_CONTEXTMENU_PLAYFILE        32835
#define IDM_CONTEXTMENU_PAUSE           32836
#define IDM_CONTEXTMENU_PREVIOUS        32837
#define IDM_CONTEXTMENU_NEXT            32838
#define IDM_CONTEXTMENU_LOADFILE        32839
#define IDM_CONTEXTMENU_DELETEITEM      32840
#define IDM_CONTEXTMENU_OPENFOLDER      32841
#define ID_32842                        32842
#define ID_32843                        32843
#define IDM_FILE_ADDFOLDER              32844// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        139
#define _APS_NEXT_COMMAND_VALUE         32847
#define _APS_NEXT_CONTROL_VALUE         1034
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

targetver 头文件


#pragma once// 以下宏定义要求的最低平台。要求的最低平台
// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
// 正常工作。// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
// 有关不同平台对应值的最新信息,请参考 MSDN。
#ifndef WINVER                          // 指定要求的最低平台是 Windows Vista。
#define WINVER 0x0600           // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。
#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif#ifndef _WIN32_WINDOWS          // 指定要求的最低平台是 Windows 98。
#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
#endif#ifndef _WIN32_IE                       // 指定要求的最低平台是 Internet Explorer 7.0。
#define _WIN32_IE 0x0700        // 将此值更改为相应的值,以适用于 IE 的其他版本。
#endif

完整项目请到此处下载:
http://download.csdn.net/detail/codemore/9423741

[更新]基于MFC对话框并使用MCI接口的音乐播放器相关推荐

  1. 树莓派云音乐c语言,基于树莓派的红外遥控版网易云音乐播放器

    基于树莓派的红外遥控版网易云音乐播放器.下面是遥控键盘示意图: CH- CH CH+ << >> || - + EQ 0 100+ 200+ 1 2 3 4 5 6 7 8 9 ...

  2. linux树莓派网易云音乐,基于树莓派的红外遥控版网易云音乐播放器

    基于树莓派的红外遥控版网易云音乐播放器.下面是遥控键盘示意图: CH- CH CH+ << >> || - + EQ 0 100+ 200+ 1 2 3 4 5 6 7 8 9 ...

  3. 基于C语言控制台程序的简易MP3音乐播放器

    这是我们小学期的第一个大作业,因感受颇深,特此写下这篇博客留作纪念. 内容:设计一个带有播放控制和音量调节功能的控制台音乐播放器,其中播放控制的子菜单能实现播放暂停切换.停止当前曲.播放上一曲和下一曲 ...

  4. 基于Basys2开发板的简易电子琴和音乐播放器设计

    背景:华中科技大学 电测综合实验 主要功能:Basys2开发板外接一个扬声器(或无源蜂鸣器也可)实现电子琴和音乐播放器的功能.其中由于开发板上只有4个按键,所以电子琴功能只做了4个音调,分别对应于4个 ...

  5. 基于Android studio有声听书系统 java音乐播放器系统

    1:注册登录:未注册用户首先进行账号注册,注册成功后进行登录,已注册用户直接输入账号密码进行登录,登录成功后进入主页面. 2:主页面:通过左右滑动可以实现对推荐界面.订阅界面.历史界面的切换,推荐界面 ...

  6. MFC学习笔记 — 看小白如何实现音乐播放器(USB-HID 声卡 wav播放)

    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX  作       者:文化人 XX  联系方式:(或进群:471144 ...

  7. 使用百度音乐盒API接口实现音乐播放器

    百度音乐盒提供了一个便捷的API可以拿来访问一些音乐资源,开发者通过访问指定格式的url可以拿到返回的数据,这个数据可以是json或者xml,这里面包含了歌曲的信息.完整的API各种访问格式是非常丰富 ...

  8. 基于android音乐播放器的设计

    本科毕业论文(设计)诚信声明 本人郑重声明:所呈交的毕业论文(设计),题目<---基于android音乐播放器的设计----------->是本人在指导教师的指导下,进行研究工作所取得的成 ...

  9. (附源码)springboot+基于微信小程序音乐播放器的设计与实现 毕业设计271156

    Springboot音乐播放小程序的设计与实现 摘 要 本文设计了一种基于微信小程序的音乐播放器,系统为人们提供了方便快捷.即用即搜的音乐搜索播放服务,包括音乐资讯.音乐库推荐.交流论坛.注册登录.最 ...

最新文章

  1. swift中字符串截取方法(substring)
  2. oracle in的用法_oracle 左连接、右连接、全外连接、内连接、以及 (+) 号用法
  3. 车牌检测识别--Towards End-to-End Car License Plates Detection and Recognition with Deep Neural Networks
  4. Hyper-V 性能加速之VMQ
  5. [答疑]-中断流程举例:在TEE侧时产生了FIQ,回到REE后为啥又产生了IRQ
  6. 使用 SAP UI5 CLI 命令行工具构建和运行 SAP UI5 应用
  7. leetcode —— 面试题29. 顺时针打印矩阵
  8. css如何让a标签,根据输入的内容长度调整宽度,宽度自适应,那位大仙帮帮忙...
  9. jquery 判断是否是浮点数_jquery或者js获取到元素宽高精确到小数
  10. 我是真的傻,她被超市安保罚了100元,我居然给她50元
  11. git命令行命令(1)
  12. python怎么放音乐_python怎么添加背景音乐
  13. 【原创】EXCEL公式经验(1)---如何拆解/拆分字符串为多列和多行,但是注意不要超过EXCEL字符串最长长度限制!
  14. layer.js之回调销毁对话框
  15. 刷新网页定位到特定位置
  16. 昆虫繁殖科学家在热带森林中发现了一种特殊的昆虫,这种昆虫的繁殖能力很强。 每对成虫过x个月产y对卵,每对卵要过两个月长成成虫。 假设每个成虫不死,第一个月只有一对成虫,且卵长成成虫后的第一个月不产卵(
  17. ARM内核全解析,从ARM7,ARM9到Cortex-A7,A8,A9,A12,A15到Cortex-A53,A57,A72
  18. 软考计算机英语词汇,软考计算机专业英语常用词汇(字母D-E)
  19. 【DASCTF2023】Misc mp3
  20. 室外管线lisp_AutoLISP语言在化工工艺室外管线设计中的应用

热门文章

  1. RowBounds实现分页
  2. 2019 互联网月饼大 PK!快看你家公司“上榜”没?
  3. python从多层循环嵌套中退出只能使用goto_goto语句只能用于退出多层循环.doc
  4. 微信小程序---获取标签节点的信息
  5. 我用大数据分析了一线城市1000多份岗位招聘需求,告诉你如何科学找工作
  6. h5ai php 函数 禁用,H5ai安装报错Warning : putenv() has been disabled for security的解决办法...
  7. IPy——Python中ip地址处理模块
  8. 瑞星发布“MSN骗子”病毒技术分析报告
  9. 2013复旦IT创新大会 达龙云桌面引领技术创新
  10. 友讯达PLM项目启动