基于MFC对话框的音乐播放器

最近完成一个基于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();
}
  • 15
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值