最近完成一个基于MFC对话框的音乐播发器程序,心中还是有不小的成就感,现在记录如下。
程序功能:
1.播放器支持MP3,WMA,WAV文件格式。
2.播放器具有上一曲,下一曲,快进5秒,后退5秒功能。
3.界面上有一个列表框控件显示播放列表,并支持双击播放。
4.程序支持拖放功能,并支持在任务栏上显示播放进度。
未完成:无法支持播放模式(顺序播放,单曲循环…)选择,希望大神能指点哈我!
程序界面如下:
所有实现文件:
/****************
*类名:CNiceSliderCtrl
*功能:支持滑块滑动功能,做到精确无误。
*文件名:NiceSlider.h
*/
#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_MSG
DECLARE_MESSAGE_MAP()
private:
bool SetThumb(const CPoint& pt);
void PostMessageToParent(const int nTBCode) const;
bool m_bDragging;
bool m_bDragChanged;
};
#endif // NiceSlider_h
实现文件:
/****************
*类名: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 up
dPos = (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 one
dCorrectionFactor = 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());
}
My Music PlayerDlg 头文件
/****************
*类名:CMyMusicPlayerDlg
*功能:函数定义及变量声明
*文件名:My Music PlayerDlg.h
*/
// My Music PlayerDlg.h : 头文件
//
#pragma once
#include "afxcmn.h"
#include "afxwin.h"
#include "NiceSlider.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()
CNiceSliderCtrl m_position; //显示播放进度控件,控件和变量关联
CListBox m_playlist; //显示播放列表控件,控件和变量关联
private:
DWORD dCurrentPos; //当前播放位置(毫秒为单位)
unsigned long m_dLength; //音频文件的长度(毫秒为单位)
BOOL isPause ; //暂停标记
WORD m_wDeviceID; //设备ID
CString strFileName; //当前播放文件名称
int CurrentSel; //播放列表中当前选中的位置
TCHAR strMciError[MAX_PATH]; //用于保存mci设备错误代码
int iSecond; //播放的秒数
int iMinute; //播放的分钟数
CNiceSliderCtrl sliderVol; //音量控制
public:
BOOL LoadFile(void); //打开文件函数
int PlayFile(CString szFileName); //播放文件函数
void PauseMe(void); //暂停函数
void GoPrevious(void); //上一曲函数
void GoNext(void); //下一曲函数
void GoAhead(void); //快进函数
void GoBack(void); //快退函数
void AddFile(void); //增加文件函数
void DeleteFile(void); //删除文件函数
void SetVolume(int Vol); //设置音量大小函数
void ConvertTime(int ); //转换时间函数
void UpdatePosition(void); //更新播放位置
//以下是按钮的映射函数
afx_msg void OnBnClickedBtnopen();
afx_msg void OnBnClickedBtnadd();
afx_msg void OnBnClickedBtnexit();
afx_msg void OnBnClickedBtnpause();
afx_msg void OnBnClickedBtnoprevious();
afx_msg void OnBnClickedBtnnext();
afx_msg void OnBnClickedBtndelete();
afx_msg void OnLbnDblclkPlaylist();
afx_msg void OnBnClickedBtnahead();
afx_msg void OnBnClickedBtnback();
afx_msg void OnTimer(UINT_PTR nIDEvent); //定时器:用于更新播放进度的位置
public:
//处理播放进度滑块位置变化
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
public:
//菜单的映射函数
afx_msg void OnFileOpen();
afx_msg void OnAppExit();
afx_msg void OnHelpAbout();
afx_msg void OnDropFiles(HDROP hDropInfo); //支持拖放文件
public:
afx_msg void OnControlPlay();
afx_msg void OnControlPause();
afx_msg void OnControlPrevious();
afx_msg void OnControlNext();
afx_msg void OnControlAhead();
afx_msg void OnControlBack();
private:
CMenu* pMainMenu;
CMenu* pSubMenu;
HACCEL hAccel; //键盘加速键
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
BOOL InitControls(void); //初始化控件
ITaskbarList3* pTaskbar; //用于支持任务栏显示播放进度
void TaskBarInit(void); //任务栏初始化
};
CMyMusicPlayerDlg的实现文件
/****************
*类名: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"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// #define WM_TASKBARBUTTONCREATED (WM_USER+0x103)
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CMyMusicPlayerDlg 对话框
CMyMusicPlayerDlg::CMyMusicPlayerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMyMusicPlayerDlg::IDD, pParent)
, dCurrentPos(0)
, m_dLength(0)
, isPause(false)
, strFileName(_T(""))
, CurrentSel(0)
, iSecond(0)
, iMinute(0)
, pMainMenu(NULL)
, pTaskbar(NULL)
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
}
void CMyMusicPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SLIDER1, m_position);
DDX_Control(pDX, IDC_PLAYLIST, m_playlist);
DDX_Control(pDX, IDC_SLIDERVOL, sliderVol);
}
BEGIN_MESSAGE_MAP(CMyMusicPlayerDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BTNOPEN, &CMyMusicPlayerDlg::OnBnClickedBtnopen)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BTNADD, &CMyMusicPlayerDlg::OnBnClickedBtnadd)
ON_BN_CLICKED(IDC_BTNEXIT, &CMyMusicPlayerDlg::OnBnClickedBtnexit)
ON_BN_CLICKED(IDC_BTNPAUSE, &CMyMusicPlayerDlg::OnBnClickedBtnpause)
ON_BN_CLICKED(IDC_BTNOPREVIOUS, &CMyMusicPlayerDlg::OnBnClickedBtnoprevious)
ON_BN_CLICKED(IDC_BTNNEXT, &CMyMusicPlayerDlg::OnBnClickedBtnnext)
ON_BN_CLICKED(IDC_BTNDELETE, &CMyMusicPlayerDlg::OnBnClickedBtndelete)
ON_WM_HSCROLL()
ON_COMMAND(IDM_FILE_OPEN, &CMyMusicPlayerDlg::OnFileOpen)
ON_COMMAND(IDM_APP_EXIT, &CMyMusicPlayerDlg::OnAppExit)
ON_LBN_DBLCLK(IDC_PLAYLIST, &CMyMusicPlayerDlg::OnLbnDblclkPlaylist)
ON_BN_CLICKED(IDC_BTNAHEAD, &CMyMusicPlayerDlg::OnBnClickedBtnahead)
ON_BN_CLICKED(IDC_BTNBACK, &CMyMusicPlayerDlg::OnBnClickedBtnback)
ON_COMMAND(IDM_HELP_ABOUT, &CMyMusicPlayerDlg::OnHelpAbout)
ON_WM_DROPFILES()
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)
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); // 设置小图标
InitControls(); //自定义初始化函数
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);
}
/************************************************************************/
/* 自定义的对话框中控件的初始化函数 */
/************************************************************************/
BOOL CMyMusicPlayerDlg::InitControls(void)
{
/************************************************************************/
/* 初始化每个控件 */
/************************************************************************/
m_position.SetPos(0); //初始化播放进度控件滑块值
m_playlist.ResetContent(); //重置播放列表
m_playlist.SetHorizontalExtent(500); //MFC ListBox 添加水平滚动条
sliderVol.SetRange(0,100); //设置音量控件的范围
sliderVol.SetPos(0); //初始化音量控件滑块值
//菜单的初始化
pMainMenu = new CMenu;
pMainMenu->LoadMenu(IDR_MENU1); // IDR_MENU1为菜单ID
pSubMenu = pMainMenu->GetSubMenu(1);
SetMenu(pMainMenu);
//加载键盘快捷键
hAccel = ::LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));
return TRUE;
}
/************************************************************************/
/* 各个功能函数的定义 */
/************************************************************************/
//打开文件
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
{
strFileName = FileDlg.GetPathName(); //得到打开文件的路径名
this->SetWindowText(strFileName + TEXT(" 状态:播放")); //设置对话框窗口标题
return TRUE;
}
}
//播放文件
int CMyMusicPlayerDlg::PlayFile(CString szFileName)
{
isPause = TRUE; //初始化
SetTimer(1,500,NULL); //初始化定时器,用于显示播放进度
//在打开新文件之前,先关闭之前的文件
mciSendCommand(m_wDeviceID,MCI_CLOSE, 0, NULL); //发送关闭命令
MCI_OPEN_PARMS mciOpen; //打开参数
MCI_PLAY_PARMS mciPlay; //播放参数
mciOpen.lpstrElementName = strFileName.GetBuffer(strFileName.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 1 ;
}
}
else
{
//保存设备ID
m_wDeviceID = mciOpen.wDeviceID ;
//声明文件信息的结构体
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 ;
//得到媒体的播放长度
//发送播放命令
mciSendCommand(m_wDeviceID,MCI_PLAY,0 ,(DWORD)(LPVOID)&mciPlay);
//初始化Taskbar
TaskBarInit();
}
//打开文件后初始化各个控件的数值
m_position.SetRange(0,m_dLength); //设置播放进度控件的范围
m_position.SetPos(0);
sliderVol.SetPos(50); //初始化音量控件的滑块位置
// 设置音量编辑框的数值
CString temp;
temp.Format(TEXT("%d"),50);
this->SetDlgItemText(IDC_EDITVOL,temp);
SetVolume(50); //设置音频的初始音量大小
ConvertTime(m_dLength); //将获得音频长度转换成 分和秒的格式
CString str;
str.Format(TEXT("%d:%d"),iMinute,iSecond);
SetDlgItemText(IDC_CURPOS,str);
UpdateData(TRUE);
}
void CMyMusicPlayerDlg::PauseMe()
{
if (isPause) //如果isPause为真
{
CString strShow;
strShow = strFileName + TEXT(" 状态:暂停");
this->SetWindowText(strShow);
MCI_GENERIC_PARMS mciPause; //mci暂停参数
//发送暂停命令
mciSendCommand(m_wDeviceID,MCI_PAUSE,0,(DWORD)(LPVOID)&mciPause);
SetDlgItemText(IDC_BTNPAUSE,TEXT("播放"));
//设置播放列表中菜单项 暂停 为选中
pSubMenu->CheckMenuItem(IDM_CONTROL_PAUSE,MF_CHECKED);
//设置播放列表中菜单项 播放 为不选中
pSubMenu->CheckMenuItem(IDM_CONTROL_PLAY,MF_UNCHECKED);
isPause = FALSE ; //toggle it
}
else
{
CString strShow;
strShow = strFileName + TEXT(" 状态:播放");
this->SetWindowText(strShow);
isPause = TRUE ;
MCI_PLAY_PARMS mciPlay;
mciSendCommand(m_wDeviceID,MCI_PLAY,0,(DWORD)(LPVOID)&mciPlay);
SetDlgItemText(IDC_BTNPAUSE,TEXT("暂停"));
pSubMenu->CheckMenuItem(IDM_CONTROL_PLAY,MF_CHECKED);
pSubMenu->CheckMenuItem(IDM_CONTROL_PAUSE,MF_UNCHECKED);
}
}
// 上一曲函数
void CMyMusicPlayerDlg::GoPrevious(void)
{
CurrentSel = m_playlist.GetCurSel(); //获得当前播放列表的选中项位置
if (CurrentSel == 0) //如果在第一个位置
{
CurrentSel = m_playlist.GetCount() - 1; //把选中项倒置到最后
}
else
{
CurrentSel--;
}
m_playlist.SetCurSel(CurrentSel); //设置选中位置
m_playlist.GetText(CurrentSel,strFileName); //得到选中位置的文本
m_playlist.SetFocus();
PlayFile(strFileName); //播放文件
}
void CMyMusicPlayerDlg::GoNext(void)
{
CurrentSel = m_playlist.GetCurSel();
if (CurrentSel == m_playlist.GetCount() - 1) //如果在最后一个位置
{
CurrentSel = 0; //返回到第一个位置
}
else
{
CurrentSel++;
}
m_playlist.SetCurSel(CurrentSel);//设置选中位置
m_playlist.GetText(CurrentSel,strFileName);//得到选中位置的文本
m_playlist.SetFocus();
PlayFile(strFileName);
}
//快进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 ; //设置播放的位置dwFrom为seek后
mciSendCommand (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); //设置滑块的新位置
}
//快退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);
}
//更新滑块的位置
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(), TBPF_INDETERMINATE);
pTaskbar->SetProgressValue(this->GetSafeHwnd(), dCurrentPos, m_dLength);
UpdatePosition();
if (m_position.GetPos() == m_dLength) //播放结束文件后跳至下个一文件
{
GoNext();
}
CDialog::OnTimer(nIDEvent);
}
//增加文件
void CMyMusicPlayerDlg::AddFile(void)
{
LoadFile();
m_playlist.InsertString(-1,strFileName);
}
//删除文件
void CMyMusicPlayerDlg::DeleteFile(void)
{
int getCur = m_playlist.GetCurSel();
m_playlist.DeleteString(getCur);
if (0 > getCur--)
{
AfxMessageBox(TEXT("列表都已经是空的啦!"), MB_OK | MB_ICONERROR);
}
m_playlist.SetCurSel(getCur);
}
//设置音量大小函数
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);
}
//转换时间
void CMyMusicPlayerDlg::ConvertTime(int time)
{
iSecond = time / 1000;
if (iSecond < 60)
{
iMinute = 0;
return ;
}
else {
iMinute = iSecond / 60;
iSecond = iSecond - iMinute * 60;
}
}
//更新播放进度
void CMyMusicPlayerDlg::UpdatePosition(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;
int sec = dCurrentPos / 1000; //获得文件的总秒数
int min = sec / 60; //将总秒数转换成 分钟
sec = sec - min * 60; //将总秒数转换成 秒数
CString str;
str.Format(TEXT("%d:%d"),min,sec);
SetDlgItemText(IDC_EDIT2,str);
}
//功能函数结束
//
//
//按钮逻辑
void CMyMusicPlayerDlg::OnBnClickedBtnopen()
{
if (LoadFile())
{
int getCur = m_playlist.InsertString(-1,strFileName);
m_playlist.SetCurSel(getCur);
pSubMenu->CheckMenuItem(IDM_CONTROL_PLAY, MF_CHECKED);
PlayFile(strFileName);
}
else
{
AfxMessageBox(TEXT("你没有打开文件"),MB_ICONINFORMATION,NULL);
}
}
void CMyMusicPlayerDlg::OnBnClickedBtnadd()
{
AddFile();
}
void CMyMusicPlayerDlg::OnBnClickedBtnexit()
{
mciSendCommand(m_wDeviceID,MCI_CLOSE,0,0);
this->SendMessage(WM_CLOSE,0,0);
}
void CMyMusicPlayerDlg::OnBnClickedBtnpause()
{
PauseMe();
Invalidate(TRUE);
}
void CMyMusicPlayerDlg::OnBnClickedBtnoprevious()
{
GoPrevious();
}
void CMyMusicPlayerDlg::OnBnClickedBtnnext()
{
GoNext();
}
void CMyMusicPlayerDlg::OnBnClickedBtnahead()
{
GoAhead();
}
void CMyMusicPlayerDlg::OnBnClickedBtnback()
{
// TODO: 在此添加控件通知处理程序代码
GoBack();
}
void CMyMusicPlayerDlg::OnBnClickedBtndelete()
{
DeleteFile();
}
//处理滑块拖动事件
//我花了好大功夫才弄好的
void CMyMusicPlayerDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
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);
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
/************************************************************************/
/* 菜单逻辑 */
/************************************************************************/
void CMyMusicPlayerDlg::OnFileOpen()
{
if (LoadFile())
{
int getCur = m_playlist.InsertString(-1,strFileName);
m_playlist.SetCurSel(getCur);
PlayFile(strFileName);
}
else
{
AfxMessageBox(TEXT("你没有打开文件"),MB_ICONINFORMATION,NULL);
}
}
void CMyMusicPlayerDlg::OnAppExit()
{
SendMessage(WM_CLOSE,0,0);
}
void CMyMusicPlayerDlg::OnHelpAbout()
{
CAboutDlg aboutdlg;
aboutdlg.DoModal();
}
void CMyMusicPlayerDlg::OnControlPlay()
{
isPause = TRUE ;
MCI_PLAY_PARMS mciPlay;
mciSendCommand(m_wDeviceID,MCI_PLAY,0,(DWORD)(LPVOID)&mciPlay);
this->SetWindowText(strFileName + TEXT(" 状态:播放"));
this->SetDlgItemText(IDC_BTNPAUSE,TEXT("暂停"));
pSubMenu->CheckMenuItem(IDM_CONTROL_PLAY,MF_CHECKED);
pSubMenu->CheckMenuItem(IDM_CONTROL_PAUSE,MF_UNCHECKED);
}
void CMyMusicPlayerDlg::OnControlPause()
{
// TODO: 在此添加命令处理程序代码
PauseMe();
this->SetDlgItemText(IDC_BTNPAUSE,TEXT("播放"));
pSubMenu->CheckMenuItem(IDM_CONTROL_PAUSE,MF_CHECKED);
pSubMenu->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::OnLbnDblclkPlaylist()
{
CListBox *Listbox = (CListBox*)GetDlgItem(IDC_PLAYLIST);
CString strText;
int iCurSel = Listbox->GetCurSel();
Listbox->GetText(iCurSel, strText);
strFileName = strText;
this->SetWindowText(strFileName + TEXT(" 状态:播放"));
PlayFile(strFileName );
}
/************************************************************************/
/* 让对话框支持拖放操作 */
/************************************************************************/
void CMyMusicPlayerDlg::OnDropFiles(HDROP hDropInfo)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
int newCurSel;
CString FileName[MAX_PATH];
int iFileCount = ::DragQueryFile(hDropInfo,0xffffffff,0,0);
int iRange = min(iFileCount,MAX_PATH);
for (int i = 0; i < iRange; i++)
{
DragQueryFile(hDropInfo,i,FileName[i].GetBuffer(512),512);
newCurSel = m_playlist.InsertString(-1,FileName[i]);
m_playlist.SetCurSel(newCurSel);
FileName[i].ReleaseBuffer();
}
CDialog::OnDropFiles(hDropInfo);
}
//支持键盘加速键
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)
{
return FALSE;
}
return CDialog::PreTranslateMessage(pMsg);
}
void CMyMusicPlayerDlg::TaskBarInit(void)
{
CoInitialize(0); //初始化COM组件,用于支持任务栏显示进度。
CoCreateInstance(CLSID_TaskbarList , NULL , CLSCTX_INPROC_SERVER , IID_PPV_ARGS (&pTaskbar));
pTaskbar->HrInit();
}