`
v_JULY_v
  • 浏览: 66962 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

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

阅读更多

100个vc小项目开发:二、一步一点设计音乐播放器[源码解读]

文章作者:July

软件来源:开源

==================

1.有不正之处,恳请指正。

2.本文贴出的是关键实现代码部分,只做粗略展示。

3.转载,请注明出处。谢谢。

---------

一、先画对话框,IDD_MYPLAYER_DIALOG,界面如图:

二、然后,对话框相关处理完成后,在CMyPlayerApp里头,编写如下代码:

设置几个全局变量:

CMyPlayerApp theApp;
CStringArray m_strPlayListArray;
int m_nPlayOrder[2000];
int m_nNowPlaying;
UINT m_nPlayMode;
HWND hAudio;
FILELIST fileList[10];
int nCurrentList;
CString strCurrentDir;

而后,编写InitInstance()的代码:

BOOL CMyPlayerApp::InitInstance()
{
AfxEnableControlContainer();
m_hMutex=CreateMutex(NULL,FALSE,"星空物语");

if (GetLastError()==ERROR_ALREADY_EXISTS )
{
HWND hwnd=FindWindow(NULL,"星空物语");

if(hwnd!=NULL);{
if(IsWindowVisible(hwnd))
return FALSE;
SendMessage(hwnd,MYWM_NOTIFYICON,NULL,(LPARAM)WM_LBUTTONDOWN);
}
return FALSE ;
}

hAudio=NULL;
TCHAR szCurDir[MAX_PATH];
GetCurrentDirectory(MAX_PATH,szCurDir);
strCurrentDir=szCurDir;
m_nPlayMode=MODE_RAND;

CMyPlayerDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{

}
else if (nResponse == IDCANCEL)
{

}

return FALSE;
}

三、// MyPlayerDlg.h : header file 头文件里头:

class CMyPlayerDlg : public CDialog
{
// Construction
public:
CString m_strLyricPath;
void DeleteNotifyIcon();
void CreateNotifyIcon();
BOOL fPlay;
void DestroyMenuDlg();
CMenuDlg* m_pMenuDlg;
int m_nVolume;
void WriteConfig();
BOOL ReadConfig();
BOOL IsFileExist(CString strFileName);
BOOL GetFileList(CString strLine,int nIndex);
void InitFileList();
int nRollTextCounter;
void CirculatePlay();
void DropFilesInPlayList(HDROP hDrop);
void DropFilesInMain(HDROP hDrop);
BOOL IsSupportFile(CString strFileName);
void GetDropFiles(HDROP hDrop);
void FormatTitle(CString strFile);
BOOL fPlaying;
UINT m_nTime;
void Play(int nIndex);
CString GetFileTitle(CString strFileName);
BOOL IsLyricDlgAttach();
BOOL IsPlayListAttach();
void MoveLyricWindow();
void MovePlayListWindow();
BOOL fInited;
void CreateLyric();
CLyricDlg* m_pLyricDlg;
void CreatePlayList();
CPlayListDlg* m_pPlayListDlg;
void InitSize();
void ExitPlayer();
void MoveSlide();
void InitText();
void CountTime();
CString strTime;
void InitRect();
CRect rectTitle;
CRect rectTime;
void DrawTime(CDC*pDC);
void RollText();
CString strOutText;
CString strTitle;
void DrawText(CDC*pDC);
void DrawMainPicture(CDC*pDC);
void InitButtons();
CMyPlayerDlg(CWnd* pParent = NULL);// standard constructor

// Dialog Data
//{{AFX_DATA(CMyPlayerDlg)
enum { IDD = IDD_MYPLAYER_DIALOG };
CSkinButtonm_btnShowMenu;
CSkinButtonm_btnLyric;
CVolumeButtonm_volume;
CSlideButtonm_slide;
CTransparentStaticm_stcMode;
CTransparentStaticm_stcPlay;
CSkinButtonm_btnStop;
CSkinButtonm_btnPrev;
CSkinButtonm_btnPLShow;
CSkinButtonm_btnPlay;
CSkinButtonm_btnOpen;
CSkinButtonm_btnNext;
CSkinButtonm_btnMin;
CSkinButtonm_btnHide;
CSkinButtonm_btnExit;
CButtonm_buttonOK;
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyPlayerDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV support
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL

// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CMyPlayerDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnBtnExit();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnStaticMode();
afx_msg void OnStaticPlay();
afx_msg void OnBtnVolume();
afx_msg void OnBtnSlide();
virtual void OnCancel();
virtual void OnOK();
afx_msg void OnBtnPlaylistShow();
afx_msg void OnMove(int x, int y);
afx_msg void OnBtnLyric();
afx_msg void OnBtnOpen();
afx_msg void OnBtnNext();
afx_msg void OnBtnPlay();
afx_msg void OnBtnPrev();
afx_msg void OnBtnStop();
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnBtnShowmenu();
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnMenuNext();
afx_msg void OnMenuOpen();
afx_msg void OnMenuPlay();
afx_msg void OnMenuPrev();
afx_msg void OnMenuRand();
afx_msg void OnMenuSeq();
afx_msg void OnMenuSingle();
afx_msg void OnMenuStop();
afx_msg void OnMenuVoldown();
afx_msg void OnMenuPause();
afx_msg void OnMenuVolslc();
afx_msg void OnMenuVolup();
afx_msg void OnAboutStar();
afx_msg void OnNotifyIcon(WPARAM wParam,LPARAM lParam);
afx_msg void OnBtnHide();
afx_msg void OnBtnMin();
afx_msg void OnSetLyricpath();
afx_msg void OnMenuOpenLyricpath();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

四、对应的// MyPlayerDlg.cpp : implementation file 实现文件里头:

void CMyPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyPlayerDlg)
DDX_Control(pDX, IDC_BTN_SHOWMENU, m_btnShowMenu);
DDX_Control(pDX, IDC_BTN_LYRIC, m_btnLyric);
DDX_Control(pDX, IDC_BTN_VOLUME, m_volume);
DDX_Control(pDX, IDC_BTN_SLIDE, m_slide);
DDX_Control(pDX, IDC_STATIC_MODE, m_stcMode);
DDX_Control(pDX, IDC_STATIC_PLAY, m_stcPlay);
DDX_Control(pDX, IDC_BTN_STOP, m_btnStop);
DDX_Control(pDX, IDC_BTN_PREV, m_btnPrev);
DDX_Control(pDX, IDC_BTN_PLAYLIST_SHOW, m_btnPLShow);
DDX_Control(pDX, IDC_BTN_PLAY, m_btnPlay);
DDX_Control(pDX, IDC_BTN_OPEN, m_btnOpen);
DDX_Control(pDX, IDC_BTN_NEXT, m_btnNext);
DDX_Control(pDX, IDC_BTN_MIN, m_btnMin);
DDX_Control(pDX, IDC_BTN_HIDE, m_btnHide);
DDX_Control(pDX, IDC_BTN_EXIT, m_btnExit);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMyPlayerDlg, CDialog)
//{{AFX_MSG_MAP(CMyPlayerDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_LBUTTONDOWN()
ON_BN_CLICKED(IDC_BTN_EXIT, OnBtnExit)
ON_WM_CREATE()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_STATIC_MODE, OnStaticMode)
ON_BN_CLICKED(IDC_STATIC_PLAY, OnStaticPlay)
ON_BN_CLICKED(IDC_BTN_VOLUME, OnBtnVolume)
ON_BN_CLICKED(IDC_BTN_SLIDE, OnBtnSlide)
ON_BN_CLICKED(IDC_BTN_PLAYLIST_SHOW, OnBtnPlaylistShow)
ON_WM_MOVE()
ON_BN_CLICKED(IDC_BTN_LYRIC, OnBtnLyric)
ON_BN_CLICKED(IDC_BTN_OPEN, OnBtnOpen)
ON_BN_CLICKED(IDC_BTN_NEXT, OnBtnNext)
ON_BN_CLICKED(IDC_BTN_PLAY, OnBtnPlay)
ON_BN_CLICKED(IDC_BTN_PREV, OnBtnPrev)
ON_BN_CLICKED(IDC_BTN_STOP, OnBtnStop)
ON_WM_RBUTTONDOWN()
ON_BN_CLICKED(IDC_BTN_SHOWMENU, OnBtnShowmenu)
ON_WM_KILLFOCUS()
ON_COMMAND(IDC_MENU_NEXT, OnMenuNext)
ON_COMMAND(IDC_MENU_OPEN, OnMenuOpen)
ON_COMMAND(IDC_MENU_PLAY, OnMenuPlay)
ON_COMMAND(IDC_MENU_PREV, OnMenuPrev)
ON_COMMAND(IDC_MENU_RAND, OnMenuRand)
ON_COMMAND(IDC_MENU_SEQ, OnMenuSeq)
ON_COMMAND(IDC_MENU_SINGLE, OnMenuSingle)
ON_COMMAND(IDC_MENU_STOP, OnMenuStop)
ON_COMMAND(IDC_MENU_VOLDOWN, OnMenuVoldown)
ON_COMMAND(IDC_MENU_PAUSE, OnMenuPause)
ON_COMMAND(IDC_MENU_VOLSLC, OnMenuVolslc)
ON_COMMAND(IDC_MENU_VOLUP, OnMenuVolup)
ON_COMMAND(IDC_ABOUT_STAR, OnAboutStar)
ON_MESSAGE(MYWM_NOTIFYICON,OnNotifyIcon)
ON_BN_CLICKED(IDC_BTN_HIDE, OnBtnHide)
ON_BN_CLICKED(IDC_BTN_MIN, OnBtnMin)
ON_COMMAND(IDC_SET_LYRICPATH, OnSetLyricpath)
ON_COMMAND(IDC_MENU_OPEN_LYRICPATH, OnMenuOpenLyricpath)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

五、以下是MyPlayerDlg对话框的初始化代码:

BOOL CMyPlayerDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);// Set big icon
SetIcon(m_hIcon, FALSE);// Set small icon

// TODO: Add extra initialization here
InitButtons();
InitRect();
InitText();
InitSize();
CreateLyric();
CreatePlayList();
m_pMenuDlg=NULL;
InitFileList();

strTitle=" 星空物语 ";
strTime="00:00";
m_nTime=0;
fInited=TRUE;
fPlaying=FALSE;
fPlay=TRUE;
nRollTextCounter=0;

SetWindowText("星空物语");

m_strLyricPath="";

if(ReadConfig()){
m_pPlayListDlg->OpenList(nCurrentList);
m_volume.SetPos(m_nVolume);
if(m_nPlayMode==MODE_SEQ)
OnStaticMode();
if(m_nPlayMode==MODE_SINGLE){
OnStaticMode();
OnStaticMode();
}
}else{
m_nPlayMode=MODE_RAND;
nCurrentList=0;
m_pPlayListDlg->OpenList(nCurrentList);
m_nVolume=8;
m_volume.SetPos(m_nVolume);
}

CreateNotifyIcon();
SetWindowPos(&CWnd::wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
m_pLyricDlg->SetPlayListWnd(m_pPlayListDlg);
return TRUE; // return TRUE unless you set the focus to a control
}

//字幕的画法

void CMyPlayerDlg::DrawText(CDC *pDC)
{
pDC->SetBkMode(TRANSPARENT);

CFont font,*pOldFont;
LOGFONT logFont;
pDC->GetCurrentFont()->GetLogFont(&logFont);

logFont.lfCharSet=134;
logFont.lfWidth=6;
logFont.lfWeight=10;
lstrcpy(logFont.lfFaceName,"华文彩云");
font.CreateFontIndirect(&logFont);

pOldFont=pDC->SelectObject(&font);
pDC->SetTextColor(RGB(255,255,0));
pDC->TextOut(21,48,"Love You Forever");

font.DeleteObject();

logFont.lfWidth=6;
logFont.lfHeight=12;
logFont.lfWeight=0;
lstrcpy(logFont.lfFaceName,"宋体");
font.CreateFontIndirect(&logFont);
pDC->SelectObject(&font);

pDC->SetTextColor(RGB(0,255,0));
pDC->TextOut(22,35,strOutText);
pDC->TextOut(22,66,"状态:");
pDC->TextOut(75,90,"☆For My Lover☆");
pDC->SetTextColor(RGB(0,150,0));
pDC->TextOut(60,103,"★星空物语 MADE BY July★");

font.DeleteObject();
pDC->SelectObject(pOldFont);
}

六、计时器部分,OnTimer、RollText、CountTime、MoveSlide等4个函数:

int CMyPlayerDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
SetTimer(1,1000,NULL);
fInited=FALSE;

DragAcceptFiles(TRUE);
return 0;
}

void CMyPlayerDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
RollText();
if(fPlaying){
CountTime();
MoveSlide();
CirculatePlay();
}

CDialog::OnTimer(nIDEvent);
}

void CMyPlayerDlg::RollText()
{
TCHAR ch;
strOutText="";
for(UINT i=0;i<16;){
ch=strTitle.GetAt(nRollTextCounter+i);
strOutText+=ch;
i++;
}
nRollTextCounter+=2;
if(nRollTextCounter>=strTitle.GetLength()-16)
nRollTextCounter=0;

InvalidateRect(&rectTitle,TRUE);
}

//计时

void CMyPlayerDlg::CountTime()
{
m_nTime=MCIWndGetPosition(hAudio)/MCIWndGetSpeed(hAudio);
int nMinute=m_nTime/60;
int nSecond=m_nTime%60;
if(nMinute<10){
if(nSecond<10)
strTime.Format("0%d:0%d",nMinute,nSecond);
else
strTime.Format("0%d:%d",nMinute,nSecond);
}else{
if(nSecond<10)
strTime.Format("%d:0%d",nMinute,nSecond);
else
strTime.Format("%d:%d",nMinute,nSecond);
}
InvalidateRect(&rectTime,TRUE);
}

//滚动条设置

void CMyPlayerDlg::MoveSlide()
{
if(hAudio!=NULL)
m_slide.SetSlidePos(MCIWndGetPosition(hAudio));
}

七、关键的播放代码,Play

void CMyPlayerDlg::Play(int nIndex)
{
if(nIndex>=m_strPlayListArray.GetSize())
return;
CString strFileName=m_strPlayListArray.GetAt(nIndex);
if(!IsFileExist(strFileName)){
m_pPlayListDlg->m_playlist.DeleteString(nIndex);
m_strPlayListArray.RemoveAt(nIndex,1);
return;
}
if(hAudio!=NULL){
MCIWndDestroy(hAudio);
hAudio=NULL;
}
try{
hAudio=MCIWndCreate(GetSafeHwnd(),AfxGetInstanceHandle(),
WS_CHILD|MCIWNDF_NOMENU,strFileName);
}catch(...)
{
if(nIndex>=0){
m_pPlayListDlg->m_playlist.DeleteString(nIndex);
m_strPlayListArray.RemoveAt(nIndex,1);
}
return;
}
if(hAudio!=NULL){
MCIWndPlay(hAudio);
if(!m_strLyricPath.IsEmpty()){
if(!m_pLyricDlg->OpenLyric(m_strLyricPath,nIndex))
m_pLyricDlg->OpenLyric(nIndex);
}else
m_pLyricDlg->OpenLyric(nIndex);

strTitle=GetFileTitle(strFileName);
FormatTitle(strTitle);
nRollTextCounter=0;
m_nTime=0;
fPlaying=TRUE;
m_slide.SetRange(0,MCIWndGetLength(hAudio));
m_slide.SetSlidePos(0);
m_pPlayListDlg->m_playlist.SetCurSel(nIndex);

int nSetVol=63*m_nVolume;
if(nSetVol>1000)
nSetVol=1000;
MCIWndSetVolume(hAudio,nSetVol);
}
}

void CMyPlayerDlg::OnBtnPlay()
{
// TODO: Add your control notification handler code here
int n=m_pPlayListDlg->m_playlist.GetCurSel();
if(n<0){
if(m_strPlayListArray.GetSize()>0){
Play(m_nPlayOrder[0]);
m_nNowPlaying=0;
}
return;
}

Play(n);

if(m_nPlayMode==MODE_RAND){
for(int i=0;i<m_strPlayListArray.GetSize();i++){
if(m_nPlayOrder[i]==n){
m_nNowPlaying=i;
break;
}
}
}else{
m_nNowPlaying=n;
}
}

八、打开文件

void CMyPlayerDlg::OnBtnOpen()
{
// TODO: Add your control notification handler code here
CString strFilter="所有支持文件(*.mp3,*.wav,*.wma)|*.mp3;*.wav;*.wma||";
CFileDialog fdlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,strFilter);
if(fdlg.DoModal()==IDOK){
CString strFileName=fdlg.GetPathName();

m_strPlayListArray.RemoveAll();
m_strPlayListArray.Add(strFileName);
CString strList,strFile;
strFile=GetFileTitle(strFileName);
strList.Format("01 %s",strFile);
m_pPlayListDlg->m_playlist.ResetContent();
m_pPlayListDlg->m_playlist.AddString(strList);

Play(0);
}
}

九、获取文件名

CString CMyPlayerDlg::GetFileTitle(CString strFileName)
{
CString str;

int nPos=-1;
int nOldPos=-1;
while((nPos=strFileName.Find("\\",nPos+1))>0)
nOldPos=nPos;
str=strFileName.Right(strFileName.GetLength()-nOldPos-1);
strFileName=str.Left(str.GetLength()-4);

return strFileName;
}

十、停止播放

void CMyPlayerDlg::OnBtnStop()
{
// TODO: Add your control notification handler code here
if(hAudio!=NULL){
MCIWndStop(hAudio);
m_nTime=0;
fPlaying=FALSE;
strTime="00:00";
m_slide.SetSlidePos(0);
InvalidateRect(&rectTime,TRUE);
}
}

//日后做详细解剖。待续。

July、二零一零年十二月二十四日。祝各位,平安夜快乐。:D。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics