2013年3月22日星期五

VC++多媒体编程

 标题成绩:我念写法式节制IDE接心的光驱,但是却找没有到正在VC里该如何做,好比我知讲正在MMC(Multi-Media Commands)里有一条下令是Test Unit Ready(00h),但是我没有知讲正在VC里如何把那条下令收给光驱,

  解问:

  对一样平常的操做法式去讲,Visual C++ 可以或许讲是搜罗万象,但是令人遗憾的是,几远出有传讲风闻过Visual C++ 对多媒体供给过头孟抚撑,以致有人讲Visual C++没有摇率多媒体编程。如果我们完备操做Visual C++的类库而没有念面把戏的话,死怕连最一个简朴的RPG游戏堵没有出去。对一个需供除夜量动绘、声音的多媒体操做法式去讲,Visual C++ 最多供给了一个中壳,而格氏苹个劣秀的声音、动绘引擎的任务,便降到了法式员的身上。

  正在而后各章节中,将陆绝介绍除夜家如何斥天阿谁引擎。

  1 对声音的措置

  1.1媒体节重朴心

  MCI(Media Control Inte***ce)媒体节重朴心是MircroSoft供给的一组多媒体设备战文件的尺度接心,它的益处是可以或许便当天节制尽除夜多数多媒体设备搜罗 音频、视频、影碟、录相称多媒体装被霈而没有需供知讲它们的内部工做自遇。但是前人云R∩也萧何,败也萧何。MCI虽然看上往下除夜齐,但对一些初级操做 去讲,它是远远步杌的。好比Visual C++虽然看上往无所事事,却需供法式员自家♀天多媒体引擎一样。对MCI指令散,我们将只做简朴介绍,重面放正在后里的波形文件混音器上。

  MCI的节制格式:

  一样平常讲去,法式员操做两个函数便可以或许与MCI挨交讲了:

  MCIERROR mciSendCommand(MCIDEVICEID wDeviceID, UINT uMsg,

  DWORD dwFlags, DWORD dwParam );

  下令字符串格式,用接远于仄居糊心用语的格式收支节制下令,开用于初级编程如VB、TOOLBOOK涤耄

  MCIERROR mciSendString(LPCTSTR lpszCommand,LPTSTR lpszReturnStr

  ing, UINT cchReturn, HANDLE hwndCallback

  );

  下令消息格式,用专业语法收支节制消息,开用于VC等发言编程,此格式直接与MCI设备挨交讲。

  对mciSendCommand,第一个参数指定了设备标识,阿谁标识会正在法式钥氦开MCI装笨啾由体系供给。第两个参数指定将如何节制装被霈具体 请查阅后里“MCI指令”一栏。第三个参数为访谒标识,第四个参数一样平常为一个数据挨算,标识法式正在访谒MCI时要的一些疑息。颖ヘ具体原料,请查阅 本光盘配套书。

  对mciSendString,第一个参数为一串节制字符串,返回疑息由系徒壁进第两个参数,第三个参数指明返回疑息的最除夜少度,若对MCI拆配设定了"notify"标识表记标帜则需供正在第四个参数挖上返回窗心句柄。

  举例:

  mciSendCommand(DeviceID,MCI_CLOSE,NULL,NULL);//启闭一个MCI装被龌

  mciSendString("open aaa.avi",0,0,0); //挨开文件"aaa.avi";

  MCI的设备范例:

  MCI的设备范例有:

  设备形貌

  形貌字符串

  申明

  MCI_ALL_DEVICE_ID

  统统设备

  MCI_DEVTYPE_ANIMATION

  Animation

  动绘设备

  MCI_DEVTYPE_CD_AUDIO

  Cdaudio

  CD音频

  MCI_DEVTYPE_DAT

  Dat

  数字音频

  MCI_DEVTYPE_DIGITAL_VIDEO

  Digitalvideo

  数琢坑频

  MCI_DEVTYPE_OTHER

  Other

  已界讲设备

  MCI_DEVTYPE_OVERLAY

  Overlay

  堆叠视频

  MCI_DEVTYPE_SCANNER

  Scanner

  扫描仪

  MCI_DEVTYPE_SEQUENCER

  Sequencer MIDI

  序列器

  MCI_DEVTYPE_VCR

  Vcr

  摇陆录相机

  MCI_DEVTYPE_VIDEODISC

  Videodisc

  激光柿犹

  MCI_DEVTYPE_WAVEFORM_AUDIO

  waveaudio Wave

  音频

  对已正在上里界岛媚MCI装被霈映雩可检察system.ini文件中[mci]部门,比方:

  [mci]

  cdaudio=mcicda.drv

  sequencer=mciseq.drv

  waveaudio=mciwave.drv

  avivideo=mciavi.drv

  videodisc=mcipionr.drv

  vcr=mcivisca.drv

  ActiveMovie=mciqtz.drv

  QTWVideo=mciqtw.drv

  MPEGVideo=C:\PROGRA~1\XING\XINGMP~1\xmdrv95.dll

  个中末了两句告别指了然Apple的QuickTime装被霈设备名为"QTWVidio"、MPEG记忆装被霈设备名为"MPEGVideo"。

  正在MCI编程中,既可以或许将设备形貌当设备名,也能够或许将形貌字符串当设备名,一个极吨Ы擦的格式识台度员没有要正在法式中指定设备名,Windows将自动按照文件扩大名辨认设备范例。

  举个例子去讲,挨开一个多媒体文件有以下三种格式:

  [1]:自动辨认:挨开一个"WAV"文件

  MCI_OPEN_PARMS mciOpen;

  mciOpen.lpstrDeviceType=0;

  mciOpen.lpstrElementName="aaa.wav";

  mciSendCommand(NULL,MCI_OPEN, MCI_OPEN_ELEMENT,

  (DWORD)&mciOpen);

  [2]:指定设备形貌:挨开CD播放器

  MCI_OPEN_PARMS mciOpen;

  mciOpen.lpstrDeviceType=(LPSTR)MCI_DEVTYPE_CD_AUDIO ;

  mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID,

  (DWORD)&mciOpen);

  [3]:指定形貌字符串: 挨开一个AVI文件

  MCI_OPEN_PARMS mciOpen;

  mciOpen.lpstrDeviceType="avivideo";

  mciOpen.lpstrElementName="aaa.avi";

  mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,

  (DWORD)&mciOpen);

  寄看三种挨开格式中,函数第三个参数的辩黑,后里会讲到那类辩黑。

  MCI指令

  MCI操做以下指令:

  MCI_BREAK

  设置间断键,缺省是”CTRL+BREAK"

  MCI_CAPTURE

  抓与当前帧并存进指定文件,仅用于数琢坑频

  MCI_CLOSE

  启闭设备

  MCI_CONFIGURE

  弹出竖坐对话框,仅用于数琢坑频

  MCI_COPY

  拷贝数据至剪掀板

  MCI_CUE

  延时播放或录音

  MCI_CUT

  删除数据

  MCI_DELETE

  删除数据

  MCI_ESCAPE

  仅用于激光视频

  MCI_FREEZE

  将隐现定格

  MCI_GETDEVCAPS

  得到设备疑息

  MCI_INDEX

  当前屏幕隐现与可,仅用于VCR设备

  MCI_INFO

  得到字符串疑息

  MCI_LIST

  得到输进装笨帻目,撑沉魁琢坑频战VCR设备

  MCI_LOAD

  拆进一个文件

  MCI_MARK

  消弭或做一个暗号,与MCI_SEEK配套

  MCI_MARK

  消弭或做一个暗号,与MCI_SEEK配套

  MCI_MONITOR

  为数琢坑频指定述讲设备

  MCI_OPEN

  挨开设备

  MCI_PASTE

  粘帖数据

  MCI_PAUSE

  暂伏掀前动做

  MCI_PLAY

  播放

  MCI_PUT

  设置源、方针战边框矩形

  MCI_QUALITY

  界讲设备缺省量量

  MCI_RECORD

  匹里劈脸录制

  MCI_RESERVE

  分拨硬疟间

  MCI_RESTORE

  拷贝一个bmp文件至帧灰″

  MCI_RESUME

  使一个停息设备重新启动

  MCI_SAVE

  留村据

  MCI_SEEK

  变动媒体位置

  MCI_SET

  设置设备疑息

  MCI_SETAUDIO

  设置音量

  MCI_SETTIMECODE

  启映鲵消弭VCR设备的时分码

  MCI_SETTUNER

  设置VCR设备频讲

  MCI_SETVIDEO

  设置video参数

  MCI_SIGNAL

  正在工做区上设置指定空间

  MCI_STATUS

  得到设备疑息

  MCI_STEP

  使播啡影备跳帧

  MCI_STOP

  停止播放

  MCI_SYSINFO

  返回MCI设备疑息

  MCI_UNDO

  消弭操纵

  MCI_UNFREEZE

  使操做MCI_UNFREEZE的视频灰″邙规复举动

  MCI_UPDATE

  更兄牺现地区

  MCI_WHERE

  得到设备减少矩形

  MCI_WINDOW

  指定图形设备窗心战窗心特性

  个中比较常常操做的指令有MCI_OPEN、MCI_CLOSE、MCI_PLAY、MCI_STOP、MCI_PAUSE、MCI_STATUS等涤耄

  真例阐收

  正在Visual C++ 5.0步播上面与new,单击projects,拔与MFC AppWizard(exe),竖坐一个新的名为"mcitest"的工程文件,OK冶。

  寄看正在操做法式范例当选择"Dialog based",然后Finish完成。那是一个基于对话框的操做法式,为林ш成MCI测试的任务,我们要变动一下对话框本钱。面与"Resource View",正在"Dialog"下拔与"IDD_MCITEST_DIALOG"对话框,按序增减Button如图所示。

  完成对话框的编削。左键单击mcitest files、拔与Add Files To Project,减进配套光盘止终给的"commci.cpp"战"commci.h"文件。挨开ClassWizard,正在Class Name下选择CMcitestDlg,减进统统的按键消息措置函数。

  正在"cmcitestDlg"类中,告别用"COMMCI"界讲Wav、Midi、Avi三个成员变量,正在按钮吸应进程中告别写上吸应措置函数open( )、play( )、close( )、pause( )、stop( )。

  正在"projoct"步播下单击setting,弹出设置对话框,正在"link"下"object/library modules"下减进"winmm.lib",编译并匝弄法式:

  图5.1

  源法式介绍

  // commci.h: inte***ce for the commci class.

  //

  ////////////////////////////////////////////////// ////////////////////

  #if !defined(AFX_COMMCI_H__90CEFD04_CC96_11D1_94F8_000 0B431BBA1__INCLUDED_)

  #define AFX_COMMCI_H__90CEFD04_CC96_11D1_94F8_0000B431BBA1 __INCLUDED_

  #if _MSC_VER >= 1000

  #pragma once

  #endif // _MSC_VER >= 1000

  //#include <windows.h>

  #include <mmsystem.h>

  class COMMCI

  {

  private:

  HWND hOwer; //窗心的具有者

  MCI_OPEN_PARMS mciOpen;

  public:

  COMMCI();

  ~COMMCI() {Close(); }

  MCIERROR Open(LPCSTR DeviceType,LPCSTR filename);

  //经过进程形貌字符串挨开设备

  MCIERROR Open(int DeviceType,LPCSTR filename); //经过进程设备范例挨开设备

  MCIERROR Open(LPCSTR filename); //自动检测设备

  void Play(HWND hWnd); //播放MCI,hWnd为回调窗心句柄

  void Close(void); //启闭设备

  void Stop(void); //停止设备

  void Pause(void); //停息设备

  DWORD Query(); //检测设备

  };

  ////////////////////////////////////////////////// ///////

  // COMMCI.CPP 中操做到的挨算

  ////////////////////////////////////////////////// ///////

  //typedef struct tagMCI_OPEN_PARMS {

  // DWORD dwCallback;

  // MCIDEVICEID wDeviceID;

  // WORD wReserved0;

  // LPCSTR lpstrDeviceType;

  // LPCSTR lpstrElementName;

  // LPCSTR lpstrAlias;

  //} MCI_OPEN_PARMS, FAR *LPMCI_OPEN_PARMS;

  //typedef struct tagMCI_PLAY_PARMS {

  // DWORD dwCallback;

  // DWORD dwFrom;

  // DWORD dwTo;

  //} MCI_PLAY_PARMS, *PMCI_PLAY_PARMS, FAR *LPMCI_PLAY_PARMS;

  //typedef struct tagMCI_STATUS_PARMS {

  // DWORD dwCallback;

  // DWORD dwReturn;

  // DWORD dwItem;

  // DWORD dwTrack;

  //} MCI_STATUS_PARMS, *PMCI_STATUS_PARMS,

  FAR * LPMCI_STATUS_PARMS;

  ////////////////////////////////////////////////// ////////

  // mci 初初化格式

  ////////////////////////////////////////////////// ////////

  //COMMCI.Open("waveaudio",filename); wave ; *.wav ,

  //COMMCI.Open("sequencer",filename); midi ; *.mid , *.rmi

  //COMMCI.Open("reelmagic",filename); vcd ; *.mpg ,

  //COMMCI.Open("avivideo",filename); avi ; *.avi ,

  ////////////////////////////////////////////////// ///////

  // mci 自遇返回值

  ////////////////////////////////////////////////// ///////

  // case MCI_MODE_NOT_READY:

  // case MCI_MODE_STOP:

  // case MCI_MODE_PLAY:

  // case MCI_MODE_RECORD:

  // case MCI_MODE_SEEK:

  // case MCI_MODE_PAUSE:

  // case MCI_MODE_OPEN:

  #endif // !defined(AFX_COMMCI_H__90CEFD04_CC96_11D1_94F8_000 0B431BBA1__INCLUDED_)

  // commci.cpp: implementation of the commci class.

  //

  ////////////////////////////////////////////////// ////////////////////

  #include "stdafx.h"

  //#include "mcitest.h"

  #include "commci.h"

  #ifdef _DEBUG

  #undef THIS_FILE

  static char THIS_FILE[]=__FILE__;

  #define new DEBUG_NEW

  #endif

  ////////////////////////////////////////////////// ////////////////////

  // Construction/Destruction

  ////////////////////////////////////////////////// ////////////////////

  COMMCI::COMMCI()

  {

  memset(this,0,sizeof(COMMCI));

  }

  MCIERROR COMMCI::Open(LPCSTR DeviceType,LPCSTR filename)

  {

  //假定有挨开的设备便启闭

  if (mciOpen.wDeviceID) Close();

  //初初化MCI_OPEN_PARMS挨算

  mciOpen.lpstrDeviceType=DeviceType;

  mciOpen.lpstrElementName=filename;

  //除挨开设备设备代码为0,上里的任何mciSendCommand语句皆要指定设

  //备代码。

  if ( mciSendCommand(NULL,MCI_OPEN,

  MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,

  (DWORD)&mciOpen))

  return FALSE;

  return TRUE;

  }

  MCIERROR COMMCI::Open(LPCSTR filename)

  {

  if (mciOpen.wDeviceID) Close();

  mciOpen.lpstrElementName=filename;

  if ( mciSendCommand(NULL,MCI_OPEN,

   MCI_OPEN_ELEMENT,

  (DWORD)&mciOpen))

  return FALSE;

  return TRUE;

  }

  MCIERROR COMMCI::Open(int DeviceType,LPCSTR filename)

  {

  if (mciOpen.wDeviceID) Close();

  mciOpen.lpstrDeviceType=(LPCSTR)DeviceType;

  mciOpen.lpstrElementName=filename;

  return mciSendCommand(NULL,MCI_OPEN,

  MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID ,(DWORD)&mciOpen);

  }

  void COMMCI::Play(HWND hWnd)

  {

  MCI_PLAY_PARMS mciPlay;

  hOwer=hWnd; //回调窗心句柄

  //MCI_PLAY_PARMS挨算只需供设定回调窗心句柄

  mciPlay.dwCallback=(WORD)hOwer;

  mciSendCommand(mciOpen.wDeviceID,MCI_PLAY,MCI_NOTI FY,

  (DWORD)&mciPlay);

  }

  void COMMCI::Close(void)

  {

  if (mciOpen.wDeviceID)

  mciSendCommand(mciOpen.wDeviceID,MCI_CLOSE,NULL,NU LL);

  memset(this,0,sizeof(COMMCI));

  }

  void COMMCI::Stop(void)

  {

  if (mciOpen.wDeviceID)

  mciSendCommand(mciOpen.wDeviceID,MCI_STOP,NULL,NUL L);

  }

  void COMMCI::Pause(void)

  {

  if (mciOpen.wDeviceID)

  mciSendCommand(mciOpen.wDeviceID,MCI_PAUSE,NULL,NU LL);

  }

  DWORD COMMCI::Query()

  {

  MCI_STATUS_PARMS mciStatus;

  mciStatus.dwItem=MCI_STATUS_MODE;

  mciSendCommand(mciOpen.wDeviceID,MCI_STATUS,

  MCI_STATUS_ITEM,(LPARAM)&mciStatus);

  return mciStatus.dwReturn;

没有评论:

发表评论