您现在的位置: 中国教师站 >> 教师关注 >> 电脑技术 >> 编程技术 >> Delphi >> 正文

Google
Delphi中MediaPlayer控件的一个Bug即修复
作者:Siny 文章来源:中国教师站cn-teacher 点击数: 更新时间:2007-4-22 15:58:02

最近在使用MediaPlayer控件编程时发现一个奇怪的问题,刚开始百思不得其解,不知道是MediaPlayer的问题,还是Delphi的MMSystem.pas本身就错了
问题如下
 MediaPlay.DeviceType的值只能设成dtAutoSelect,否则,不管是AVI,还是MPG文件都不能播放,我用Delphi6 和Delphi6 sp2 在win2000和xp环境下测试,均不能成功。
 如果将设备类型设置成明显的错误,MediaPlay控件会报错,如文件是AVI或MPG格式,选择DeviceType=dtCDAudio,会报MCI错误,但是如果用AVI文件,选择dtAVIVideo,则不报任何错误,文件打开,但不管是通过程序,还是通过MediaPlay的Button总之是播放不了文件的,而且MediaPlay.Length的长度也不正确例如:       
 ExPlay.DeviceType :=dtAVIVideo;
        ExPlay.FileName := 'd:windowsclock.avi';
        ExPlay.Open;
        ExPlay.Play;
    在不得已的情况下我只能去看MediaPlayer的源代码(本人对Delphi实在了解的不多)
分析情况如下
Delphi的TMediaPlayer控件的DeviceType是只能在几种类型中选择,这是在MPlay.pas中定义的几种
TMPDeviceTypes = (dtAutoSelect, dtAVIVideo, dtCDAudio, dtDAT, dtDigitalVideo, dtMMMovie,
    dtOther, dtOverlay, dtScanner, dtSequencer, dtVCR, dtVideodisc, dtWaveAudio);
在MCI的定义中有如下结构:
  tagMCI_OPEN_PARMSA = record
    dwCallback: DWORD;
    wDeviceID: MCIDEVICEID;
    lpstrDeviceType: PAnsiChar;  //设备类型
    lpstrElementName: PAnsiChar;
    lpstrAlias: PAnsiChar;
  end;
在mplay.pas中
procedure TMediaPlayer.Open;
const
  DeviceName: array[TMPDeviceTypes] of PChar = ('', 'AVIVideo', 'CDAudio', 'DAT',
    'DigitalVideo', 'MMMovie', 'Other', 'Overlay', 'Scanner', 'Sequencer',
    'VCR', 'Videodisc', 'WaveAudio');
...设定了实际传给MCI的DeviceType值................
begin
 ......(mplay.pas lines 841)
 OpenParm.lpstrDeviceType := DeviceName[FDeviceType];   // 你选定的设备类型
       ......
   if FDeviceType <> dtAutoSelect then
      FFlags := FFlags or mci_Open_Type;

     if FDeviceType <> dtAutoSelect then            //不明白为什么这里要做两次同样的判断
      FFlags := FFlags or mci_Open_Type
     else
      FFlags := FFlags or MCI_OPEN_ELEMENT;    //只有这样才能正确播放,也就是自动模式
 
 OpenParm.dwCallback := Handle;
   FError := mciSendCommand(0, mci_Open, FFlags, Longint(@OpenParm));  //。。。。。。

参照上面的情况,我选择DeviceType=dtAVIVideo时传的值就应该是‘AVIVideo’。这也和注册表中的MCI32项中的值对应。为了验证使用lpstrDeviceType的值确实是可以用'AVIVideo'我加载了一个MCI32.OCX,这个控件是在VS6种附带的,其中的DeviceType属性和TMediaPlayer中的DeviceType属性大致相当,只不过MCI32.ocx中的值可以直接指定到设备名,我将MCI32.ocx的DeviceType设成'AVIVideo',结果可以正常播放。
   为了找出原因,我将VC的MMSystem.h文件和MMSystem.pas中的参数和数据结构作比较,没有发现有什么差异,基本判断MMSystem,pas是没有问题的,那么问题一定在mplay.pas中了。于是从mplay.pas中另外生成一个控件TDeMediaPlay,跟踪下来,居然也没有发现什么问题,文件打开MCIOpened 、设备号FDeviceID、是否显示FHasVideo等标志正常,GetDeviceCaps函数无异常,唯独GetLength函数中
 FError := mciSendCommand( FDeviceID, mci_Status, FFlags, Longint(@StatusParm));
 Result := StatusParm.dwReturn;
的返回值不正常,而且居然也没有返回错误,在我的机器上,不管怎么设置timeformat都返回4,您的机器可能会不一样
   播放器之类的软件实在是以前没写过,去网上查找关于这方面的Delphi的资料,好像都是让自动选择的也就是dtAutoSelect模式的,但恰恰我的要求是一定要指定具体驱动。
   没有办法,再次打开VC,找到一个MCI的例子,仔细阅读,发现了问题,例子中有这样一段代码
 mciMO.lpstrDeviceType="MpegVideo";
 ......
 dwFlags=(DWORD)(MCI_OPEN_ELEMENT|MCI_OPEN_TYPE|)

[1] [2] 下一页

  • 上一篇文章:

  • 下一篇文章:
  • 相关专题:
     
     网友评论:(评论内容只代表网友观点,与本站立场无关!)
    GOOGLE广告

    阅读排行

    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 |
    中国教师站

    中国教师站 版权所有 Copyright © 2006-2020 All Rights Reserved 站长:Sina & Siny
    [备用域名:www.JXZYW.Com] 有事请留言有事请留言
    【实力成就精品 诚信呵护品牌】

    信息产业部备案
    苏ICP备06018635号