admin管理员组

文章数量:1531792

2024年4月23日发(作者:)

基于MFC运用windows media player控件实现的多媒体播放器

设计平台

PC(windows 7 x64),Visual C++ 6.0

设计框图

打开MediaPlayer

MediaPlayer初始化

打开文件

列表

关于

播放

顺序播放

导入/出 选中项上/下移动 删除选中/所有项

循环模式

播放模式

暂停 音量 快进退 上下曲

停止

随机播放

退出

静音

一.工程创建

本程序基于MFC的对话框模式,起名为MediaPlayer。

二. 添加Windows Media Player 控件

在对话框的空白处点击右键选择“Insert ActiveX control”,在弹出的对话框中找到

Windows Media Player。(因为Win7系统中没有ActiveMovieControl控件所以就用以

上控件代替了。)

2 / 24

三.为Windows Media Player 控件设置变量

在已经添加好的控件上单击右键选择“ClassWizard”,在弹出的窗口中切换到

“Member Variables”一栏,找到刚刚添加的控件的ID,选中它然后在右侧的按钮中

点击“Add Variables”,然后如图所示:

这样就添加成功了。此时在源文件的对话框中,系统会自动生成必需的媒体实现文件。

3 / 24

四.播放器界面设计

设计的界面如下图所示,其中播放控制按钮有打开文件,播放,暂停,停止,快退,

快进,播放列表,全屏,退出,关于。然后还有音量控制,播放模式,播放进度,

列表选项的相关控制器件。

4 / 24

控件ID与变量关联如下:

控件

WMPlayer

ListControl

Slider

Slider

ID 变量类型

CWMPPlayer4

CListCtrl

CSliderCtrl

CSliderCtrl

int

变量名称

m_player

m_listCtrl

m_schedule

m_VOLUME

m_order

响应函数名称

OnOpen()

OnPlay()

OnPause()

OnStop()

OnReverse()

OnForward()

OnPlayList()

OnFullScreen()

OnExit()

OnSub()

OnAdd()

OnLast()

OnNext()

OnAbout()

OnSlience()

OnListchooseup()

OnListchoosedown()

OnListchoosedelet()

OnListdeleteall()

OnListimport()

OnListexport()

IDC_OCX1

IDC_LIST1

IDC_SLIDER1

IDC_SLIDER2

Radio Button IDC_ORDER

按钮控件的ID和对应的响应函数名称如下:

控件名称

打开文件

播放

暂停

停止

快退

快进

播放列表

全屏

退出

-

+

上一曲

下一曲

关于

静音

选中项上移

选中项下移

删除选中项

删除所有项

导入列表

导出列表

ID

IDC_OPEN

IDC_PLAY

IDC_PAUSE

IDC_STOP

IDC_REVERSE

IDC_FORWARD

IDC_PLAYLIST

IDC_FULLSCREEN

IDC_EXIT

IDC_SUB

IDC_ADD

IDC_LAST

IDC_NEXT

IDC_ABOUT

IDC_SILENCE

IDC_LISTCHOOSEUP

IDC_LISTCHOOSEDOWN

IDC_LISTCHOOSEDELETE

IDC_LISTDELETEALL

IDC_LISTIMPORT

IDC_LISTEXPORT

五.功能实现

(1)播放控制

 Windows Media Player 控件初始化

在添加该控件的时候自动生成的多个库文件,不同的文件实现播放器各个

方面的功能,所以需要我们手动将他们联系起来。所以我们要在

MediaPlayerDlg.h头文件中添加如下内容:

添加头文件:

#include "wmpcontrols.h"

#include "wmpsettings.h"

#include "wmpplaylist.h"

5 / 24

#include "wmpmedia.h"

添加公共成员:

CWMPControls m_control;

CWMPSettings m_setting;

CWMPMedia m_media;

在的初始化函数BOOL CMediaPlayerDlg::OnInitDialog()

中添加

m_control=static_cast(m_trols());

m_setting=m_tings();

m_list=static_cast(m_rentPlaylist());

m_media=static_cast(m_rentMedia());

将相应媒体播放控制文件联系起来。

 打开文件到播放列表

void CMediaPlayerDlg::OnOpen()

{

m_us();

CString str;

POSITION pos;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

m_mState(IndexInFieldList,~LVIS_SELECTED,

LVIS_SELECTED);

TCHAR szFilter[] =

_T("Mp3 File(*.mp3)|*.mp3

|Wma File(*.wma)|*.wma

|Video File(*.dat)|*.dat

|Wave File(*.wav)|*.wav

|AVI File(*.avi)|*.avi

|Movie File(*.mov)|*.mov

|Media File(*.mmm)|*.mmm

|Mid File(*.mid;*,rmi)|*.mid;*.rmi

|MPEG File(*.mpeg)|*.mpeg

|All File(*.*)|*.*||");

CFileDialog fileDlg(TRUE,NULL, NULL,OFN_HIDEREADONLY |

OFN_OVERWRITEPROMPT, szFilter, this);

CString strFilePath;

if (IDOK == l())

{

strFilePath = hName();

per();

m_(strFilePath);

m_media=static_cast(m_ia(strFilePath));

m_Item(m_media);

m_Item(0,m_e());

6 / 24

m_mText(0,1,_T(m_mInfo("FileType")));

m_mText(0,2,_T(m_ationString()));

m_mText(0,3,_T(strFilePath));

m_mText(0,4,_T(m_mInfo("Duration")));

m_(m_mText(0,3));

m_mState(0,LVIS_SELECTED,LVIS_SELECTED);

}

}

打开功能实现分为了两个部分,第一部分通过m_()来取得媒体文

件,第二部分是将媒体文件的相关信息添加到右侧的播放列表中去,让列表中

的光标始终停留在第一栏的位置。

 播放按钮

void CMediaPlayerDlg::OnPlay()

{

if(m_nt()<=0)

{

MessageBox("列表无文件!","Warning",MB_OK);

spaceflag=1;

}

else

{

if(!le(m_()))

{

MessageBox("文件不已存在,该列项将被删除!",

"Warning",MB_OK);

CMediaPlayerDlg::OnListchoosedelete();

}

else

{

KillTimer(0);

m_();

if(m_rentPosition()==0)

m_rentPosition(0.01);

SetTimer(0,20,NULL);

spaceflag=0;

}

}

}

播放功能主要是通过控件提供的m_()来实现的。函数中Timer的设

置和后面的播放模式有关,m_rentPosition(0.01)的目的是为了将

未播放状态与播放后的停止状态区分开来。

 暂停按钮

void CMediaPlayerDlg::OnPause()

7 / 24

{

m_();

}

停止按钮

void CMediaPlayerDlg::OnStop()

{

KillTimer(0);

m_();

}

全屏模式

void CMediaPlayerDlg::OnFullscreen()

{

if(m_rentPosition()!=0&&!m_lScreen())

{

m_();

m_lScreen(true);

m_();

}

}

全屏模式存在着bug,就是进入到全屏后不能够接收键盘输入字符,否则整个

程序会变为未响应状态。后来有添加了对键盘信息的获取和控制函数来解决这

个问题,后面会提到。

快进/退

void CMediaPlayerDlg::OnReverse()

{

double t = m_rentPosition();

m_rentPosition(t=t-10); }

void CMediaPlayerDlg::OnForward()

{

double t = m_rentPosition();

m_rentPosition(t=t+10);

}

虽然"wmpcontrols.h"中有直接快进、退的相关函数,但是视频播放时是无效的,

所以就没有用自带的函数来实现。这里是通过m_rentPosition()

来获得播放媒体的当前位置,然后通过m_rentPosition()来设置播

放媒体的当前位置为原位置+10或-10来实现快进、退功能。

播放列表的显示和隐藏

void CMediaPlayerDlg::OnPlaylist()

{

flag=!flag

if(flag)

{

SetWindowPos(NULL,0,0,440,505,SWP_NOMOVE);

}

8 / 24

else

{

SetWindowPos(NULL,0,0,760,505,SWP_NOMOVE);

}

}

从函数内容可以看出,播放列表的显示和隐藏是通过设置主窗体的大小来实现

的。其中flag为bool型的全局变量,初值为false。当按下播放列表的按钮时

会执行SetWindowPos(NULL,0,0,420,454,SWP_NOMOVE);无相对移动,窗口缩小

列表隐藏。执行另一语句时列表又会显示出来。

(2)音量控制

 静音

void CMediaPlayerDlg::OnSilence()

{

if(!m_e())

m_e(true);

else

m_e(false);

}

通过调用函数m_e()获取当前是否处于静音状态,通过

m_e(false/true)设置是否静音。

 加减音量

void CMediaPlayerDlg::OnAdd()

{

m_ume(m_ume()+10);

//获得当前音量大小,并设置当前音量为原音量大小+10

m_(m_ume());

//设置滑动条位置

}

void CMediaPlayerDlg::OnSub()

{

int Volume=m_ume();

m_ume(Volume=Volume-10);

//获得当前音量大小,并设置当前音量为原音量大小+10

m_(m_ume());

//设置滑动条位置

}

加减音量也可以通过调用相应的成员函数来实现。在按下“+”、“-”按钮时,

滑动条也会做出相对应的动作,滚动条需要初始化,会在下面的播放进度中详

细说明。

9 / 24

(3)播放模式

 上/下一曲

void CMediaPlayerDlg::OnLast()

{

// TODO: Add your control notification handler code here

m_us();

POSITION pos;CString strName;

UINT flag1 = LVIS_SELECTED|LVIS_FOCUSED;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

if(IndexInFieldList == -1)

{

AfxMessageBox("列表内没有被选中项!");

return;

}

if(IndexInFieldList == 0)

{

AfxMessageBox("已经到了列表头部!");

m_mState(IndexInFieldList, flag1, flag1);

return;

}

m_mState(IndexInFieldList,~LVIS_SELECTED,LVIS_SELECTED);

m_mState(IndexInFieldList-1, flag1, flag1);

strName=m_mText(IndexInFieldList-1,3);

CMediaPlayerDlg::OnStop();

m_(strName);

CMediaPlayerDlg::OnPlay();

}

void CMediaPlayerDlg::OnNext()

{

// TODO: Add your control notification handler code here

m_us();

POSITION pos;CString strName;

UINT flag1 = LVIS_SELECTED|LVIS_FOCUSED;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

if(IndexInFieldList == -1)

{

AfxMessageBox("列表内没有被选中项!");

return;

}

if(IndexInFieldList == m_mCount()-1)

10 / 24

{

AfxMessageBox("已经到了列表末尾!");

m_mState(IndexInFieldList, flag1, flag1);

return;

}

m_mState(IndexInFieldList,~LVIS_SELECTED,LVIS_SELECTED);

m_mState(IndexInFieldList+1, flag1, flag1);

strName=m_mText(IndexInFieldList+1,3);

CMediaPlayerDlg::OnStop();

m_(strName);

CMediaPlayerDlg::OnPlay();

}

上/下一曲的功能主要是通过移动播放列表中的光标来实现的。如上一曲的功

能实现过程为:IndexInFieldList获得列表光标当前位置,通过析构函数

m_mState(IndexInFieldList,~LVIS_SELECTED,LVIS_SELECTED)使本行光

标消失,通过函数m_mState(IndexInFieldList-1, flag1, flag1)使光标

显示在下一行的位置,strName=m_mText(IndexInFieldList-1,3)获得

光标所在行第四栏的信息,在这里也就是列表中媒体文件的路径,然后再调用

相关函数来进行播放。

 四种播放模式(顺序播放、随机播放、全曲循环、单曲循环)

首先我们需要定义一个Botton Group,在四个Radio Button选择一个单击右键,

在弹出菜单中选择“ClassWizard”,翻到“Member Variables”,找到刚刚选择

的Radio Button的ID,“Add Bariables”添加一个int型的成员m_order,如图

所示:

然后再在中填写各个Radio Button函数中的内容:

void CMediaPlayerDlg::OnOrder()

{

//顺序播放

m_order=0;

}

11 / 24

void CMediaPlayerDlg::OnRandom()

{

// 随机播放

m_order=1;

}

void CMediaPlayerDlg::OnAllcircle()

{

//全曲循环

m_order=2;

}

void CMediaPlayerDlg::OnSinglecircle()

{

// 单曲循环

m_order=3;

}

之前在ClassWizard中已经添加好了OnTimer成员。这时我们要把它联合起来

使用:

(关键代码)

CMediaPlayerDlg::OnTimer(UINT nIDEvent)

{//计时器的选择代码省略

switch(m_order)

{

case 0:

{

KillTimer(0);

POSITION pos;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

m_us();

if(IndexInFieldList == m_mCount()-1)

{

m_mState(IndexInFieldList, LVIS_SELECTED,LVIS_SELECTED);

m_();

return;

}

m_mState(IndexInFieldList,~LVIS_SELECTED,

LVIS_SELECTED);

m_mState(IndexInFieldList+1, LVIS_SELECTED,LVIS_SELECTED);

CString strName=m_mText(IndexInFieldList+1,3);

m_(strName);

CMediaPlayerDlg::OnPlay();

break;

12 / 24

}

case 1:

{

KillTimer(0);

m_us();

POSITION pos;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

m_mState(IndexInFieldList,~LVIS_SELECTED,

LVIS_SELECTED);

int i;

srand((unsigned)time( NULL ));

i=rand()%m_mCount();

m_mState(i, LVIS_SELECTED,LVIS_SELECTED);

CString strName=m_mText(i,3);

m_(strName);

CMediaPlayerDlg::OnPlay();

break;

}

case 2:

{

KillTimer(0);

POSITION pos;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

m_us();

if(IndexInFieldList == m_mCount()-1)

{

IndexInFieldList=-1;

}

m_mState(IndexInFieldList,~LVIS_SELECTED,

LVIS_SELECTED);

m_mState(IndexInFieldList+1, LVIS_SELECTED,

LVIS_SELECTED);

CString strName=m_mText(IndexInFieldList+1,3);

m_(strName);

CMediaPlayerDlg::OnPlay();

break;

case 3:

{

KillTimer(0);

m_rentPosition(0.01);

m_();

13 / 24

}

SetTimer(0,20,NULL);

break;

}

default:

{

KillTimer(0);

break;

}

}

各种播放模式的实现都是通过对播放列表进行操作来实现的。具体来讲就是通

过控制列表中的光标的移动来获取光标所在行的相关信息。

(4)播放进度

 滚动条和数值显示

因为他们共同构成一个整体,又在同一个OnTimer()函数中,所以就合起来说

明。

首先为IDC_SLIDER1添加CSliderCtrl类型的成员m_schedule;

然后是滚动条的初始化,在的OnInitDialog()中添加语句:

m_ge(0,200,false);

m_Freq(1);

m_eSize(1);

m_(0);

最后在对OnTimer()进行编辑:

void CMediaPlayerDlg::OnTimer(UINT nIDEvent)

{

switch(nIDEvent)

{

case 0:

{

If(m_rentPosition()==0);

SetDlgItemText(IDC_CURRENT,"00:00");

SetDlgItemText(IDC_DURATION,"00:00");

//下面是有关播放模式的代码,在这里省略

//……

POSITION pos;double td;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

td=_ttol(m_mText(IndexInFieldList,4));

m_(

(int)((m_rentPosition()/td)*200));

SetDlgItemText(IDC_DURATION,

m_mText(IndexInFieldList,2));

SetDlgItemText(IDC_CURRENT,

14 / 24

}

}

CDialog::OnTimer(nIDEvent);

m_rentPositionString());

break;

}

此处的nIDEvent就是你前面设置的Timer的编号,当编号为0的时候就执行下

面的语句。SetDlgItemText()让媒体的当前播放的位置和总长度以数值的形式显

示出来。

5)列表选项

 选中项上下移动

void CMediaPlayerDlg::OnListchooseup()

{

// TODO: Add your control notification handler code here

m_us();

POSITION pos;

int num;

CString name;

CString form;

CString length;

CString strName;

CString duration;

UINT flag1 = LVIS_SELECTED|LVIS_FOCUSED;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

if(IndexInFieldList == -1)

{

AfxMessageBox("列表内没有被选中项!");

return;

}

if(IndexInFieldList == 0)

{

AfxMessageBox("已经到了列表头部!");

m_mState(IndexInFieldList, flag1, flag1);

return;

}

num=IndexInFieldList;

name=m_mText(num,0);

form=m_mText(num,1);

length=m_mText(num,2);

strName=m_mText(num,3);

duration=m_mText(num,4);

m_Item(num);

15 / 24

m_Item(num-1,_T(name));

m_mText(num-1,1,_T(form));

m_mText(num-1,2,_T(length));

m_mText(num-1,3,_T(strName));

m_mText(num-1,4,_T(duration));

m_mState(IndexInFieldList-1, flag1, flag1);

}

void CMediaPlayerDlg::OnListchoosedown()

{

// TODO: Add your control notification handler code here

m_us();

POSITION pos;

int num;

CString name;

CString form;

CString length;

CString strName;

CString duration;

UINT flag1 = LVIS_SELECTED|LVIS_FOCUSED;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

if(IndexInFieldList == -1)

{

AfxMessageBox("列表内没有被选中项!");

return;

}

if(IndexInFieldList == m_mCount()-1)

{

AfxMessageBox("已经到了列表末尾!");

m_mState(IndexInFieldList, flag1, flag1);

return;

}

num=IndexInFieldList;

name=m_mText(num,0);

form=m_mText(num,1);

length=m_mText(num,2);

strName=m_mText(num,3);

duration=m_mText(num,4);

m_Item(num);

m_Item(num+1,_T(name));

m_mText(num+1,1,_T(form));

m_mText(num+1,2,_T(length));

m_mText(num+1,3,_T(strName));

16 / 24

m_mText(num+1,4,_T(duration));

m_mState(IndexInFieldList+1, flag1, flag1);

}

该功能和上下一曲的实现方法很相似。将光标所在行的信息通过临时变量记录

下来,之后将该行删除,再通过m_Item()、m_mText()

将临时变量记录下来的信息插入到前一行或后一行中去并让光标停留在该行。

 删除选中项

void CMediaPlayerDlg::OnListchoosedelete()

{

// TODO: Add your control notification handler code here

m_us();

POSITION pos;CString strname;

int num;

UINT flag1 = LVIS_SELECTED|LVIS_FOCUSED;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

if(IndexInFieldList == -1)

{

AfxMessageBox("列表内没有被选中项!");

return;

}

num=IndexInFieldList;

m_Item(num);

CMediaPlayerDlg::OnStop();

if(m_mCount()!=0)

{

if(IndexInFieldList == m_mCount())

{

m_mState(IndexInFieldList-1, flag1, flag1);

strname=m_mText(IndexInFieldList-1,3);

m_(strname);

}

else

{

m_mState(IndexInFieldList, flag1, flag1);

strname=m_mText(IndexInFieldList,3);

m_(strname);

}

CMediaPlayerDlg::OnPlay();

}

}

删除选中项通过m_Item(),不过要注意删完该行后光标应停留在

哪里的问题。如果删除行不是最后一行,那么光标可以停留在下一行,如何是

删除的最后一行,那么光标应该停留在上一行。

17 / 24

 删除所有项

void CMediaPlayerDlg::OnListdeleteall()

{

// TODO: Add your control notification handler code here

CMediaPlayerDlg::OnStop();

int m=m_mCount(),i;

for(i=m-1;i>=0;i--)

{

m_Item(i);

}

}

获得列表中的行数,从最后一行往上逐行删除。

 导入列表

void CMediaPlayerDlg::OnListimport()

{

// TODO: Add your control notification handler code here

m_us();

TCHAR szFilter[] = _T("列表文件(*.list)|*.list||");

// 构造打开文件对话框

CFileDialog fileDlg(TRUE, _T("list"), NULL, 0, szFilter, this);

CString strFilePath;

// 显示打开文件对话框

if (IDOK == l())

{

// 如果点击了文件对话框上的“打开”按钮,则将选择的文件路径

显示到编辑框里

strFilePath = hName();

}

CStdioFile file;int i;

if((strFilePath,CFile::modeRead|CFile::typeText))

{

POSITION pos;

pos = m_stSelectedItemPosition();

IndexInFieldList = m_tSelectedItem(pos);

m_mState(IndexInFieldList,

~LVIS_SELECTED,LVIS_SELECTED);

Begin();

CString str;CString strtemp[6];

while(ring(str))

{

for(i=0;i<5;i++)

AfxExtractSubString(strtemp[i],str,i,'|');

m_Item(0,strtemp[0]);

m_mText(0,1,_T(strtemp[1]));

18 / 24

}

m_(m_mText(0,3));

m_mState(0,LVIS_SELECTED,LVIS_SELECTED);

}

else

{

TRACE("Can't open list file!");

}

();

m_mText(0,2,_T(strtemp[2]));

m_mText(0,3,_T(strtemp[3]));

m_mText(0,4,_T(strtemp[4]));

m_(strtemp[3]);

m_media=static_cast(

m_ia(strFilePath));

m_Item(m_media);

}

找到要导入的列表文件,虽然把文件的后缀名改为了list,实际上还是文本文

件,只是为了与其他的非列表文本文件区分开来。

通过ring(str)逐行读取list文件内容。

通过AfxExtractSubString(strtemp[i],str,i,'|'),将字符串流切分成几个小的字符串,

记录在数组中,再导入列表里面。

如图是以文本文件格式打开的list文件:

 导出列表

void CMediaPlayerDlg::OnListexport()

{

// TODO: Add your control notification handler code here

TCHAR szFilter[]=_T("列表文件(*.list)|*.list||");

CFileDialog fileDlg(FALSE,_T("list"),NULL,OFN_HIDEREADONLY |

OFN_OVERWRITEPROMPT, szFilter, this);

CString strFilePath;

if (IDOK == l())

{

// 如果点击了文件对话框上的“保存”按钮,则将选择的文件路径

显示到编辑框里

strFilePath = hName();

}

CStdioFile file;int i,j;

if((strFilePath,CFile::modeCreate|CFile::modeReadWrite|

CFile::typeText))

{

19 / 24

for(i=m_mCount()-1;i>=0;i--)

{

CString temp;

for(j=0;j<4;j++)

{

temp=m_mText(i,j);

temp+="|";

tring(temp);

}

temp=m_mText(i,j);

temp+="n";

tring(temp);

}

();

}

else

{

TRACE("Can't Open File");

}

}

前半部分获取保存路径,后半部分将列表信息写入到该路径下的文件中。

(6)获取按键信息

在”ClassWizard”中的”Message Maps”页面为”CMediaPlayerDlg”添加”Member

functions”:PreTranslateMessage如图所示。

20 / 24

再添加如下代码:

BOOL CMediaPlayerDlg::PreTranslateMessage(MSG* pMsg)

{

// TODO: Add your specialized code here and/or call the base class

if(pMsg->message==WM_KEYDOWN)

{

switch(pMsg->wParam)

{

case VK_ESCAPE:

{//ESC键

if(m_rentPosition()!=0&&

m_lScreen())

m_lScreen(false);

else

SendMessage(WM_CLOSE);

return TRUE;

break;

}

case VK_SPACE:

{//空格键

if(spaceflag==0)

CMediaPlayerDlg::OnPause();

else

if(spaceflag==1)

CMediaPlayerDlg::OnPlay();

return TRUE;

break;

}

case VK_LEFT:

{//←键

CMediaPlayerDlg::OnReverse();

return TRUE;

break;

}

case VK_RIGHT:

{//→键

CMediaPlayerDlg::OnForward();

return TRUE;

break;

}

case VK_PRIOR:

{//PageUp键

CMediaPlayerDlg::OnLast();

return TRUE;

21 / 24

}

break;

}

case VK_NEXT:

{//PageDown键

CMediaPlayerDlg::OnNext();

return TRUE;

break;

}

case VK_UP:

{//↑键

CMediaPlayerDlg::OnAdd();

return TRUE;

break;

}

case VK_DOWN:

{//↓键

CMediaPlayerDlg::OnSub();

return TRUE;

break;

}

default:

return TRUE;

break;

}

return CDialog::PreTranslateMessage(pMsg);

}

到此,全屏不能碰键盘的bug被修复了,并且也可以通过键盘进行媒体播放

操作,特别是在全屏播放视频文件的时候。

22 / 24

实验结果

(1) 音乐播放测试

(2) 视频播放测试

(3) 列表导入测试

23 / 24

(4) 列表导出测试

相关代码及工程文件下载:

/share/link?shareid=1420842405&uk=3425060786

2013-6-30

24 / 24

本文标签: 播放文件列表控件实现