vc多媒体播放器.docx
《vc多媒体播放器.docx》由会员分享,可在线阅读,更多相关《vc多媒体播放器.docx(27页珍藏版)》请在冰豆网上搜索。
vc多媒体播放器
多媒体播放器
1.基本功能描述
多媒体播放软件现在几乎成为每一台家用计算机的装机必备软件,比较流行的有迅雷播放器、WindowsMediaPlayer以及金山影霸等等,通过这些软件能够播放RM、RMVB、MP3、MPEG、DAT等多种格式的多媒体文件。
这些商业软件在功能上已经做的相当完备,也符合大多数普通消费者的的胃口,但很多人电脑里总是安装了多种播放器,因为不同的播放器有不同的特点,不是每个人都执著于用一款播放器,所以设计一款符合自己使用习惯的播放器是很有可行性的。
使用VC++6.0强大的MFC、AppWizard、ClassWizard和其中的多种控件可以很方便地建立各种应用程序。
同时想要实现更高级更复杂的功能,也可以借助ActiveX控件资源,用这些现有的控件资源,可以省去自己编程的复杂过程,从而实现更高级的功能。
本次课程设计要使用VC++6.0自带的一个ActiveX控件——WindowsMediaPlayer控件,建立自己的多媒体播放器。
此多媒体播放器具有打开文件、播放、暂停、全屏、音量调节、快进、快退等基本播放功能,并且可以播放:
*.mp3,*.wma,*.mdi,*.wav,*avi,*dat等格式的音频视频文件。
同时还具有自制的可隐藏的播放列表,并且可以在播放模式中选择顺序播放、随机播放、单曲循环三种方式随机即模式放器具有打开文件、播放、暂停、关闭,就是每个人都执著与XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。
同时,我也添加了保存列表的功能,当下一次打开时能保留上一次保存的播放列表,当然也添加了删除列表和删除当前的功能,更具人性化。
2.设计思路
根据各个按钮控件功能以及WindowsMediaPlayer控件的特点,首先要在头文件中将CWMPControl,CWMPSettings等类的对象的绑定以及定义,在后面的程序中需要调用这些类的成员函数。
对于打开文件按钮,需要调用通用文件对话框类,并利用listbox中的AddString函数把选中的文件添加到播放列表中,在MFC学习中有涉及。
对于一些基本的功能的实现,如播放、暂停、全屏、音量增大、音量减小、静音、快进、快退等功能,主要调用CWMPControl和CWMPPlayer类中的成员函数来进行实现。
对于播放列表,这次设计使用了SetWindowPos函数来改变一个子窗口弹出的尺寸和方向,并一些相关的函数实现了保存列表、删除列表、删除当前的功能。
对应播放列表,我还添加了播放模式选择的功能,提供了顺序播放、随即播放、单曲循环三种选择。
这当中运用的ontimer函数和settimer函数来控制播放模式。
参照以上的设计
思想,流程图如图1所示:
图1流程图
3.软件设计
3.1设计步骤
首先,打开MicrosoftVisualStudio6.0软件,新建一个工程如图2所示,以ZhuangWenfeng为工程名,然后将此工程定义为基于对话框的MFC应用程序如图3所示,点击完成就成功建立了一个基于对话框的工程。
图2工程建立
图3基于对话框的MFC程序
在建立好工程之后,首先是WindowsMediaPlayer控件的添加:
建立空白对话框之后,在对话框的空白处单击鼠标右键,选择InsertActiveXControl菜单项。
选择WindowsMediaPlayer控件,如图4所示。
加入控件后,此时该控件与该对话框并没有联系,需要对其进行变量的关联。
图4WindowsMediaPlayer控件的添加
添加完该控件之后可以发现,该控件与右边控件工具栏添加的控件的形式与功能完全不同,是一种更为高级的控件,将该控件名改为IDC_player,如图5所示。
图5WindowsMediaPlayer控件
虽然已已经添加了该控件,但是可以发现,改控件没有与工程中的对话框发生任何联系,所以需要对其进行变量的关联,所属类为ZhuangWenfeng类,变量类型为CWPPlayer4如图6所示。
图6关联变量
关联变量之后,才算是真正的添加完了该控件,可以发现在关联变量之后,控件工具栏多了WindowsMediaPlayer控件的选项,并且在SourceFiles中增加了17个类,相应的头文件也增加了17个,如图7所示。
图7添加控件后的变化
其中最主要的类为Cwmpplayer4,Cwmpcontrols,Cwmpmedia,Cwmpplaylist,Cwmpsettings五大类。
Cwmpplayer4类主要是关于对其他类的对象的调用以及基本的控件功能的实现,提供了与WindowsMediaPlayer控件进行交互的基本方法,其中部分成员函数还能够进一步获取得到其他相关类对象的实例;Cwmpcontrols类主要是对控件的更多的操作;Cwmpmedia类主要是对于媒体文件资源的一些操作;Cwmpplaylist类主要是关于播放列表的操作;Cwmpsettings类主要是对于媒体文件中的一些基本设置的操作。
对于该控件的添加以及内部函数的理解需要较多时间熟悉,添加完此关键控件之后,进行界面的设计。
3.2界面设计
首先是打开按钮,用于媒体文件的打开。
然后依次是,播放、暂停、全屏、快进、快退、音量增大、音量减小、静音、播放停止、退出等按钮。
对其进行变量的关联,以及ID的修改,修改结果如表1、表2所示:
表1控件ID以及关联变量
控件Caption
按钮ID
关联变量类型
关联变量名称
WMPlayer
IDC_player
CWMPlayer4
m_ZhuangWenfeng
表2控件ID以及对应响应函数
控件Caption
按钮ID
消息响应函数
打开
IDC_open
Onopen
播放
IDC_play
Onplay
暂停
IDC_pause
Onpause
全屏
IDC_fullscreen
Onfullscreen
播放列表
IDC_list
Onlist
列表框
IDC_LIST1
OnDblclkList1
快进
IDC_fastforward
Onfastforward
快退
IDC_fastreverse
Onfastreverse
+(音量增加)
IDC_addvol
Onaddvol
-(音量减小)
IDC_decvol
Ondecvol
静音
IDC_mute
Onmute
表2控件ID以及对应响应函数
控件Caption
按钮ID
消息响应函数
停止
IDC_stop
Onstop
保存列表
IDC_save
Onsave
删除列表
IDC_dellist
Ondellist
删除当前
IDC_dellistcur
Ondellistcur
退出
IDC_exit
Onexit
关于
IDC_about
Onabout
以上为有对应控件的对象的关联,除了有对应控件的,还需要有WindowsMediaPlayer控件所生成的17个类中的几个重要的类进行对象的定义,而可知,对于成员对象的定义和成员函数的声明都放在头文件中,此次设计共主要用到其中3个类,因为设计了一个退出提醒弹出框,所以也要对其定义,具体如表3所示:
表3其他类及对应对象
类名
对象名
类名
对象名
CWMPControls
m_Control
CString
m_PathName
CWMPSettings
m_Setting
Check
CCheck
除了对各个控件关联变量以及消息响应函数,还要对对话框类进行消息响应函数的关联,因为此次设计中添加了播放模式选择的功能,所以需要用到WM_TIMER消息响应函数以及SetTimer()和OnTimer()函数来实现这项功能,将对话框类进行该消息响应函数的关联并书写程序。
添加方法如图8所示。
图8添加WM_TIMER消息响应函数
最终得到各个空间分布后的界面如图9所示。
图9多媒体播放器界面
除了以上主对话框外,我还对ABOUTBOX进行了重新设计,也自制了一个Check对话框,其中ABOUTBOX如图10所示。
Check对话框是在用户点击退出按钮自动弹出的提醒窗口,主要用于防止用户误按关闭按钮导致程序关闭,有利于用户的使用,增强软件的友好性,如图11所示。
图10修改后的ABOUTBOX对话框图11提醒对话框
关于菜单的制作,首先,需要在ResourceView中加入资源Menu,后增加对应的菜单项以及菜单自己布局,下拉菜单则需要和按钮关联,其方法是将其ID和按钮的ID一样,菜单布局图12所示。
图12菜单栏
3.3关键功能的实现
对于各个函数的介绍,本文以关键代码以及注释的方式进行介绍,首先介绍主对话框中函数的实现以及说明:
(1)Onopen()。
打开函数
voidCZhuangWenfengDlg:
:
Onopen()
{
charszFileFilter[]=
"AllFile(*.*)|*.*|"
"AVIFile(*.avi)|*.avi|"
"Mp3File(*.mp3)|*.mp3|"
"MPEGFile(*.mpeg)|*.mpeg|"
"MediaFile(*.asf)|*.asf|"
"VideoFile(*.dat)|*.dat|"
"MPGAFile(*.mpga)|*.mpga|"
"WaveFile(*.wav)|*.wav|"
"MovieFile(*.mov)|*.mov|"
"MidFile(*.mid。
*,rmi)|*.mid。
*.rmi|"
"WmaFile(*.wma)|*.wma|"
"RmvbFile(*.rmvb)|*.rmvb|"
"AllFile(*.*)|*.*||"。
//可选的文件类型
CFileDialogdlg(true,NULL,NULL,OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR,szFileFilter)。
//OFN_ALLOWMULTISELECT是允许选择多个文件OFN_NOCHANGEDIR是不改变当前目录
POSITIONpos=dlg.GetStartPosition()。
if(dlg.DoModal()==IDOK)
{while(pos!
=NULL)
{
m_pathname=dlg.GetNextPathName(pos)。
//得到完整的文件名,包括目录名和扩展名
m_list.AddString(m_pathname)。
//增加到播放列表
}
}
}
其中难点在于对于陌生函数的理解,由于类数目较多,各类又有各自不同的成员函数,运用起来比较困难。
除了调用通用文件对话框和较为熟悉之外,其他的函数都是平时没有见过的。
播放列表中获取路径名是靠的添加主要依靠于GetNextPathName()函数,而m_list.AddString()函数是将工程名添加到播放列表中。
(2)Onlist()。
播放列表按钮函数和OnDblclkList1()。
播放列表函数:
voidCZhuangWenfengDlg:
:
Onlist()
{
flag=!
flag。
if(!
flag)
{
SetWindowPos(NULL,0,0,400,430,SWP_NOMOVE)。
//播放列表初始位置状态
}
else
{
SetWindowPos(NULL,0,0,590,430,SWP_NOMOVE)。
//点击按钮后播放列表位置状态
}
}
对于播放列表按钮,设计在那的功能是运行软件时播放器的播放列表是隐藏的,当点击按钮时,播放列表弹出。
为了实现这个功能,我将播放列表LIST1和播放列表按钮关联起来,关系设为控制。
为此,在程序定义了一个全局变量flag,将其设为一个标志,在初始化时定义窗口无相对位移,当点击按钮是,窗口位移,因此就实现了播放列表的隐藏和出现的功能。
而对于播放列表,则要求它实现双击播放功能,所以对列表控件增加一个消息映射,并选择双击消息函数响应,如图13所示。
在其中编程时也加入了执行响应函数SetTimer(),当点击函数时就开始创建计数器,以便实现播放模式的功能。
图13播放列表消息映射函数设置
具体程序如下所示:
voidCZhuangWenfengDlg:
:
OnDblclkList1()。
//双击播放函数
{
CStringstr
intindex=m_list.GetCurSel()。
//获取选择的行数
m_list.GetText(index,str)。
m_ZhuangWenfeng.SetUrl(str)。
//播放
m_pathname=str。
SetTimer(1,1000,NULL)。
//在点击播放时就创建计时器每隔1秒就自动执行下响应函数ontimer()
}
(3)Onplay();播放函数及其他多媒体播放控制按钮
voidCZhuangWenfengDlg:
:
Onplay()
{m_Control.play()。
//暂停后继续播放}
如同播放函数所示,其他控制播放状态的函数都可以直接调用添加的控件的类的对象调用实现,按钮响应函数和调用的函数关系如表4所示。
表4响应函数和调用函数关系
响应函数
调用函数
响应函数
调用函数
Onfastreverse()
m_Control.fastReverse()
Onfulscreen()
m_ZhuangWenfeng.SetFullScreen
(1)
Onfastforward()
m_Control.fastForward()
Onmute()
m_Setting.SetVolume(m_Setting.GetMute())。
Onstop()
m_Control.stop()
Onaddvol()
m_Setting.SetVolume(m_Setting.GetVolume()+10)
Onpause()
m_Control.pause()
Ondecvol()
m_Setting.SetVolume(m_Setting.GetVolume()-10
(4)播放列表状态
这款播放器设计了保存播放列表、删除播放列表、删除当前三种对播放列表状态的控制,其中函数主要调用了m_list类中的函数,在初始化是加入了一个读取上次保存的播放列表的指针函数,增加了播放列表的人性化。
具体函数如下:
voidCZhuangWenfengDlg:
:
Onsave()
{
CStdioFilefile。
file.Open(".\\list.txt",CFile:
:
modeCreate|CFile:
:
modeReadWrite|CFile:
:
typeText)。
//打开指定文件
for(inti=0。
ii++)
{
CStringstrtemp。
m_list.GetText(i,strtemp)。
strtemp+="\n"。
file.WriteString(strtemp)。
//保存播放列表
}
}
voidCZhuangWenfengDlg:
:
Ondellist()
{
CStdioFilefile。
m_list.ResetContent()。
//删除列表
file.Open(".\\list.txt",CFile:
:
modeCreate)。
}
voidCZhuangWenfengDlg:
:
Ondellistcur()
{
m_list.DeleteString(m_list.GetCurSel())。
//删除当前光标所选择的行
Onsave()。
//自动保存删除某一行后的播放列表
}
(5)播放模式
播放模式的选择需要用到WM_TIMER消息如图14所示,以及适时调用SetTimer()和OnTimer()函数。
初始化时默认设置为顺序播放,当双击播放时就开始创建计数器,每1秒就执行以下OnTimer函数。
而OnTimer函数就会获得播放状态,如果当前的播放完了,就检测单选按钮在哪,从而选择执行哪个程序。
如果是顺序播放,就自动执行下一工程;如果是随即播放,就在0-列表的文件数种产生一个随即数,然后执行;而如果是单曲循环,那么就一直执行当前文件。
图14M_TIMER消息添加
初始化程序如下:
m_list.SetCurSel(0)。
//选择第一行
m_list.GetText(m_list.GetCurSel(),m_pathname)。
((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(true)。
//默认播放模式为顺序播放
计数器函数OnTimer程序如下:
voidCZhuangWenfengDlg:
:
OnTimer(UINTnIDEvent)
{
intindex=m_ZhuangWenfeng.GetPlayState()。
//获取播放状态
if(index==1)//如果播放完成
{
if(((CButton*)GetDlgItem(IDC_RADIO1))->GetCheck())//如果是顺序播放
{
CStringstr。
intindex=m_list.GetCurSel()+1。
if(index>=m_list.GetCount())index=0。
//如果播放完最后一曲就自动播放第一首
m_list.GetText(index,str)。
m_ZhuangWenfeng.SetUrl(str)。
m_list.SetCurSel(index)。
//自动置光标
}//这样就实现了顺序播放
if(((CButton*)GetDlgItem(IDC_RADIO2))->GetCheck())//随机播放
{
srand(time(0))。
//目的在于每次都能产生不同的随机数序列
m_list.SetCurSel(rand()%m_list.GetCount())。
//随机选择0-m_list.GetCount()-1的任意一个数即随即选择m_list里的文件
m_list.GetText(m_list.GetCurSel(),m_pathname)。
m_ZhuangWenfeng.SetUrl(m_pathname)。
}
if(((CButton*)GetDlgItem(IDC_RADIO3))->GetCheck())//单曲循环
{
m_list.GetText(m_list.GetCurSel(),m_pathname)。
m_ZhuangWenfeng.SetUrl(m_pathname)。
}
}
CDialog:
:
OnTimer(nIDEvent)。
}
(6)Onabout()和Onexit()函数
因为调用自身编辑的对话框并且修改了工程中的ABOUTBOX资源,所以也要对其进行一定的修改。
首先,是对Onabout()函数的修改:
voidCZhuangWenfengDlg:
:
Onabout()
{
CAboutDlgaboutDlg。
aboutDlg.DoModal()。
}
其次,是对Onexit()函数的重载。
对于添加自制的对话框,制作方面较为简单不作介绍,在此要介绍的是自制对话框的添加以及对应类和头文件的添加。
在制作好对话框后,利用ClassWizard对该对话框进行类的关联,由于要调用该对话框,故要生成该对话框类自身的对象如图15所示。
图14生成自制对话框的新类
选择Createanewclass后需要输入一个类名CCheck,在输入确定之后会在工程的FileView中增加一个对应的Check.cpp和Check.h文件,之后便可以对该自制对话框类及其对象进行操作。
故调用该对话框的方法就是如下所示,在完成退出时还要删除计数器,释放内存。
voidCZhuangWenfengDlg:
:
Onexit()
{
CCheckCheck。
//生成CCheckBox类的对象CheckBox
if(Check.DoModal()==IDOK)//弹出对应的模态对话框
{
CDialog:
:
OnCancel()。
//点击确定则退出
KillTimer
(1)。
//退出程序时删除计数器
}
}
(7)菜单栏的添加制作以及功能
菜单栏的制作和添加不难,只要将其对应到对话框中即可,文中不再赘述。
各个菜单中的菜单项的功能,只要将对应的菜单项改成与对应功能的按钮控件的ID相同即可方便快速地实现。
4结论与心得体会
经过一周的面向对象程序课程设计,我学到了很多。
在这一周的实际动手学习中,我对VC++这门课程有了更深刻的认识,熟悉了用MFC创建基于对话框的应用程序,让我对于MFC编程的方法有了更新更全面的认识。
这次课程设计我做了多媒体视频播放器的设计,播放器主要对常用的多媒体格式的文件实现播放和控制。
接触题目开始做后,同学们手中的VC++6.0都没有ActiveMovie这一控件,只能选用WindowsMediaPlayer控件,而同时网上虽然有点关于WindowsMediaPlayer控件的资料,但按照网上的方法来添加控件并编程却根本无法编译。
所以对于该控件的添加方法和编程基本是在摸索实践中出来的。
C++作为我们的主要专业课程之一,开始觉得那些程序枯燥无味,但在这次课程设计后我发现在自己一点一滴的努力中对C++程序的兴趣也在增加。
可是在制作的过程中,编程总是运行错误成为了我非常大的困难之一,常常在悉心时久的编程后,运行出现错误,往往是越改越错,导致此段代码需要重新编写,但在前面代码的不断出错与修改的同时,我们也学到了更多,领悟到了上课所没有领会的知识点,所以在后面的编程中就越编越顺。
在程序设计时不要妄想一次就将整个程序设计好,反复修改,不断改进是程序设计的必经之路。
最终终于顺利完成了本人所想实现的大部分功能,掌握了一个全新的类的部分功能的使用,感觉受益匪浅,但也由于本人能力有限,才疏学浅,很多地方还有疏漏,没有实现一些想要实现的功能。
最后,我觉的做C++语言课程设计是十分有意义的,而且是十分有必要的,我们在课堂上掌握的只是专业课的理论知识,而这次课程设计为我们提供了很好的实践平台。
让我们增强了动手编程,自己调试,寻找错误的能力,为以后进一步的学好C++语言提供了基础。
5参考文献
[1]周长发.VisualC++.NET多媒体编程[M].电子工业出版社.2002
[2]揣锦华.面向对象程序设计与VC++实践[M].西安电子科技大学出版社.2005
[3]郑阿奇.VisualC++教程[M].北京:
机械工业出版社.2004
[4]SteveMack.流媒