VFP探讨之OLE控件(四):多媒体控制器(中)
上期介绍了利用多媒体控制器制作背景音乐。现在就说说如何利用多媒体控制器设计一个简易播放器。播放器分成两部分:播放CD和播放wave文件,本期介绍其中的播放CD部分。由于是简易播放器,就不设计时间跳动界面和声音控制部分了。在界面上,CD播放器只有两处显示:一处是在下拉列表框中显示当前光驱盘符,同时,若有不止一个光驱,可供用户下拉选择;另一处是在下拉列表框后面显示是否放入了CD唱片。
CD播放器设计时有以下几个地方需要重点关注:
1、如何判断某个盘符是光驱;
2、如何实时检查指定光驱中已放入了CD唱片;
3、如何判断当前光驱中是否放入了有效的CD唱片;
4、光驱中无盘片时,如何用按钮弹出光驱托盘;
5、若有多光驱,如何使播放器正确弹出用户选择的当前光驱;
接下来就这四个方面具体说说,其它的看附件表单中的相应代码。为了便于理解代码中对象的名字,这里先罗列一下:表单对象的内存变量名字:MMC;选项钮组名字:功能;第一个选项钮名字:CD播放器;第二个选项钮名字:数字音频播放器;下拉列表框名字:光驱列表;Timer控件名字:计时器;弹出按钮名字:弹出。
如何判断某个盘符是光驱?
这个问题比较简单,FoxPro 9.0本身就提供了这样的函数:DRIVETYPE(),它的调用语法是:DRIVETYPE(路径)。其中:参数“路径”必须是要带盘符的路径(比如:C:\、D:\ABC等),至于这个路径是否真实存在,FoxPro不会去管。该函数的返回值为数值型,分别是:“1”:未知类型。当找不到指定盘符或路径中不包含盘符时,返回该值。可以利用该返回值来判断是否所有盘符都已遍历;“2”:软盘;“3”:硬盘;“4”:可移动硬盘或网络驱动器;“5”:CD-ROM;“6”:RAM磁盘(用内存模拟出来的磁盘)。根据以上返回值就很容易判断哪个盘符是光驱,即,返回值为5的就是。
请看下面一段代码(选自“功能.CD播放器.Click”事件代码):
FOR I=67 TO 90 &&从C盘开始检查,因为A、B总是代表软驱的
光驱符号=CHR(I)+":\"
盘符类型号=DRIVETYPE(光驱符号)
IF 盘符类型号=1 THEN &&检查完所有的盘符
EXIT
ELSE
IF 盘符类型号=5 THEN &&是光驱符号
光驱数=光驱数+1
PUBLIC 光驱[光驱数]
光驱[光驱数]=光驱符号
ENDIF
ENDIF
NEXT
如何实时检查指定光驱中已放入了CD唱片?
可以用一个Timer控件,Interval属性值设为10(毫秒),Timer事件的代码如下:
IF 播放类型=1 THEN &&播放CD时
IF MMC.播放器.Mode=524 OR MMC.播放器.Mode=525 THEN &&如果处在停止状态
MMC.光驱列表.Click
ENDIF
ENDIF
如何判断当前光驱中是否放入了有效的CD唱片?
唱片文件名的格式通常是“Track01.CDA”这种,因此,只要用FILE函数检查该驱动器中是否存在文件“Track01.CDA”就可以了。代码如下(选自“光驱列表.Click”事件):
IF 播放类型=1 THEN &&放CD时
PUBLIC 当前光驱序号,第一首曲子
当前光驱序号=This.ListIndex
第一首曲子=This.DisplayValue+"Track01.cda"
IF !FILE(第一首曲子) THEN
MMC.Label1.Caption="还未放入CD"
MMC.Label1.ForeColor=RGB(255,0,0)
MMC.播放.Enabled= .F.
ELSE
MMC.Label1.Caption="已放入CD"
MMC.Label1.ForeColor=RGB(0,0,255)
MMC.播放器.FileName=第一首曲子
MMC.播放.Enabled= .T.
ENDIF
ELSE &&放音频文件时
… …
ENDIF
光驱中无盘片时,如何用按钮弹出光驱托盘?
多媒体控制器中的Command属性,其中有一个值是Eject,就是用来弹出或收回光驱托盘的。但是它有一个缺陷:当光驱中无任何盘片时,该命令不起作用,这不符合我们日常使用习惯。要解决这个问题,就要动用API函数mciExecute(),谁有更好的方法,可以跟帖告诉我。API函数在使用前需要声明,声明的语法是:DECLARE 函数返回值的类型 函数名 IN DLL库的文件名 [参数1类型 [@]参数1 [, … …][, 参数n类型 [@]参数n]],语法中红色文字为关键字,中括号中的内容表示其中内容可以省略。声明的代码是(选自“Form1.Init”事件):DECLARE Long mciExecute IN winmm.dll String 命令字串。其中,Long表示该函数返回值是一个长整型;mciExecute是函数名(不需要标明后面的圆括号);winmm.dll是Windows操作系统自带的一个包含API函数的库文件;String表示参数1的数据类型是字符串型(API函数的数据类型标识不同于FoxPro);“命令字串”是参数1的名字,该名字可以随意命名,大致可参考FoxPro内存变量的命名方式。在本例中,mciExecute()函数需要有一个字符串类型的参数用来向FoxPro发出指令,所以在声明中需要有一个参数。
使用mciExecute()函数的代码如下(选自“弹出.Click”事件):
CD_Driver=MMC.光驱列表.DisplayValue+;
" type CDAudio alias cdrom" &&指定哪个盘符为默认光驱
mciExecute("open "+CD_Driver)
IF !光驱打开 THEN
mciExecute("set cdrom door open")
光驱打开=.T.
ELSE
mciExecute("set cdrom door closed")
光驱打开=.F.
ENDIF
第一个mciExecute()函数用来打开光驱设备,且设置光驱别名为“cdrom”;第二个mciExecute()函数用来弹出光驱托盘,其中“cdrom”就是前面mciExecute()函数设置的别名;第三个mciExecute()函数用来收回光驱托盘。
若有多光驱,如何使播放器正确弹出用户选择的当前光驱?
这个问题让我在网络上找了好久,一直得不到答案,网络上关于用API函数弹出光驱托盘的命令多为mciExecute(“open CDAudio alias cdrom”) + mciExecute( "set cdrom door open")的组合,而这种组合只能弹出多光驱中盘符在前的那个光驱的托盘。一个很偶然的机会,我在网上发现了一小段C语言程序,让这个问题得以解决。就是把打开光驱设备的命令写成mciExecute(“open e: type CDAudio alias cdrom”)这种形式,也即,指定哪个盘符为当前播放CD音乐的光驱。再结合表单中设计的下拉列表,由此得到命令组合CD_Driver=MMC.光驱列表.DisplayValue+" type CDAudio alias cdrom"+mciExecute("open "+CD_Driver)。今天在这里分享出来,也是希望有多光驱的朋友不再受这个问题的困扰。
当然,这个简易的CD播放器还是有缺陷的:如果用户手工按下光驱的弹出键弹出托盘,则程序无法感应。有知道如何在FoxPro中判断光驱托盘是否被弹出的朋友请跟帖列出代码,若实验通过,将给予不低于50的奖励分!
简易播放器.rar
(163.13 KB)
[ 本帖最后由 taifu945 于 2014-4-11 21:55 编辑 ]