Windows声音播放:MciSendCommand 用法详解

参考:https://blog.csdn.net/dnfyg_000/article/details/8511645

 

MciSendCommand 命令格式:

MCIERROR mciSendCommand(
         MCIDEVICEID IDDevice, //接受命令的设备ID,由 MCI_OPEN 命令的wDeviceID变量返回
          UINT uMsg,            //MCI 命令
          DWORD fdwCommand,     //flags 列表区,一般都与 DWORD dwParam 中的相关成员配合使用
         (DWORD)(相应MCI命令的参数区类型) dwParam 
                        );
返回的值:
返回 0 表示成功,否则为出错代码.

MCI 命令列表:

MCI_BREAK 设置中断键,缺省是”CTRL+BREAK"。
下面是MCI_BREAK 命令第四个参数dwParam的结构:(其它各命令用相同格式说明)
typedef struct { DWORD dwCallback; //低字指定一个窗口句柄,与 MCI_NOTIFY 有关 (处理命令完成后的相应动作)
int nVirtKey; //键码 (相关flag:MCI_BREAK_KEY )
HWND hwndBreak; //窗口句柄 (相关flag:MCI_BREAK_HWND )
} MCI_BREAK_PARMS;
flags:MCI_BREAK_OFF 关闭中断键
MCI_CAPTURE 抓取当前帧并存入指定文件,仅用于数字视频
typedef struct {
DWORD dwCallback; 
LPSTR lpstrFileName; //存入指定文件的全路径
RECT rc; //抓取的矩形区域
} MCI_DGV_CAPTURE_PARMS;
[注] typedef struct _RECT { 
LONG left; 
LONG top; 
LONG right; 
LONG bottom; 
} RECT;
MCI_CLOSE 关闭设备 用于所有设备,没有什么要特别说明的
typedef struct {
DWORD dwCallback; 
} MCI_GENERIC_PARMS;
MCI_CONFIGURE 弹出配置对话框,仅用于数字视频(Digital-video)
MCI_COPY 拷贝数据至剪贴板 仅用于数字视频
typedef struct {
DWORD dwCallback; 
DWORD dwFrom; //复制起点
DWORD dwTo; //复制终点
RECT rc; //(相关flag:MCI_DGV_COPY_AT )
DWORD dwAudioStream; 
DWORD dwVideoStream; 
} MCI_DGV_COPY_PARMS;



MCI_FROM 
MCI_TO 
MCI_DGV_COPY_AT 不使用此flag,将复制完整帧 
MCI_DGV_COPY_AUDIO_STREAM (缺省是这两个STRAM都不指定)
MCI_DGV_COPY_VIDEO_STREAM (但如果你使用一般只用其中一个)
MCI_CUE 延时播放或录音 用于Digital-video, VCR, 和 waveform-audio
MCI_CUT 删除数据 ,并将数据复制到剪贴板 用于Digital-video
MCI_DELETE 将文件中的数据删除 用于 Digital-video 和 waveform-audio
MCI_ESCAPE 直接向设备发送一个串 仅用于激光视频
MCI_FREEZE 将显示定格 Digital-video, video-overlay, and VCR devices
MCI_GETDEVCAPS 获取设备信息 用于所有设备
typedef struct {
DWORD dwCallback; 
DWORD dwReturn; 
DWORD dwItem; 
} MCI_GETDEVCAPS_PARMS;
MCI_INDEX 当前屏幕显示与否, 仅用于VCR设备
MCI_INFO 获取设备字符串信息
typedef struct {
DWORD dwCallback; 
LPSTR lpstrReturn; //根据相应的flags返回信息串
DWORD dwRetSize; //返回信息串大小(bytes)
} MCI_INFO_PARMS;
MCI_INFO_PRODUCT 设备的硬件信息 用于所有设备

用于cdaudio的flags : 
MCI_INFO_MEDIA_IDENTITY 
MCI_INFO_MEDIA_UPC 
产品通用代码 (UPC) ,不一定使用于所有CD 。
MCI_LIST 获取输入设备数量,支持数字视频和VCR设备
MCI_LOAD 装入一个文件 Digital-video and video-overlay
MCI_MARK 取消或做一个记号,供MCI_SEEK快速定位 VCR devices
MCI_MONITOR 为数字视频指定报告设备
typedef struct {
DWORD dwCallback;
DWORD dwSource; 
DWORD dwMethod; 
} MCI_DGV_MONITOR_PARMS;
MCI_OPEN 打开设备 All devices (详见后面的介绍)
typedef struct {
DWORD dwCallback; 
MCIDEVICEID wDeviceID; 
LPCSTR lpstrDeviceType; 
LPCSTR lpstrElementName; 
LPCSTR lpstrAlias; 
} MCI_OPEN_PARMS;
MCI_PASTE 粘帖数据 仅用于数字视频
MCI_PAUSE 暂停当前动作
typedef struct {
DWORD dwCallback; 
} MCI_GENERIC_PARMS;
MCI_PLAY 播放
MCI_PUT 设置源、目的和边框矩形 Digital-video and video-overlay
MCI_QUALITY 定义设备缺省质量
typedef struct {
DWORD dwCallback; 
DWORD dwItem; 
LPSTR lpstrName; 
DWORD lpstrAlgorithm; 
DWORD dwHandle; 
} MCI_DGV_QUALITY_PARMS;
MCI_RECORD 开始录制 VCR and waveform-audio (详见后面的介绍)
typedef struct {
DWORD dwCallback; 
DWORD dwFrom; 
DWORD dwTo; 
} MCI_RECORD_PARMS;
MCI_RESERVE 为后面的记录分配相对连续的硬盘空间 Digital-video
MCI_RESTORE 拷贝一个bmp文件至帧缓冲 Digital-video
typedef struct {
DWORD dwCallback; 
DWORD lpstrFileName; 
RECT rc; 
} MCI_DGV_RESTORE_PARMS;
MCI_RESUME 使一个暂停设备重新启动 Digital-video, VCR, and waveform-audio
MCI_SAVE 保存数据 Video-overlay and waveform-audio (详见后面的介绍)
MCI_SEEK 更改媒体位置 (详见后面的介绍)
typedef struct {
DWORD dwCallback; 
DWORD dwTo; 
} MCI_SEEK_PARMS;
MCI_SET 设置设备信息 (详见后面的介绍)
typedef struct {
DWORD dwCallback; 
DWORD dwTimeFormat; 
DWORD dwAudio; 
} MCI_SET_PARMS;
MCI_SETAUDIO 设置视频设备中的 audio 播放和捕捉的相关参数 用于Digital-video and VCR
MCI_SETTIMECODE 启用或取消VCR设备的时间码 用于 VCR
MCI_SETTUNER 设置VCR设备频道
MCI_SETVIDEO 设置video参数 用于Digital-video and VCR
MCI_SIGNAL 在工作区上设置指定空间 用于Digital-video,
typedef struct {
DWORD dwCallback; 
DWORD dwPosition; //Position to be marked. 
DWORD dwPeriod; //Interval of the position marks. 
DWORD dwUserParm; //User value associated with signals. 
} MCI_DGV_SIGNAL_PARMS;
MCI_STATUS 获取设备当前的相关状态信息 用于All devices(详见后面的介绍)
ttypedef struct {
DWORD dwCallback; 
DWORD dwReturn; 
DWORD dwItem; 
DWORD dwTrack; 
} MCI_STATUS_PARMS;
MCI_STEP 使播放设备跳帧 Digital-video, VCR, and CAV-format videodisc
MCI_STOP 停止播放和录音 CD audio, digital-video, MIDI sequencer, videodisc, VCR, and waveform-audio
MCI_SYSINFO 返回MCI设备信息 
typedef struct {
DWORD dwCallback; 
LPSTR lpstrReturn; 
DWORD dwRetSize; 
DWORD dwNumber; 
UINT wDeviceType; 
} MCI_SYSINFO_PARMS;
MCI_UNDO 取消操作 如新近操作MCI_CUT, MCI_COPY, MCI_DELETE, or MCI_PASTE 等 用于Digital-video devices
MCI_UNFREEZE 让使用MCI_UNFREEZE的视频缓冲区恢复运动 Digital-video, VCR, and video-overlay
MCI_UPDATE 更新显示区域 Digital-video devices
MCI_WHERE 获取设备裁减矩形 Digital-video, and video-overlay devices
MCI_WINDOW 指定图形设备窗口和窗口特性 用于 Digital-video, and video-overlay devices
For digital-video devices:
typedef struct {
DWORD dwCallback; 
WORD hWnd; 
WORD nCmdShow; 
LPSTR lpstrText; 
} MCI_DGV_WINDOW_PARMS;

 

其中比较常用的指令有MCI_OPEN、MCI_CLOSE、MCI_PLAY、MCI_STOP、MCI_PAUSE、MCI_STATUS等等。

--MciSendCommand 命令格式:
发送命令消息到指定的 MCI device.

MCIERROR mciSendCommand(
         MCIDEVICEID IDDevice, //接受命令的设备ID,由 MCI_OPEN 命令的wDeviceID变量返回
          UINT uMsg,            //MCI 命令
          DWORD fdwCommand,     //flags 列表区,一般都与 DWORD dwParam 中的相关成员配合使用
         (DWORD)(相应MCI命令的参数区类型) dwParam 
                        );
返回的值:
返回 0 表示成功,否则为出错代码.

参数:

IDDevice 
MCI device的标识符。
(此参数不被 MCI_OPEN 命令消息所使用,被置为null) 
此参数IDDevice指定了设备标识,这个标识会在程序员使用MCI_OPEN打开MCI设备时由系统提供,保存在 MCI_OPEN_PARMS结构的wDeviceID变量中。

uMsg 
命令消息(Command message). 
第二个参数指定将如何控制设备,详细请查阅上面“MCI指令”列表

fdwCommand 
Flags for the command message. 
第三个参数为访问标识(flags)在后面有详细说明。

dwParam 
第四个参数一般是一个数据结构,程序在使用mciSendCommand命令访问MCI时需要的或者是返回的一些信息。

返回的值:
返回 0 表示成功,否则为出错代码.
mciSendCommand 返回的值是一个双字,其中低字中包含 出错代码。如果是出错是由 可识别的设备 引起的,那么在高字中返回该设备的 标识符ID(the driver identifier),否则高字中为零(0). 可以通过查看MCIERR Return Values 相关内容判断出错原因。

* 使用 MCI_OPEN 得到当前打开设备的ID(保存在 MCI_OPEN_PARMS结构的wDeviceID变量中). 

环境要求:
Windows NT: V3.1 以上.
Windows: Windows 95 以上.
Windows CE: 不支持.
头文件包含: mmsystem.h.
函数库: winmm.lib.
支持 Unicode(双字节编码)和 ANSI 编码.

* 现在我们通过 MCI_OPEN 命令的使用来熟悉 mciSendCommand 命令。

--MCI_OPEN

MCI_OPEN 命令可以被所有设备识别。它可以用来初始化一个设备或者是一个文件。

命令格式:
MCIERROR mciSendCommand( MCIDEVICEID wDeviceID, 
                         MCI_OPEN, 
                         DWORD dwFlags, 
                         (DWORD) (LPMCI_OPEN_PARMS) lpOpen); 
『例』
////////////////////////////////////////////////////////////////////////
/*
* 函数名称:MCI_Open
* 函数介绍:用mci命令打开文件
* 输入参数:CString strPath, 文件的路径
* 输出参数:无
* 返回值 :mci命令的错误信息
*/
DWORD MCIMP3::MCIOpen(const CString &strPath)
{
  MCI_OPEN_PARMS mciOP;
  DWORD dwReturn;

  ASSERT(m_wID == NULL); // m_wID保存将打开设备的 ID
  //由mci判断文件类型
  mciOP.lpstrDeviceType=NULL;
  mciOP.lpstrElementName=strPath;
  dwReturn=mciSendCommand( 
           NULL, //指定设备标识,MCI_OPEN此处为NULL,
               //成功OPEN后,标识放入MCI_OPEN_PARMS结构的wDeviceID变量中
            MCI_OPEN, 
           MCI_OPEN_ELEMENT | MCI_WAIT | MCI_OPEN_SHAREABLE,
          (DWORD)(LPVOID)&mciOP);

  if (dwReturn==0) //成功打开文件,将对应的设备ID 送m_wID 以供其他命令引用,
      m_wID=mciOP.wDeviceID;
  else
      m_wID=NULL;

return dwReturn;
}

上例说明:
---- MCI_OPEN_PARMS (对应MCI_OPEN命令格式 中的第4个参数)
在这个结构中,我们给相应的成员变量赋值,为使用 MCI_OPEN 做好准备;
如:mciOP.lpstrDeviceType=NULL; //由mci判断文件类型

当我们给MCI_OPEN_PARMS 中某些成员赋值,并同时在fdwCommand 参数区指定了相应的 标志(flags),那么该 成员所赋值在此次mciSendCommand命令中生效。
例如上例:
fdwCommand 参数 对应引用 MCI_OPEN_PARMS 的成员
MCI_OPEN_ELEMENT mciOP.lpstrElementName=strPath 待打开的文件

MCI_OPEN_PARMS 结构:
typedef struct {
        DWORD dwCallback; 
        MCIDEVICEID wDeviceID; 
        LPCSTR lpstrDeviceType; 
        LPCSTR lpstrElementName; 
        LPCSTR lpstrAlias; 
} MCI_OPEN_PARMS; 

[注] 对于一些扩展的命令设置[我们可以通过程序中fdwCommand 参数区指定的相应标志(flags)明白它是来控制什么类型的设备,从而做出正确的操作动作] 系统会用设备特殊的“数据结构”来代替上面这个常用的结构。

     例如:for waveform-audio devices: 
         typedef struct {
             DWORD dwCallback; 
             MCIDEVICEID wDeviceID; 
             LPCSTR lpstrDeviceType; 
             LPCSTR lpstrElementName; 
             LPCSTR lpstrAlias; 
             DWORD dwBufferSeconds; 
         } MCI_WAVE_OPEN_PARMS;

MCI_OPEN_PARMS 结构 成员说明:

dwCallback 
 低位字为 MCI_NOTIFY flag 指定一个窗口句柄. 

wDeviceID 
 为成功打开的文件返回 设备标识符. 
(上例:// MCI_OPEN 命令中的这个参数(第一个参数)一定为NULL,成功OPEN后,
标识放入MCI_OPEN_PARMS结构的wDeviceID变量mciOP.wDeviceID中)

lpstrDeviceType 
 设备类型的名字或常量标识. (设备名可以从注册表或者 SYSTEM.INI 文件中获得) 

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将自动根据文件扩展名识别设备类型。(如上例:mciOP.lpstrDeviceType=NULL)



lpstrElementName 
 设备元素 (通常是打开的文件全路径). 

lpstrAlias 
 可选别名. 

--The Wait, Notify 两个通用的 fdwCommand 参数

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/mci_3353.asp

在多数的 MCI 命令中都会有fdwCommand 参数区(如上例MCI_OPEN命令,第三个参数:” MCI_OPEN_ELEMENT | MCI_WAIT | MCI_OPEN_SHAREABLE”),而且对于不同的命令有不同的falgs 。但有这样两个falg参数,对于所有mciSendCommand命令都适用:
(The "wait" (MCI_WAIT) and "notify" (MCI_NOTIFY) flags)

――The Wait Flag

MCI 命令在执行时一般会立即返回执行结果,即使有些命令执行要花上几分钟才能完成。
你可以使用 "wait" (MCI_WAIT) flag 来指定设备等待,直到请求命令完成再返回到应用程序控制。

比如:下面使用mciSendString来发送一个 play 命令,执行play直到 palyback 完成后才返回应用程序。
mciSendString("play mydevice from 0 to 100 wait", 
lpszReturnString, lstrlen(lpszReturnString), NULL);
注:用户可以使用 a break key 来终止 wait ,缺省的break key是: CTRL+BREAK. 你也可以使用MCI_BREAK 命令重新定义这个功能键 (MCI_BREAK 使用 MCI_BREAK_PARMS 结构) 

在我们的例子中也使用到了这个参数,目的是为了在没有完成OPEN(可能正在打开文件)操作的过程中不会将控制权交由应用程序,避免“人为”的干扰;实际上这个时间一般持续的相当短暂,以至于你根本无法察觉的到(除非你的设备或文件有问题?)。

――The Notify Flag

The "notify" (MCI_NOTIFY) flag 指示设备完成一次操作后 (邮寄)post 一个 MM_MCINOTIFY 信息。 我们可以在MM_MCINOTIFY 的处理函数来做一些相应的处理工作: 是否completed successfully, failed, or was superseded or aborted 等等。


――The Test Flag
The "test" (MCI_TEST) flag 测试设备此时是否能执行命令. 如果可以执行,设备返回一个 无错 信息。

MCI_TEST flag 支持 digital-video and VCR devices 所有命令,但在 open (MCI_OPEN) and close (MCI_CLOSE)中不能使用.


--MCI_OPEN fdwCommand 参数区 中可用的flags 

对应与不同的设备有如下分类:

* MCI_OPEN 通用的flags 参数表(所有设备均可用): 

MCI_OPEN_ALIAS 
对应 MCI_OPEN_PARMS结构中的 LPCSTR lpstrAlias 成员变量,为打开的设备起个别名。
MCI_OPEN_SHAREABLE 
将设备或文件以共享的方式打开。 

MCI_OPEN_TYPE 
对应 MCI_OPEN_PARMS结构中的 LPCSTR lpstrDeviceType 成员变量,设备类型的名字或常量标识. (设备名可以从注册表或者 SYSTEM.INI 文件中获得) 

MCI_OPEN_TYPE_ID 
和 MCI_OPEN_TYPE flag 一起使用后,我们可以在 MCI_OPEN_PARMS结构中的 lpstrDeviceType 成员变量的低字中得到一个标准的MCI 设备的类型ID,同时在高字中指出该设备ID 此时在系统里的顺序索引号。 

MCI_OPEN为compound devices提供的flags 控制参数: 

MCI_OPEN_ELEMENT 
对应 MCI_OPEN_PARMS结构中的 LPCSTR lpstrElementName 成员变量,设备元素 (通常是打开的文件全路径). 

MCI_OPEN_ELEMENT_ID 
和 MCI_OPEN_ELEMENT flag 一起使用后,我们可以将 MCI_OPEN_PARMS结构中的 lpstrElementName 成员变量看成是一个doubleword value,表示一个内部的设备。 

* MCI_OPEN为digitalvideo (数字视频)提供的flags 控制参数:

MCI_DGV_OPEN_NOSTATIC 

MCI_DGV_OPEN_PARENT 

MCI_DGV_OPEN_WS 

MCI_DGV_OPEN_16BIT 

MCI_DGV_OPEN_32BIT 
the lpOpen parameter points to an MCI_DGV_OPEN_PARMS structure:

   typedef struct {
           DWORD dwCallback; 
           UINT wDeviceID; 
           LPSTR lpstrDeviceType; 
           LPSTR lpstrElementName; 
           LPSTR lpstrAlias; 
           DWORD dwStyle; 
           HWND hWndParent; 
   } MCI_DGV_OPEN_PARMS;



* 下面的flags 控制参数用于 the overlay device type(重叠视频): 

MCI_OVLY_OPEN_PARENT 

MCI_OVLY_OPEN_WS 
the lpOpen parameter points to an MCI_OVLY_OPEN_PARMS structure:

    typedef struct {
      DWORD dwCallback; 
      MCIDEVICEID wDeviceID; 
      LPCSTR lpstrDeviceType; 
      LPCSTR lpstrElementName; 
      LPCSTR lpstrAlias; 
      DWORD dwStyle; 
      DWORD hWndParent; 
    } MCI_OVLY_OPEN_PARMS;

* 下面的flags 控制参数用于the waveaudio device type:
(音频设备MCI_DEVTYPE_WAVEFORM_AUDIO) 

MCI_WAVE_OPEN_BUFFER 
对应 MCI_WAVE_OPEN_PARMS (替代了MCI_OPEN_PARMS)结构中的 DWORD dwBufferSeconds 成员变量,用来设置读写音频的数据缓冲长度。

  for waveform-audio devices: 
    typedef struct {
             DWORD dwCallback; 
             MCIDEVICEID wDeviceID; 
             LPCSTR lpstrDeviceType; 
             LPCSTR lpstrElementName; 
             LPCSTR lpstrAlias; 
             DWORD dwBufferSeconds; //数据缓冲的长度
     } MCI_WAVE_OPEN_PARMS;

小结:

1. 通过对 MCI_OPEN 细致分析,我们基本了解了如何利用MciSendCommand 命令来正确的控制MCI 设备了;下面我们所要掌握的就是各个 MCI 命令的格式及相关参数的使用了。
2. 在这些MCI 命令的使用中,我的经验是主要是要掌握每个命令“参数表”的数据结构(如:MCI_OPEN 的 MCI_OPEN_PARMS 结构中各成员的含义)及 fdwCommand 参数区(如上例MCI_OPEN命令,第三个参数:” MCI_OPEN_ELEMENT | MCI_WAIT | MCI_OPEN_SHAREABLE”)中各标志(falgs)的正确含义。
3. 在学习的过程中,最好的在线老师就是微软提供的MSDN.说明的非常详尽,如果你觉得还是不够的话,那么你不妨直接到微软MSDN 的网站上去看看吧。

有了上面的知识基础,相信再理解以后的 MCI 命令不会有什么大问题的。

--MCI_OPEN 使用2 :为录音打开一个空文件(wav文件)

BOOL CWaveAudio::Record (void)
{
   Close ();//为成功打开设备,录制前关闭一次设备

   MCI_OPEN_PARMS OpenParms;
   OpenParms.lpstrDeviceType = "waveaudio";
   OpenParms.lpstrElementName = "";
   if (::mciSendCommand (NULL, 
                         MCI_OPEN, 
                         MCI_OPEN_ELEMENT | MCI_OPEN_TYPE 
                         | MCI_WAIT, 
                         (DWORD)(LPVOID) &OpenParms))
       return FALSE; //打开设备失败
   m_wDeviceID = OpenParms.wDeviceID;//打开设备成功,保存设备ID

   MCI_RECORD_PARMS RecordParms;
   if (mciSendCommand (m_wDeviceID, 
                       MCI_RECORD, 
                       NULL, 
                       (DWORD)(LPVOID) &RecordParms))
       return FALSE;

   //开始录音,设置程序相应标志
   m_bRecording = TRUE;
   m_bOpened = TRUE;
   return TRUE;
}

--MCI_SAVE

MCI_SAVE 命令保存当前文件。在保存文件操作之前,设备可以修改当前打开的文件,但不会影响到原来保存在磁盘上的原文件。
Video-overlay(覆盖视频) 和 waveform-audio 设备可以正确识别该命令。

[例]
BOOL CWaveAudio::Save (CString Filename)
{
	if (!m_bRecording)
		return FALSE;

	Stop ();
	MCI_SAVE_PARMS SaveParms;
	SaveParms.lpfilename = (LPCSTR) Filename;
	if (mciSendCommand (m_wDeviceID, 
                            MCI_SAVE, 
                            MCI_SAVE_FILE | MCI_WAIT, 
                            (DWORD)(LPVOID) &SaveParms))
		return FALSE;

	m_bRecording = FALSE;
	Load (Filename);
	return TRUE;
}
MCIERROR mciSendCommand(
  MCIDEVICEID wDeviceID, 
  MCI_SAVE, 
  DWORD dwFlags, 
  (DWORD) (LPMCI_SAVE_PARMS ) lpSave
);

lpSave:

typedef struct {
     DWORD_PTR dwCallback; 
     LPCSTR lpfilename; 
} MCI_SAVE_PARMS;

dwFlags:

 MCI_SAVE_FILE  应用于所有设备。lpSave结构中 lpfilename 成员指出存盘目标文件名。

 

--MCI_PLAY

不用多说它是用来做什么的。
CD audio, digital-video, MIDI sequencer, videodisc, VCR, waveform-audio devices 均可识别该命令.

『例』
////////////////////////////////////////////////////////////////////////
/*
* 函数名称:MCIPlay
* 函数介绍:用mci命令播放已打开(当前)的MP3文件
* 输入参数:无
* 输出参数:无
* 返回值 :mci命令的错误信息
*/
DWORD MCIMP3::MCIPlay()
{
MCI_PLAY_PARMS mciPP;

//mciPP.dwCallback=(DWORD)GetSafeHwnd();
return mciSendCommand(m_wID, MCI_PLAY, MCI_NOTIFY,
(DWORD)(LPVOID)&mciPP);
}
格式:
MCIERROR mciSendCommand(MCIDEVICEID wDeviceID, 
                        MCI_PLAY, 
                        DWORD dwFlags, 
                        (DWORD) (LPMCI_PLAY_PARMS ) lpPlay);

参数:

wDeviceID 
接受播放的MCI设备的ID,在MCI_OPEN 成功执行后得到该设备的ID. 

dwFlags 
MCI_NOTIFY, MCI_WAIT, digital-video 和 VCR 设备还可用 MCI_TEST. 

lpPlay

MCI_PLAY_PARMS 结构的地址. (扩展的命令中可能用设备指定的结构所代替) 

typedef struct {
        DWORD dwCallback; 
        DWORD dwFrom; 
        DWORD dwTo; 
} MCI_PLAY_PARMS;

LPMCI_PLAY_PARMS 成员:

dwCallback 
低位字为 MCI_NOTIFY flag 指定一个窗口句柄.

dwFrom 播放起始点. 

dwTo 播放结束点.

备注:

如果使用了成员函数,必须设置相应的fdwCommand 参数区的标志(flags). 
两个常用的flags是:
MCI_FROM :让MCI_PLAY 使用上面结构中dwFrom 。
可以使用 MCI_SET 命令的MCI_SET_TIME_FORMAT flag设定时间格式。
缺省播放会从当前位置开始。
MCI_TO : 用法和MCI_FROM 相同,播放结束于dwTo 。
缺省停止位置是 媒体结束。
当然还有对视频等设备起作用的flags ,这里不再详述。

返回:

0 表示成功。

--MCI_RECORD

  从当前位置开始或在一个指定区段中录音。Video-overlay(覆盖视频) 和 waveform-audio 设备可以正确识别该命令。

[例]见MCI_OPEN 使用2 :为录音打开一个空文件(wav文件)
MCIERROR mciSendCommand(
         MCIDEVICEID wDeviceID, 
         MCI_RECORD, 
         DWORD dwFlags, 
         (DWORD) (LPMCI_RECORD_PARMS) lpRecord
);

lpRecord:

typedef struct {
        DWORD_PTR dwCallback; 
        DWORD dwFrom; 
        DWORD dwTo; 
} MCI_RECORD_PARMS;

 dwFrom ,dwTo   区段起止位置(必须和dwFlags中的MCI_FROM、MCI_TO 配合使用)

dwFlags:

 MCI_FROM |MCI_TO  
   使lpRecord中的 dwFrom ,dwTo 起作用。如果没有使用这两个flags,MCI_RECORD 缺省的起始录音位置是当前位置;缺省的结束位置:你啥时候罗嗦完就算结束了:)
   使用的时间(或帧)长度格式由MCI_SET命令的MCI_SET_TIME_FORMAT 标志(flag)来设定。

 MCI_RECORD_INSERT 
   最新的录音会被插入或粘贴到当前的wave文件中。这是MCI_RECORD命令缺省设置,但有些设备可能不支持此flag.

MCI_RECORD_OVERWRITE 
最新录音将覆盖现存打开的文件。MCIWAVE.DRV 设备返回MCIERR_UNSUPPORTED_FUNCTION 响应这个flag.

 支持 digitalvideo 设备的flags 这里不做介绍。

--MCI_SET

  设置设备信息(设置时间格式及播放速度等 )。CD audio, digital-video, MIDI sequencer, VCR, videodisc, video-overlay, 和 waveform-audio 设备可正确识别该命令。

[例]设置时间格式及播放速度 
MCI_SET_PARMS SetParms;
SetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS; //设置时间单位为毫秒
mciSendCommand (m_wDeviceID, 
                MCI_SET, 
                MCI_SET_TIME_FORMAT, 
                (DWORD)(LPVOID) &SetParms);

MCI_SEQ_SET_TEMPO 设置播放速度,
PQRN类型,此值为节拍/分,
SMPTE类型,此值为祯/秒
MCIERROR mciSendCommand(MCIDEVICEID wDeviceID, 
                        MCI_SET, 
                        DWORD dwFlags, 
                        (DWORD) (LPMCI_SET_PARMS) lpSet);

lpSet:

typedef struct {
        DWORD dwCallback; 
        DWORD dwTimeFormat; 
        DWORD dwAudio; 
} MCI_SET_PARMS;

dwTimeFormat  设置时间格式 (相关flag: MCI_SET_TIME_FORMAT )
 时间格式常量:
 MCI_FORMAT_BYTES                比特 (使用 脉冲编码调制[PCM]格式的waveaudio 类型文件)   
 MCI_FORMAT_MILLISECONDS         设置时间单位为毫秒 
 MCI_FORMAT_MSF                  (分/秒/帧)Minute/second/frame 
 MCI_FORMAT_SAMPLES              采样 Samples 
  MCI_FORMAT_SMPTE_24             SMPTE(电影与电视工程师学会[美]), 24 帧 
  MCI_FORMAT_SMPTE_25             SMPTE, 25 帧
  MCI_FORMAT_SMPTE_30             SMPTE, 30 帧
  MCI_FORMAT_SMPTE_30DROP         SMPTE, 30 frame drop 
 MCI_FORMAT_TMSF                 Track/minute/second/frame 
 MCI_SEQ_FORMAT_SONGPTR          MIDI song pointer

dwAudio 
 音频输出声道编号. (相关flag: MCI_SET_AUDIO )

备注:
 MCI_SET_PARMS 成员赋值 要必须要使用相应的 dwFlags.

对于 waveform-audio 设备, lpSet 指针将指向 MCI_WAVE_SET_PARMS 结构:

typedef struct {
        DWORD dwCallback; 
        DWORD dwTimeFormat; 
        DWORD dwAudio; 
        UINT wInput; 
        UINT wOutput; 
        WORD wFormatTag; 
        WORD wReserved2; 
        WORD nChannels; 
        WORD wReserved3; 
        DWORD nSamplesPerSec; 
        DWORD nAvgBytesPerSec; 
        WORD nBlockAlign; 
        WORD wReserved4; 
        WORD wBitsPerSample; 
        WORD wReserved5; 
} MCI_WAVE_SET_PARMS;

下面waveform-audio的属性要在录音(录制)前设定好,录音开始后将不能再被改变:
MCI_WAVE_SET_AVGBYTESPERSEC 
MCI_WAVE_SET_BITSPERSAMPLE 
MCI_WAVE_SET_BLOCKALIGN 
MCI_WAVE_SET_CHANNELS 
MCI_WAVE_SET_FORMATTAG 
MCI_WAVE_SET_SAMPLESPERSEC 

dwFlags:

  对所有设备作用的flags:

 MCI_SET_AUDIO  
    使 dwAudio 成员起作用。该flag必须配合MCI_SET_ON 或 MCI_SET_OFF使用。
    决定音频输出声道编号的flags有:
        MCI_SET_AUDIO_ALL     所有声道 
        MCI_SET_AUDIO_LEFT     左声道 
        MCI_SET_AUDIO_RIGHT      右声道

 MCI_SET_DOOR_CLOSED  关闭设备面版(一般用在CD设备)
 MCI_SET_DOOR_OPEN 
 MCI_SET_OFF  关闭指定 video or audio channel.
 MCI_SET_ON   
 MCI_SET_TIME_FORMAT  
  MCI_FORMAT_BYTES   by the waveaudio device type. 
  MCI_FORMAT_FRAMES  by the digitalvideo, vcr, and videodisc device types. 
  MCI_FORMAT_HMS  格式:时/分/秒 by the vcr and videodisc device types. 
  MCI_FORMAT_MILLISECONDS   by all device types. 
  MCI_FORMAT_MSF  by the cdaudio and vcr device types. 
  MCI_FORMAT_SAMPLES  转换时间格式为 samples,by the waveaudio device type. 
  MCI_FORMAT_SMPTE_24, MCI_FORMAT_SMPTE_25, and MCI_FORMAT_SMPTE_30 
                      by the sequencer and vcr device types. 
  MCI_FORMAT_SMPTE_30DROP     by the sequencer and vcr device types. 
  MCI_FORMAT_TMSF          by the cdaudio and vcr device types. 
 MCI_SET_VIDEO  
  与MCI_SET_ON or MCI_SET_OFF合用,设置视频信号(video signal)开关状态. 
   设备无视频功能返回 MCIERR_UNSUPPORTED_FUNCTION. 

--MCI_STATUS

查询设备当前的相关状态信息。所有设备都能争取识别该命令。返回的信息内容在lpStatus 结构dwReturn成员变量中。

[例]
MCI_STATUS_PARMS mciSP;

mciSP.dwItem=MCI_STATUS_MODE;
DWORD dwReturn=mciSendCommand(m_wID, 
                              MCI_STATUS, 
                              MCI_STATUS_ITEM,
                              (DWORD)(LPVOID)&mciSP);
if (dwReturn==(DWORD)0)
   if ( mciSP.dwReturn==MCI_MODE_OPEN ||
        mciSP.dwReturn==MCI_MODE_PLAY ||
        mciSP.dwReturn==MCI_MODE_PAUSE ||
        mciSP.dwReturn==MCI_MODE_STOP ||
        mciSP.dwReturn==MCI_MODE_SEEK
      ) return true;
MCIERROR mciSendCommand(MCIDEVICEID wDeviceID, 
                        MCI_STATUS, 
                        DWORD dwFlags, 
                        (DWORD) (LPMCI_STATUS_PARMS) lpStatus);

lpStatus:

typedef struct {
                DWORD dwCallback; 
                DWORD dwReturn; 
                DWORD dwItem; 
                DWORD dwTrack; 
               } MCI_STATUS_PARMS;

dwReturn  返回的信息内容
      如:   MCI_MODE_OPEN
           MCI_MODE_PLAY
           MCI_MODE_PAUSE
           MCI_MODE_STOP
           MCI_MODE_SEEK
 
dwItem  请求查询的内容
 
dwTrack 轨道的长度或数目 

备注:
 MCI_STATUS_ITEM flag 要和 dwItem 合用

备注:

MCI_STATUS_ITEM 用此flag来说明我们使用lpStatus结构的dwItem成员来指定 查询项目(status item )

下面的查询项目(status item)将由lpStatus 结构 中的 dwReturn 成员变量返回:

MCI_STATUS_CURRENT_TRACK 当前的轨道数到 dwReturn(MCI 使用连续轨道号)

MCI_STATUS_LENGTH 返回当前媒体(文件)的总长到 dwReturn

MCI_STATUS_MODE 返回设备当前的工作模式到 dwReturn,常量如下:
MCI_MODE_NOT_READY
MCI_MODE_PAUSE
MCI_MODE_PLAY
MCI_MODE_STOP
MCI_MODE_OPEN
MCI_MODE_RECORD
MCI_MODE_SEEK

MCI_STATUS_POSITION 获得文件播放的当前位置
MCI_STATUS_TIME_FORMAT 获得当前的时间格式
MCI_SEQ_STATUS_DIVTYPE 判断文件是PPQN类型还是SMPTE类型
MCI_SEQ_STATUS_TEMPO 获得当前播放速度:PQRN类型,此值为节拍/分;SMPTE类型,此值为祯/秒

MCI_STATUS命令所涉及到的 状态信息 实在太多,用到什么就去看看 MSDN 吧。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/mmcmd_9ycz.asp

--MCI_SEEK

改变当前播放位置跳到指定位置。在执行SEEK时,视频和音频的输出被禁止。SEEK完成后设备会处于停止状态。CD audio, digital-video, MIDI sequencer, VCR, videodisc, 和waveform-audio 设备可正确识别该命令。

[例]
DWORD MCIaudio::MCISeekTo(DWORD dwTo)
{
 DWORD dwReturn;

 if (dwTo>0 && dwTo=m_dwLength)
              dwReturn = MCISeekToEnd();
       else
              dwReturn = MCISeekToStart();
 return dwReturn;
}
命令格式:
MCIERROR mciSendCommand(MCIDEVICEID wDeviceID, 
                        MCI_SEEK, 
                        DWORD dwFlags, 
                        (DWORD) (LPMCI_SEEK_PARMS) lpSeek);

lpSeek:

typedef struct {
                DWORD dwCallback; 
                DWORD dwTo; 
               } MCI_SEEK_PARMS;

dwTo   跳转的位置  (相应的flag: MCI_TO)

dwFlags:

MCI_SEEK对所有设备都支持的flags: 

MCI_SEEK_TO_END 跳到文件尾

MCI_SEEK_TO_START 跳到文件头

MCI_TO 指定使用 lpSeek结构中的 dwTo 成员变量来说明跳转的位置。MCI_TO不能和 MCI_SEEK_TO_END 或 MCI_SEEK_TO_START一起使用。

使用于 vcr设备类型的flags:(VCR设备的lpSeek指向 MCI_VCR_SEEK_PARMS 结构 )
MCI_VCR_SEEK_AT 
MCI_VCR_SEEK_MARK 
MCI_VCR_SEEK_REVERSE 
MCI_VCR_SEEK_MARK

你可能感兴趣的:(windows,VC)