标题:VFP探讨之OLE控件(四):多媒体控制器(中)
只看楼主
taifu945
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:80
帖 子:1545
专家分:3298
注 册:2012-7-6
结帖率:100%
 问题点数:0 回复次数:3 
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 编辑 ]
搜索更多相关主题的帖子: 播放器 多媒体 控制器 背景音乐 光驱 
2014-04-11 18:51
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:0 
触类旁通、非常实用!

活到老,学到老! http://www. E-mail:hu-jj@
2014-04-11 21:20
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
得分:0 
学习
2014-04-17 15:15
asdf_123000
Rank: 4
等 级:业余侠客
威 望:1
帖 子:262
专家分:203
注 册:2012-12-20
得分:0 
非常实用
2014-04-18 18:45



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-429971-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.053148 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved