繁星音乐播放器是本人第二次使用VC++编写的小应用。主要实现音乐的导入,删除和现实歌词,另外有一些特效

一、功能需求:

1.实现基本的音乐播放器的播放、暂停、继续、停止、上一首、下一首。

2.实现音乐播放器的音乐的快进、快退。

3.实现声音的增大和减小。

4.实现歌词的显示。

5.界面设计与美化。

二、总体设计

1.系统模块功能图

2.系统业务处理流程图

(1)、添加、删除、播放模式流程图

(2)、播放音乐流程图

三、程序详细设计

一、CPlayMusic类的编写

1、音乐播放器的播放、暂停、继续、停止、上一首、下一首

编写一个自定义类用来控制音乐的播放、暂停等功能实现。

类的定义:

class CPlayMusic

{

public:

CPlayMusic();

virtual ~CPlayMusic();

bool OpenFiles();                //打开CFileDialog,获取歌曲列表

CString Play();                    //播放(打开设备并初始化)

void Pause();                //暂停

void Continue();             //继续

void Stop();                 //停止

void Previous();             //上一首

void Next();                 //下一首

voidSpeedForward();         //上一首

voidSpeedBackward();        //下一首

void OnTimer();                          //循环播放

DWORD Getinfo(DWORDitem);   //获取媒体文件信息(播放时间,已播放时间等)

DWORD m_count;               //当前播放的媒体在列表中的位置

DWORDItemLength,ItemFrom,ItemTo,ItemNow;    //播放总时间,起始时间,结束时间,当前已播放时间

DWORD SetVolumn(DWORDvol);  //设置音量

bool GetLrc();

CString Lrc[100]; //歌词

CString MusicLrc; //当前歌词

int TotleLine;  //歌词总行数

int   iPlayed;                      //当前已播放的媒体文件数

bool PlayingFalg;                 //标志,是否正在播放

CStringstrFileName;   //增加的文件路径

};

初始化参数:

iPlayed=0;

ItemFrom=0;

PlayingFalg=false;

MusicLrc="";

(1)、添加音乐的文件打开:    bool OpenFiles();

//每次只能添加一首音乐

bool CPlayMusic::OpenFiles()

{

char szFileFilter[]="mp3文件(*.mp3)|*.mp3|"//设置文件播放格式

"wma文件(*.wma)|*.wma|"

"wav文件(*.wav)|*.wav|"

"所有文件(*.*)|*.*|";

CFileDialogfdlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,szFileFilter);

if(fdlg.DoModal()==IDOK)

{

strFileName=fdlg.GetPathName();

m_MusicList.Add(strFileName);

MusicNumber++;

iPlayed=MusicNumber-1;

Stop();

Play();

}

return TRUE;

}

(2)、播放音乐 CString Play()

CString CPlayMusic::Play()

{

PlayingFalg=TRUE;      //置播放标志

MCI_OPEN_PARMSmciopenparms;                                       //打开

MCI_PLAY_PARMSmciplayparms;                                        //播放

mciopenparms.lpstrElementName=m_MusicList.GetAt(iPlayed);    //播放路径

CurMusic=m_MusicList.GetAt(iPlayed);

//CurMusic 当前播放歌曲名,  m_FileList[]保存所有的歌曲路径

int n=CurMusic.ReverseFind('\\');//得到歌曲名在字符中的位置

CurMusic=CurMusic.Mid(n+1);    //只保存歌曲名

mciopenparms.lpstrDeviceType=NULL;                    //NULL为各种类型

mciSendCommand(0,MCI_OPEN,MCI_DEVTYPE_WAVEFORM_AUDIO,

(DWORD)(LPVOID)&mciopenparms);                    //向MCI设备发送命令消息

m_count=mciopenparms.wDeviceID;

mciplayparms.dwCallback=NULL;                         //窗口拥有者句柄

ItemLength=Getinfo(MCI_STATUS_LENGTH);   //得到播放长度

ItemTo=MCI_MAKE_HMS(MCI_HMS_HOUR(ItemLength),

MCI_HMS_MINUTE(ItemLength),

MCI_HMS_SECOND(ItemLength));        //根据长度计算出时、分、秒

mciplayparms.dwFrom=MCI_MAKE_HMS(0,0,0);             //播放起点

mciplayparms.dwTo=ItemTo;                             //播放终点

mciSendCommand(m_count,MCI_PLAY,MCI_TO|MCI_FROM,

(DWORD)(LPVOID)& mciplayparms);

IsPlaying=TRUE;//发送播放命令消息

returnm_FileList[iPlayed];

}

(3)、停止播放void  Stop()

void CPlayMusic::Stop()

{

PlayingFalg=false;                                                   //关闭正在播放标志

ItemFrom=MCI_MAKE_HMS(0,0,0);                             //播放位置归文件开头

mciSendCommand(m_count,MCI_CLOSE,0,NULL);         //发出关闭消息

}

(4)、暂停 void Pasue()

void CPlayMusic::Pause()

{

PlayingFalg=false;

mciSendCommand(m_count,MCI_PAUSE,0,NULL);         //发送暂停命令消息

}

(5)、继续 void Continue()

void CPlayMusic::Continue()

{

PlayingFalg=true;

mciSendCommand(m_count,MCI_RESUME,0,NULL);            //发送播放命令消息

}

(6)、上一首 void Previous()

void CPlayMusic::Previous()

{

iPlayed--;

if(iPlayed==-1) //若以后退到头,则指向最后一个,iPlayed是从0开始,iSelected从1开始

iPlayed=MusicNumber-1;  //MusicNumber 为歌曲总数,是一个全局变量

Stop();

Play();         //播放

}

(7)、下一首  void Next();

void CPlayMusic::Next()

{

iPlayed++;

if(iPlayed>=MusicNumber)

iPlayed=iPlayed%MusicNumber;

Stop();

Play();

}

2、音乐快进,快退

(1)、void SpeedForward()

void CPlayMusic::SpeedForward()

{

MCI_PLAY_PARMSmciplayparms;            //播放

ItemNow=Getinfo(MCI_STATUS_POSITION);   //获取当前播放位置

if(ItemNow+ItemLength/15< ItemTo)

mciplayparms.dwFrom=ItemNow + ItemLength/15; //改变播放起点

else

mciplayparms.dwFrom=ItemTo;

mciplayparms.dwTo=ItemTo;               //播放终点

mciSendCommand(m_count,MCI_PLAY,MCI_TO|MCI_FROM,(DWORD)(LPVOID)&mciplayparms);        //发送播放消息

}

(2)、快退 void SpeedBackward()

void CPlayMusic::SpeedBackward()

{

MCI_PLAY_PARMSmciplayparms;            //播放

ItemNow=Getinfo(MCI_STATUS_POSITION);   //获取当前播放位置

longpos=ItemNow-ItemLength/15;

if(pos>(long)ItemFrom)

mciplayparms.dwFrom=pos;            //改变播放起点

else

mciplayparms.dwFrom=ItemFrom;

mciplayparms.dwTo=ItemTo;               //播放终点

mciSendCommand(m_count,MCI_PLAY,MCI_TO|MCI_FROM,(DWORD)(LPVOID)&mciplayparms);        //发送播放消息

}

3、改变音量

在CPlayMusic.cpp中增加库

#include "Digitalv.h"//音量控制时会用到

DWORD CPlayMusic::SetVolumn(DWORD vol) //设置音量

{

MCI_DGV_SETAUDIO_PARMSSetVolumn;

SetVolumn.dwCallback=NULL;

SetVolumn.dwItem=MCI_DGV_SETAUDIO_VOLUME;

SetVolumn.dwValue=vol;

mciSendCommand(m_count,MCI_SETAUDIO,MCI_DGV_SETAUDIO_VALUE|MCI_DGV_SETAUDIO_ITEM,(DWORD)(LPVOID)&SetVolumn);

return 0;

}

4、得到歌词

bool CPlayMusic::GetLrc()

{

CFile file;

CStdioFile file1;

CString str;

str=m_FileList[iPlayed];

str.Replace("mp3","lrc");

int n=0;

int i=0;

int temp;

if(file1.Open(str,CFile::modeRead))

{

while(file1.ReadString(str))

{

n=str.Find(']',0);

temp=n;

while(str.Find(']',temp+1)!=-1)

temp=str.Find(']',temp+1);

if(temp!=-1)

n=temp;

str.Delete(0,n+1);

if(str!="")

{

Lrc[i]=str+"\r\n";

MusicLrc+=Lrc[i];

i++;

}

}

TotleLine=i;

return 1;

}

return 0;

}

整个CPlayMusic类编写基本完成。

二、音乐播放器的主要实现

1、为了使得对话框中的按钮控件好看,并有其他功能。重写CButton类

自定义MyButton类从Cbutton继承而来,增加功能有:用图片来替换按钮控件,鼠标移动在控件时自动改变控件的图片并显示按钮功能提示

(1)、实现鼠标移动到按钮处时改变按钮图片

添加变量

Public:

UINT m_nMouseOverID;  //鼠标在按钮上之后按钮的图片ID

UINT m_nNormalID;   //按钮之前的图片ID

CWnd* pWndParent;

HCURSOR m_hCursor;

BOOL m_bMouseOver; //判断鼠标是否在按钮上FALSE不在按钮上,TURE在按钮上

添加函数

Public:

void InitButtons(UINTnNormalID, UINT nMouseOverID,CString strTipText);//按钮初始化函数  三个参数(默认的按钮图片,鼠标经过时的图片,按钮功能提示语)

BOOL SetBitmap(UINT nNormalID,UINT nMouseOverID);

private:

void AdjustPosition();

void SetDefaultCursor();

另外添加DrawItem函数和WM_TIME、WM_SETCURSOR、WM_MOUSEMOVE消息响应函数

void CMyButton::InitButtons(UINT nNormalID, UINTnMouseOverID,CString strTipText)

{

m_nNormalID=nNormalID;

m_nMouseOverID=nMouseOverID;

m_hCursor=LoadCursor(NULL,MAKEINTRESOURCE(32649));

pWndParent=this->GetParent();

AdjustPosition();

m_bMouseOver=FALSE;

Invalidate();

}

void CMyButton::AdjustPosition()

{

CBitmap bitmap;

BITMAP m_Bitmap;

CRect rect;

bitmap.LoadBitmap(m_nNormalID);

bitmap.GetBitmap(&m_Bitmap);

GetWindowRect(&rect);//根据图象的大小调整按钮大小

pWndParent->ScreenToClient(&rect);

rect.right=rect.left+m_Bitmap.bmWidth;

rect.bottom=rect.top+m_Bitmap.bmHeight;

MoveWindow(&rect,TRUE);

}

void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

// TODO: Add your codeto draw the specified item

UINT nID;

CDC*pDC;

pDC=CDC::FromHandle(lpDrawItemStruct->hDC);

UINTnState=lpDrawItemStruct->itemState;

if(m_bMouseOver&&(!(nState & ODS_SELECTED)))

nID=m_nMouseOverID;

else

nID=m_nNormalID;

CBitmap bitmap;

BITMAP m_Bitmap;

CDC MemDC;

bitmap.LoadBitmap(nID);

MemDC.CreateCompatibleDC(pDC);

MemDC.SelectObject(&bitmap);

bitmap.GetBitmap(&m_Bitmap);

pDC->BitBlt(0,0,m_Bitmap.bmWidth,m_Bitmap.bmHeight,&MemDC,0,0,SRCCOPY);

bitmap.DeleteObject();

MemDC.DeleteDC();

}

BOOL CMyButton::SetBitmap(UINT nNormalID, UINT nMouseOverID)

{

m_nNormalID=nNormalID;

m_nMouseOverID=nMouseOverID;

AdjustPosition();

Invalidate();

return TRUE;

}

void CMyButton::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add yourmessage handler code here and/or call default

m_bMouseOver=TRUE;

SetTimer(1,100,NULL);

Invalidate();

CButton::OnMouseMove(nFlags,point);

}

void CMyButton::OnTimer(UINT nIDEvent)

{

// TODO: Add yourmessage handler code here and/or call default

if (nIDEvent==1)

{

POINT point;

GetCursorPos(&point);

ScreenToClient(&point);

CRect rect;

GetClientRect(&rect);

if(!rect.PtInRect(point)){

KillTimer(1);

m_bMouseOver=FALSE;

Invalidate();

}

}

CButton::OnTimer(nIDEvent);

}

BOOL CMyButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)//更换光标

{

// TODO: Add yourmessage handler code here and/or call default

if (m_hCursor)  //如果设置了光标,就使用新设置的光标

{

::SetCursor(m_hCursor);

return TRUE;

}

returnCButton::OnSetCursor(pWnd, nHitTest, message);

}

(2)、添加按钮功能提示

自定义                  BOOLSetBitmap(UINT nNormalID,UINT nMouseOverID);

CToolTipCtrl m_ToolTip;//提示按钮作用

添加系统函数:PreTranslateMessage(MSG*pMsg);和PreSubclassWindow()函数

在按钮初始化自定义函数InitButtons(UINTnNormalID, UINT nMouseOverID,CString strTipText)中添加代码:

m_ToolTip.UpdateTipText(strTipText,this,TIP_ID);//#define TIP_ID  1

为PreSubclassWindow()添加代码

void CMyButton::PreSubclassWindow()

{

// TODO: Add yourspecialized code here and/or call the base class

CRect rect;

GetClientRect(&rect);

m_ToolTip.Create(this);

m_ToolTip.SetDelayTime(100);

m_ToolTip.SetMaxTipWidth(200);

m_ToolTip.AddTool(this,"",rect,TIP_ID);

CButton::PreSubclassWindow();

}

为PreTranslateMessage()添加代码

BOOL CMyButton::PreTranslateMessage(MSG* pMsg)

{

// TODO: Add yourspecialized code here and/or call the base class

m_ToolTip.RelayEvent(pMsg);

returnCButton::PreTranslateMessage(pMsg);

}

以上CMyButton已基本完成

2、音乐播放器的真正实现部分

(1)、设计主对话框(在主对话框中主要有停止、上一首、播放(暂停,继续)、下一首, 窗口最小化、关闭、音乐播放器的设置、添加音乐、删除、播放模式)等按钮控件

另外这里还应用的改变对话框大小技术

动态改变对话大小

自定义函数::ChangeDlgSize()

void CMusicDlg::ChangeDlgSize()

{

CRect rect;

CString str;

if(pSize)

{

str = "";

rect = pFull;

}

else

{

str = "";

rect = pHalf;

CRect dlgRect;

GetWindowRect(dlgRect);

CRect desktopRect;

}

SetWindowPos(NULL,0,0,rect.Width(), rect.Height(), SWP_NOMOVE);//显示对话框

m_btnMenuList.SetWindowText(str);//设置按钮文本

pSize = !pSize;

}

在对话框初始化函数增加代码

GetWindowRect(&pFull);

pHalf = pFull;

//确定小尺寸对话框范围

CRect rect;

m_btnMenuList.GetWindowRect(&rect);//m_btnMenuList为添加控件的成员变量

pHalf.bottom =rect.bottom +5; //显示的对话框高度到按钮下方+5的距离处

pSize = false;//初始设置为小对话框

//调用改变尺寸函数

ChangeDlgSize();

初始化的对话框大小如图:

当点击歌曲,即变量成员是m_btnMenuList的控件,消息响应函数为:

void CMusicDlg::OnMenulist()

{

//TODO: Add your control notification handler code here

ChangeDlgSize();

}

对话框大小有如图:

重复点击会变小变大。

(2)、按钮控件的初始化;

为各个按钮控件添加相应的控件变量

修改控件的定义将CButton改为CMyButton;

设置按钮控件的位置

CRect rect1;

rect1.right=1000;  //按钮后边最大距离

rect1.bottom=1000;//按钮底边最大距离

rect1.left=215;

rect1.top=128;

m_btnMenuList.MoveWindow(&rect1,TRUE);

m_btnMenuList.InitButtons(IDB_MENU2,IDB_MENU,"歌曲列表");   //默认位图,鼠标经过时的位图,控件作用提示

//

rect1.left=240;

rect1.top=4;

m_btnClose.MoveWindow(&rect1,TRUE);

m_btnClose.InitButtons(IDB_CLOSE2,IDB_CLOSE,"关闭");

//

rect1.left=220;

rect1.top=4;

m_btnHide.InitButtons(IDB_HIDE2,IDB_HIDE,"");

//

rect1.left=80;

rect1.top=130;

m_btnNext.InitButtons(IDB_NEXT2,IDB_NEXT,"下一首");

//

rect1.left=53;

rect1.top=130;

m_btnPlay.MoveWindow(&rect1,TRUE);

m_btnPlay.InitButtons(IDB_PLAY2,IDB_PLAY,"播放");

//

rect1.left=28;

rect1.top=130;

m_btnPrev.InitButtons(IDB_PREV2,IDB_PREV,"上一首");

//

rect1.left=200;

rect1.top=4;

m_btnSet.InitButtons(IDB_SET2,IDB_SET,"设置");

//

rect1.left=5;

rect1.top=130;

m_btnStop.InitButtons(IDB_STOP2,IDB_STOP,"停止");

//增加

rect1.left=5;

rect1.top=477;

m_btnAdd.InitButtons(IDB_ADD2,IDB_ADD,"");

//删除

rect1.left=110;

rect1.top=480;

m_btnDel.InitButtons(IDB_DELETE2,IDB_DELETE,"");

//     播放模式

rect1.left=190;

rect1.top=480;

m_btnPlayMode.InitButtons(IDB_SHUNXU2,IDB_SHUNXU,"");

(3)、Silder properties控件初始化(音乐播放进度,音量控制)

A、声音控件

m_btnVolume.SetRange(0,1000);//滑块的移动范围

m_btnVolume.SetPos(500);//滑块中点

B、音乐播放进度

m_btnProgress.SetRange(0,100,TRUE);

m_btnProgress.SetTic(0);

m_btnProgress.SetTicFreq(10);

SetTimer(3,1000,NULL);          //播放进度条设置定时器

(4)、控件消息响应函数:

A、停止控件stop

voidCMusicDlg::OnStop()

{

//TODO: Add your control notification handler code here

IsPlaying= FALSE;

PlayMusic.Stop();//停止播放音乐

m_btnProgress.SetPos(0);  //设置进度条位置为0

CRectrect1;

rect1.right=1000;

rect1.bottom=1000;

rect1.left=53;

rect1.top=129;

m_btnPlay.MoveWindow(&rect1,TRUE);

m_btnPlay.InitButtons(IDB_PLAY2,IDB_PLAY,"");  //控件更改图片

IsPause=FALSE;

CurMusic="繁星音乐播放器   欢迎您";  //CurMusic用来在对话框中显示当前播放歌曲名;当无歌曲播放时显示“繁星音乐播放器  欢迎您”

}

B、播放控件(暂停,继续)

voidCMusicDlg::OnPlay()

{

//TODO: Add your control notification handler code here

CRectrect1;

rect1.right=1000;

rect1.bottom=1000;

rect1.left=53;

rect1.top=129;

m_btnPlay.MoveWindow(&rect1,TRUE);

if(MusicNumber==0)  //当无歌曲则返回

return ;

else{

if (IsPlaying)  //有歌曲正在播放点击按钮之后则暂停

{

IsPlaying=FALSE;

m_btnPlay.InitButtons(IDB_PLAY2,IDB_PLAY,"继续");  //这时控件的提示语应为继续

PlayMusic.Pause();  //暂停歌曲

MusicLrcDlg->KillTimer(1);

IsPause=TRUE;

}

else{ //如果没有播放则播放

IsPlaying=TRUE;

m_btnPlay.InitButtons(IDB_PASUE2,IDB_PASUE,"暂停");

if(IsPause)  //如果没有播放是暂停的

{PlayMusic.Continue();则继续播放

MusicLrcDlg->SetTimer(1,5000,NULL);

IsPause=FALSE;

}

Else  //如果没有播放并不是暂停的,则播放一首新的歌曲

{

PlayMusic.Play();

ShowMusicLrc();  //显示歌词

}

}

}

Invalidate();

}

C、上一首

voidCMusicDlg::OnPrev()

{

//TODO: Add your control notification handler code here

if(IsPlaying)

{  PlayMusic.Previous();

ShowMusicLrc();

}

UpdateData(FALSE);

}

D、下一首

voidCMusicDlg::OnNext()

{

//TODO: Add your control notification handler code here

if(IsPlaying)

{     PlayMusic.Next();

ShowMusicLrc();

}

UpdateData(FALSE);

}

E、改变音量控件(通过ClassVizard  添加声音控件的NM_CUSTOMDRAW消息响应函数)

voidCMusicDlg::OnCustomdrawVolum(NMHDR* pNMHDR, LRESULT* pResult)

{

//TODO: Add your control notification handler code here

UpdateData(true);//更新数据

PlayMusic.SetVolumn(m_btnVolume.GetPos());//当前滑块位置

UpdateData(FALSE);

*pResult= 0;

}

F、播放进度控件(通过ClassVizard 添加WM_HSCROLL消息响应函数)

voidCMusicDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

{

//TODO: Add your message handler code here and/or call default

if(IsPlaying)

{

int percent =m_btnProgress.GetPos();          //获取进度条比例

int ratio =m_ItemPosition*100/m_ItemLength;   //计算已播放的比例

while(percent>ratio)          //若滑块超前,则快进,直到播放比例与进度条指示相同

{

PlayMusic.SpeedForward();

ratio=PlayMusic.Getinfo(MCI_STATUS_POSITION)*100/PlayMusic.Getinfo(MCI_STATUS_LENGTH);   //得到曲目长度

};

while(percent<ratio)

{

PlayMusic.SpeedBackward();    //若滑块滞后,则快进,直到播放比例与进度条指示相同

ratio=PlayMusic.Getinfo(MCI_STATUS_POSITION)*100/PlayMusic.Getinfo(MCI_STATUS_LENGTH);           //得到曲目长度    DWORD w1 = m_Media.Getinfo(MCI_STATUS_LENGTH);           //得到曲目长度

};

}

CDialog::OnHScroll(nSBCode,nPos, pScrollBar);

}

另外在OnTimer函数中添加:

if(nIDEvent==3)

{

if(IsPlaying)

{

m_ItemLength   = PlayMusic.Getinfo(MCI_STATUS_LENGTH);       //得到曲目长度        DWORD w1 = m_Media.Getinfo(MCI_STATUS_LENGTH);           //得到曲目长度

m_ItemPosition= PlayMusic.Getinfo(MCI_STATUS_POSITION);    //得到曲目长度     DWORDw1 = m_Media.Getinfo(MCI_STATUS_LENGTH);           //得到曲目长度

intpercent = m_ItemPosition*100 / m_ItemLength;             //计算播放比例

m_btnProgress.SetPos(percent);                             //更新进度条位置

PlayMusic.OnTimer();

}

Invalidate(FALSE);

UpdateData(FALSE);

}

G、添加音乐控件消息响应函数(添加控件原本相有个添加文件和添加文件夹两种方式,这里由于添加音乐文件夹方式没有学会,这里只有添加文件)添加控件要有两种添加方式则需要新建个Menu

添加控件的消息响应函数:

void CMusicDlg::OnAdd()

{

//TODO: Add your control notification handler code here

//与Menu连接使用

CRectrect;

GetDlgItem(IDC_ADD)->GetWindowRect(&rect);//控件ID

CMenum_Menu;

m_Menu.LoadMenu(IDR_MENU_ADD);  //载入Menu,MenuID

m_Menu.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTBUTTON,

rect.left, rect.bottom,this,NULL);

}

添加文件消息响应函数:

voidCMusicDlg::OnAddFile()

{

//TODO: Add your command handler code here

Invalidate(FALSE);

PlayMusic.OpenFiles();  //打开增加文件对话框并将选择歌曲目录保存

CRectrect1;

rect1.right=1000;

rect1.bottom=1000;

rect1.left=53;

rect1.top=129;

m_btnPlay.MoveWindow(&rect1,TRUE);

m_btnPlay.InitButtons(IDB_PASUE2,IDB_PASUE,"");

UpdateData(FALSE);

intn;

//截取歌曲目录文件之后的音乐文件名

CStringstrFormat;

CString str =m_MusicList.GetAt(MusicNumber-1);        n=str.ReverseFind('\\');   str=str.Mid(n+1);

//将音乐文件名添加在list box控件中

if(MusicNumber<10)

strFormat.Format("0%d     %s",MusicNumber,str);

else

strFormat.Format("%d     %s",MusicNumber,str);

m_menulist.AddString(strFormat);  //m_menulist为list box的相关变量

if(MusicNumber!=0)

IsPlaying = TRUE;

m_menulist.SetCurSel(PlayMusic.iPlayed);//选中最后增加的歌曲

ShowMusicLrc();

UpdateData(FALSE);

}

H、删除控件

删除选中音乐

void CMusicDlg::OnDelSelect()

{

//TODO: Add your command handler code here

intn=m_menulist.GetCurSel();//得到list box中选中的歌曲

if(n<0)

return;

m_MusicList.RemoveAt(n,1);//m_MusicList是CStringArray类型的变量用来保存所有添加的歌曲,RemoveAt删除指定位置的歌曲

MusicNumber--;  //歌曲数减一

CStringstrGet;

CStringstrFileTitle;

CStringstrFormat;

intnPos;

for(inti=n;i<m_menulist.GetCount()-1;i++){

m_menulist.GetText(i+1,strGet);

nPos=strGet.Find("  ",0);

strFileTitle=strGet.Right(strGet.GetLength()-nPos);

if(i+1<10)

strFormat.Format("0%d%s",i+1,strFileTitle);

else

strFormat.Format("%d%s",i+1,strFileTitle);

m_menulist.InsertString(i,strFormat);

m_menulist.DeleteString(i+1);

}

m_menulist.DeleteString(i);//播放列表中同样删除选中歌曲

}

删除所有歌曲

void CMusicDlg::OnDelAll()

{

// TODO: Add yourcommand handler code here

MusicNumber=0;

m_MusicList.RemoveAll();

m_menulist.ResetContent();

}

I、List box控件消息响应(鼠标双击选中歌曲,让其播放)为list box 控件添加LBN_DBLCLK消息响应函数

voidCMusicDlg::OnDblclkMusiclist()  //双击list box中选择的一行 消息响应函数

{

// TODO: Add yourcontrol notification handler code here

intn=m_menulist.GetCurSel();  //得到鼠标点击处为行数

PlayMusic.Stop();

PlayMusic.iPlayed=n;

PlayMusic.Play();

m_btnProgress.SetPos(0);  //重新设置播放进度调的位置

SetTimer(3,1000,NULL);          //播放进度  设置定时器

ShowMusicLrc(); //显示歌词

UpdateData(FALSE);

}

3、为了使得音乐播发器更加完美,下面添加一些额外的代码

(1)、因为音乐播放器去掉了原本对话框中的Title bar导致对话框不能够拖到

这里使用鼠标左键按下拖动对话框,添加WM_LBUTTONDOWN消息响应函数

在鼠标左键按下中添加代码:

PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));//允许点击任意处拖动

(2)、设置对话框透明

SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,

GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);

HINSTANCE hInst = LoadLibrary("User32.DLL");

if(hInst)

{

typedef BOOL (WINAPI *MYFUNC)(HWND,COLORREF,BYTE,DWORD);

MYFUNC fun = NULL;

//取得SetLayeredWindowAttributes函数指针

fun=(MYFUNC)GetProcAddress(hInst,"SetLayeredWindowAttributes");

if(fun)fun(this->GetSafeHwnd(),0,100,2);  //更改100可改变对话框透明效果  数字越小,透明度越大。

FreeLibrary(hInst);

}

注:该方法不足,设置对话框的透明度同时,对话框中的字同样透明(变暗)。

(3)、由于本程序添加list box导致lisx box处的背景没有对话框的图片背景。解决方法

添加消息响应函数:WM_CTLCOLOR消息响应函数

添加代码:

HBRUSH hbrush= (HBRUSH)::GetStockObject(NULL_BRUSH);

pDC->SetTextColor(RGB(255,255,255));//设置字体颜色

pDC->SetBkMode(TRANSPARENT);

更改返回值为 return hbrush;

(4)、为了在对话框中显示当前播放歌曲名,不借助任何控件,即在对话框上写字

添加WM_PAINT消息响应函数;

CFont font;

LOGFONT logFont;

dc.GetCurrentFont()->GetLogFont(&logFont);

logFont.lfCharSet=134;

logFont.lfWidth=8;

logFont.lfHeight=18;

logFont.lfWeight=1000;

lstrcpy(logFont.lfFaceName,"楷体");

font.CreateFontIndirect(&logFont);

dc.SelectObject(&font);

dc.SetTextColor(RGB(119,190,232));//设置文本颜色

dc.SetBkMode(TRANSPARENT);//设置透明背景

dc.TextOut(WidthX,40,CurMusic);//字幕初始位置

四、程序测试与实现

1、添加音乐

添加后并自动播放:

2、删除选中音乐

     

3、迷你模式

4、透明对话框

五、程序优缺点、个人心得

优点:已经基本上实现了音乐播放器的基本功能,另外增加了透明对话框,迷你模式,显示播放时间,音量控制,快进,快退。显示歌曲名。

缺点:删除功能还不够理想,播放模式也没有怎么真正实现,播放时间不够精确,显示歌词方面还有待于实现。声音控件和播放进度控件可视化效果不够好。

增加文件夹没有实现,程序中设有的全局变量有点多。

个人心得:通过音乐播放器程序的编写,最初的问题时对MFC中的控件使用不够清楚导致重写了好几回,学会了如何重写一个类。在编写音乐播放器时参考了不少资料,总感觉编写有点乱。如何更改静态文本框的字体和颜色。两个或多个类之间的相会调用。还没有真正的弄懂MCI;

参考文献:

1、MSDN VC++ 6.0

2、深入浅出MFC第二版侯杰  华中科技大学出版社

3、Visual C++从入门到实践葛亮  清华大学出版社

4、Visual C++程序开发案例分析  杨国富 清华大学出版社

源代码: http://download.csdn.net/detail/fangxin205/7287719

VC++ 繁星音乐播放器相关推荐

  1. 100个vc小项目开发:二、一步一点设计音乐播放器 [I]

    100个vc小项目开发:二.一步一点设计音乐播放器 [源码解读] 文章作者: July 软件来源:开源 ================== 1.有不正之处,恳请指正. 2.本文贴出的是关键实现代码部 ...

  2. 【180609】超酷界面的VC++音乐播放器

    超酷界面的VC++音乐播放器,推荐给大家,源码爱好者在VC++6.0下顺利编译,它的界面非常 酷,编译中也没有发现用到第三方的界面控件,而且播放器的窗口还具有像千千静听一样的自动吸附功能,也就是拖动窗 ...

  3. 【190302】VC 仿千千静听音乐播放器源码源代码

    源码下载简介 超酷界面的VC++音乐播放器,推荐给大家, 在VC++6.0下顺利编译,它的界面非常 酷,编译中也没有发现用到第三方的界面控件,而且播放器的窗口还具有像千千静听一样的自动吸附功能,也就是 ...

  4. 一个VC写的音乐播放器

    以前,一直想写一个音乐播放器,但VC还没有完全学完,有些东西还练的很少,实力还不够,这是学完VC后,练习了很多东西,看了不少VC的知识,所以才决定写的. 这是2013年3月份写的,当时没有写在博客中, ...

  5. 单片AT89C2051 + SD卡 + 3310LCD = 音乐播放器

    http://www.amobbs.com/thread-4503884-1-1.html 这个小玩意,采用 ATMEL 的传统51MCU作主控制芯片,加上SD卡和显示屏,就可以作简单的音乐播放器了, ...

  6. C/C++简单音乐播放器系统

    C/C++简单音乐播放器系统 程序设计题 1:简单音乐播放器系统 出题人:吴敏 面向专业:计算机科学与技术 难度等级:4 1 问题描述 编写一个简单音乐播放器软件,实现歌单文件的浏览,点歌,加入收藏夹 ...

  7. SE Springer小组之《Spring音乐播放器》可行性研究报告一、二(转载)

         此文转载自组员小明处~~ 1 引言  1.1编写目的 <软件工程>课程,我们团队计划开发一个音乐播放器.本文档是基于网络上现有的音乐播放器的特点,团队计划实现的音乐播放器功能和团 ...

  8. 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)

    转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...

  9. 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)...

    转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...

最新文章

  1. 参加第一届宇宙 JavaScript 大会是怎样的体验
  2. 汇智清华,医道生机 | 第四届清华校友三创大赛医疗健康行业论坛圆满召开
  3. js如何通过变量调用函数,函数名在变量里面
  4. windows下安装virtual box(ubuntu)
  5. Linux常用命令总结之(五)alias
  6. HDU2159(完全背包)
  7. 多伦多大学密西莎加计算机科学,解析加国名校多伦多大学密西沙加校区
  8. jQuery(九):节点遍历
  9. 数据挖掘肿瘤预测_给你一个基因,利用数据挖掘能做什么?
  10. 【色空win7动漫美女诱惑主题】
  11. FTP、FTPS 与 SFTP 简介
  12. html中qq号码怎么写,根据QQ头像hash分析QQ号(html版)
  13. 小游戏正在毁灭微信群聊(文中有福利)
  14. 傻孩子菜单框架(转)
  15. 计算机网络实验报告哈工大_哈工大计算机网络实验报告之二
  16. 哈工大计算机考研复试指南
  17. 腾讯滑块JS破解/本地识别DLL
  18. 一周疫情对行业影响观察 | 对香港IPO冲击大于内地,纺织服装新增企业同比下滑超五成...
  19. xingtai - 学习九九乘法表和皇帝的米粒
  20. gcc/g++ 编译C/C++代码

热门文章

  1. 离散数学——第三章 关系
  2. 700MHz让中国移动成为最优秀的5G运营商,联通和电信难匹敌
  3. android自带的nsd发现服务器,Android NSD不会发现所有服务
  4. 从零开始单排学设计模式「代理模式」青铜 III
  5. PHPCMS手机访问,调用手机模板
  6. 如何使用Boxer在Mac上轻松玩经典DOS游戏
  7. access百度翻译 get_php百度翻译类
  8. C#实现的QQ登录器
  9. JS 找出字符串中最长回文子串
  10. 中国大学MOOC第10周编程题在线测试