【MFC】基于windows media player的音乐播放器

时间:2021-04-24 05:03:20

 

如图所示,目前程序能完成添加单曲音乐,音量控制,播放控制,只是播放进度条在定期滑动时会引起音乐间断,初步猜测是线程问题。

//2011.10.21

经过测试,并非是线程问题,而是程序响应了滑动条OnNMCustomdrawProgress消息,并在此消息中又调整了音乐播放的位置,因此会出现播放反复现象。不过这个错误使得今天学习了MFC多线程编程。【MFC】基于windows media player的音乐播放器

//解决办法是在OnNMReleasedcaptureProgress而不是OnNMCustomdrawProgress中响应进度条拖动消息。

在定时器中定时更新进度条位置。

同时重写PreTranslateMessage消息,在进度条被选中且鼠标左键按下的消息中,killtimer,然后再在鼠标左键弹起的消息响应中,settimer

 

本程序使用的有CButtonST类,windows media player activeX插件,以及一个实现滑动条透明的MySliderControl类。

 

步骤:

以下为windows media player插件使用方法(转载)

 

/*

Windows media player作为MS的官方组件,MSDN上有着比较详细的英文说明,但是该说明却并不是那么让人一目了然。该文就如何操作该组件的几个主要接口以及一些基本功能的实现给与详尽而明白的说明,为使该文尽量简单易懂,本文给出了用windows media player控件编写一个简单播放器的基本步骤。

首先,创建一个对话框,然后在资源管理器中右击对话框,选择插入Active控件”—〉选择windows media player—〉将控件拉到适合大小〉右击player控件〉选择添加变量(m_avPlayer)。此时添加的变量在VS2003中不在时IWMPPlay4了,而是COcx//COcx1.h

右击类视图/解决方案〉添加类〉选择“Active中的MFC”—〉选择windows media player<1.0>à选择相应的接口(IWMPMedia IWMPSettings IWMPControls IWMPPlaylist等等)生成类。为图方便,我将所有接口都生成了相应的类。
为了说明方便,我在对话框中放了几个按钮,分别是:打开,播放,暂停,停止,添加。并在对话框右边添加了一个clistctrl又来显示播放列表。
然后在对话框头文件中添加了以下变量:

CWMPControls m_control;CWMPSettings m_set;
CWMPPlaylist m_playlist;
CWMPMedia m_media;
COcx1 m_avPlayer;

CListCtrl m_listCtrl;



一切准备工作就绪,下面就涉及到具体的编程问题了。
media player
的主要功能有:播放控制,屏幕显示,播放列表,播放列表集,播放信息显示。

l 其中播放控制又有:打开,开始,暂停,停止,快速播放,倒退等等。
1.
打开:当选择一个文件打开是,可以直接使用 m_avPlayer.put_URL(fileName)
为打开按钮添加消息响应函数,在函数中添加如下代码:
char szFileFilter[]="Mp3 File(*.mp3)|*.mp3|"
"MPEG File(*.mpeg)|*.mpeg|"
"Media File(*.asf)|*.asf|"
"Video File(*.dat)|*.dat|"
"MPGA File(*.mpga)|*.mpga|"
"Wave File(*.wav)|*.wav|"
"AVI File(*.avi)|*.avi|"
"Movie File(*.mov)|*.mov|"
"Mid File(*.mid;*,rmi)|*.mid;*.rmi|"
"Wma File(*.wma)|*.wma|"
"All File(*.*)|*.*||";
CFileDialog fileDialog( TRUE,NULL,NULL,NULL,szFileFilter,this);
if (fileDialog.DoModal() == IDOK)
{
CString fileName=fileDialog.GetPathName();
m_avPlayer.put_URL(fileName);
}


这样当选择一个播放文件后, media player 就会自动播放该文件了。
2.
开始:为了实现播放控制,在 OnInitDialog ()中添加代码:
m_control = static_cast<CWMPControls>(m_avPlayer.get_controls());
然后为开始按钮添加消息响应函数,并在函数中添加代码 :
m_control.play();
3.
暂停: m_control.pause();
4.
停止: m_control.stop();
5.
其他如倒退,快速播放, MSDN 上有相应的函数,读者可依次自行解决。
到此,一个带有简单播放控制的播放器就完成。

l 下面来实现播放列表。为实现播放列表控制,首先在 OnInitDialog ()中添加代码:
//创建一个播放列表m_playlist = static_cast<CWMPPlaylist>(m_avPlayer.get_currentPlaylist());
然后将打开按钮的消息响应函数改为:
char szFileFilter[]=
"Mp3 File(*.mp3)|*.mp3|"
"MPEG File(*.mpeg)|*.mpeg|"
"Media File(*.asf)|*.asf|"
"Video File(*.dat)|*.dat|"
"MPGA File(*.mpga)|*.mpga|"
"Wave File(*.wav)|*.wav|"
"AVI File(*.avi)|*.avi|"
"Movie File(*.mov)|*.mov|"
"Mid File(*.mid;*,rmi)|*.mid;*.rmi|"
"Wma File(*.wma)|*.wma|"
"All File(*.*)|*.*||";
CFileDialog fileDialog( TRUE,NULL,NULL,NULL,szFileFilter,this);
if (fileDialog.DoModal() == IDOK)
{
CString fileName=fileDialog.GetPathName();
//创建一个媒体
m_media = static_cast<CWMPMedia>(m_avPlayer.newMedia(fileName));
//将媒体添加到播放列表
m_playlist.appendItem(m_media);
//将列表添加到当前列表,以便实现自动播放
m_avPlayer.put_currentPlaylist(m_playlist);

m_set = (CWMPSettings)m_avPlayer.get_settings();
//参数true设置自动播放,false不设置自动播放
m_set.put_autoStart(true);
//将媒体的名字添加到列表控件
m_listCtrl.InsertItem(0, m_media.get_name());
}



l 接着是屏幕显示控制
m_avPlayer.put_fullScreen(true/false);

l 使用播放列表自动播放文件,第一步 : 需要在播放列表中添加媒体 ; 第二步:将列表设置为当前播放列表;第三步:将播放设置为自动播放。
函数如下:
//创建一个播放列表m_playlist = static_cast<CWMPPlaylist>(m_avPlayer.get_currentPlaylist());
然后将打开按钮的消息响应函数改为:
char szFileFilter[]=
"Mp3 File(*.mp3)|*.mp3|"
"MPEG File(*.mpeg)|*.mpeg|"
"Media File(*.asf)|*.asf|"
"Video File(*.dat)|*.dat|"
"MPGA File(*.mpga)|*.mpga|"
"Wave File(*.wav)|*.wav|"
"AVI File(*.avi)|*.avi|"
"Movie File(*.mov)|*.mov|"
"Mid File(*.mid;*,rmi)|*.mid;*.rmi|"
"Wma File(*.wma)|*.wma|"
"All File(*.*)|*.*||";
CFileDialog fileDialog( TRUE,NULL,NULL,NULL,szFileFilter,this);
if (fileDialog.DoModal() == IDOK)
{
CString fileName=fileDialog.GetPathName();
//创建一个媒体
m_media = static_cast<CWMPMedia>(m_avPlayer.newMedia(fileName));
//将媒体添加到播放列表
m_playlist.appendItem(m_media);
//将列表添加到当前列表,以便实现自动播放
m_avPlayer.put_currentPlaylist(m_playlist);

m_set = (CWMPSettings)m_avPlayer.get_settings();
//参数true设置自动播放,false不设置自动播放
m_set.put_autoStart(true);
//将媒体的名字添加到列表控件
m_listCtrl.InsertItem(0, m_media.get_name());
}


l 播放信息的显示
可以通过 CWMPMedia 类获取相关的媒体信息。
获取播放文件名: media.get_name()

l 其他 , 如鼠标,接盘事件响应,可添加相应的消息响应函数
要注意的是,在添加如鼠标一类的消息时,消息函数有个参数如 nButton ,它的值为 1 时是单击鼠标左键, 2 为单击鼠标右键消息, 4 为单击鼠标中键。等等。

*/

 

以下为设置对话框背景方法:(转载)

/*

1 定义一个CBitmapm_Bitmap。并在OnInitDialog()LoadBitmap();

m_Bitmap.LoadBitmap(IDB_BITMAP_BACKGROUND);

2在建立类向导的class info中选择Windows即可找到消息响应函数,函数在OnEraseBkgnd(CDC*pDC)消息中处理背景刷新问题。Onpain()级别较低,会出现相应不及时的问题。

BOOL CLiteFindDlg::OnEraseBkgnd(CDC* pDC)
{
CDialog::OnEraseBkgnd(pDC);
if(!m_Bitmap.m_hObject)
return true;
CRect rect;
GetClientRect(&rect);
CDC dc;
dc.CreateCompatibleDC(pDC);
CBitmap* pOldBitmap = dc.SelectObject(&m_Bitmap);
int bmw, bmh ;
BITMAP bmap;
m_Bitmap.GetBitmap(&bmap);
bmw = bmap.bmWidth;
bmh = bmap.bmHeight;
int xo=0, yo=0;


////////此处贴图采用拉伸strentch//////////

pDC->StretchBlt(xo, yo, rect.Width(),rect.Height(), &dc,0, 0,bmw,bmh, SRCCOPY);/////////////////////////////////////////dc.SelectObject(pOldBitmap);return true;}*/ 以下为设置除button按钮,slider control 控件外其他控件透明的方法/*HBRUSH XXXX::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor){HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: 在此更改DC 的任何属性if (nCtlColor==CTLCOLOR_SCROLLBAR){pDC->SetTextColor(RGB(0,255,0));return (HBRUSH)m_brush.GetSafeHandle();}switch(pWnd->GetDlgCtrlID()){default:pDC->SetBkMode(TRANSPARENT);return (HBRUSH)GetStockObject(NULL_BRUSH);break;} // TODO: 如果默认的不是所需画笔,则返回另一个画笔return hbr;}