除了DirectShow,在VC下提供了两种播放多媒体的方法:MCI和MCIWnd
MCI就是:MCISendCommand及MCISendString
MCIWnd类可以直接注册使用
-------------------------------------------------------------------
视频领域是多煤体的一个重要方面。虽
然Microsoft很早就认识了这一点,但
Windows 3.X仍未提供对视频的内置支
持,Windows 3.X对视频的支持是通过
Video for windows(Vfw)得以实现的。在
Windows 95下,Video for windows不再是
一个独立的部分,它被集成进了Windows。
AVI(Audio Visual Interface)文件是用于
存储Windows视频信号的数据文件,本文
以一个AVI文件的播放程序为例,分别讨
论利用MCI和MCIWnd两种方法播放AVI
的程序设计。
一. 利用MCI播放AVI文件
媒体控制接口(Media Control Interface)
提供了对AVI的支持,利用MCI播放AVI
的方法既适用于Windows 3.X,也适用于
Windows 95。不同的是,在Windows 95下,
AVI设备驱动程序已被自动安装完毕,而在
Windows 3.X下,必须自己安装AVI设备驱
动程序。驱动程序文件名为MCIAVI.DRV,
将此驱动程序安装在\WINDOWS\SYSTEM
目录下,使用SYSTEM.INI文件来装载此驱
动程序,装载驱动程序的指令在
SYSTEM.INI文件的[MCI]段,如下所示∶
AVIVideo = mciavi.drv
如果安装了Video for windows,则以上驱动
程序会被自动安装。
播放AVI文件可以直接利用MCI函
数,有关利用MCI函数播放AVI的过程可
以参见例程。
例程 :
以下是一个AVI播放的例程,如图2
所示,该例程使用了MCI控制接口以及
MCIWnd两种方法播放AVI文件,该例程
在Windows 95下用Visual C++ 4.0通过。
图2 AVI播放例程
可按如下方法建立VIDEO例程∶
1. 利用AppWizard建立一Dialog工程
2. 在VIDEODLG.H中加入mmsystem.h和
vfw.h,link设置中加入库winmm.lib和
vfw32.lib。
3. 建立对话框模板,加入与按钮对应的变量
Cstring mCommandString;
Cstring mErrorString;
Cstring mReturnString;
4. 在VideoDlg.h中加入MCIWnd句柄声明
HWND mVideoWnd;
5. 利用ClassWizard加入消息处理函数框架
6. 加入如下的消息处理代码
void CVideoDlg::OnMciSendString()
{
DWORD mciError;
char reply[BUF_SIZE];
char mciErrorString[BUF_SIZE];
UpdateData(TRUE);
mciError = mciSendString(mCommandString,
reply,BUF_SIZE,NULL);
mciGetErrorString(mciError,mciErrorString,BU
F_SIZE);
mReturnString = reply;
mErrorString = mciErrorString;
UpdateData(FALSE);
}
void CVideoDlg::OnMciSendcommand()
{
MCI_OPEN_PARMS mciOpenParms;
MCI_PLAY_PARMS mciPlayParms;
int wDeviceID;
DWORD mciError;
char mciErrorString[BUF_SIZE];
UpdateData(TRUE);
mciOpenParms.dwCallback = 0L;
mciOpenParms.wDeviceID = 0;
mciOpenParms.lpstrDeviceType = "avivideo";
mciOpenParms.lpstrElementName=(LPCSTR)m
CommandString;
mciError = mciSendCommand(0,MCI_OPEN,
MCI_OPEN_TYPE|MCI_OPEN_ELEMENT,
(DWORD)(LPVOID)&mciOpenParms);
if (!mciError)
{
wDeviceID = mciOpenParms.wDeviceID;
mciPlayParms.dwCallback = (DWORD)this-
> m_hWnd;
mciError = mciSendCommand(wDeviceID,
MCI_PLAY,MCI_NOTIFY,(DWORD)(LPVOID)&
mciPlayParms);
}
mciGetErrorString(mciError,mciErrorString,BU
F_SIZE);
mErrorString = mciErrorString;
mReturnString = "";
UpdateData(FALSE);
return;
}
LONG CVideoDlg::OnMCINotify(UINT wParam,
LONG lParam)
{
DWORD mciError;
char mciErrorString[BUF_SIZE];
mciError= iSendCommand(LOWORD(lParam),
MCI_CLOSE,MCI_WAIT,NULL);
mciGetErrorString(mciError,mciErrorString,BU
F_SIZE);
mErrorString = mciErrorString;
UpdateData(FALSE);
return 0;
}
void CVideoDlg::OnOpenMciwnd()
{
if (mVideoWnd==NULL)
{
UpdateData(TRUE);
mVideoWnd = MCIWndCreate(this->m_hWnd,
AfxGetInstanceHandle(),WS_CAPTION|WS_V
ISIBLE|MCIWNDF_SHOWPOS|MCIWNDF_SHOW
NAME,(LPCSTR)mCommandString);
mErrorString = "";
mReturnString = "";
UpdateData(FALSE);
SetDlgItemText(IDC_OPENMCIWND,"Close
MCIWnd");
}
else
{
MCIWndDestroy(mVideoWnd);
mVideoWnd = NULL;
mErrorString = "";
mReturnString = "";
UpdateData(FALSE);
SetDlgItemText(IDC_OPENMCIWND,"Open
MCIWnd");
}
二.利用MCIWnd播放AVI文件
MCIWnd是Windows 95提供的基于
MCI的窗口类。注意这里的“类”的概念不
同于VC++的“类”,MCIWnd并不属于
MFC,因此不能从MCIWnd派生类。
一个MCIWnd窗口对象提供了可靠的
方法对媒体播放进行控制。图1是一个正在
播放AVI的MCIWnd,它包含了一个播放/
暂停按钮,一个菜单按钮以及一个进度标
尺。在窗口内击鼠标右键将出现一个浮动式
菜单,这个菜单与按菜单按钮获得的菜单是
一样的。
图1 播放AVI的MCIWnd
在VC++中利用MCIWnd进行编程,首
先应包含头文件VFW.H,并在Project
Setting下声明连接库VFW32.LIB。然后,
创建一个MCIWnd窗口∶
hWnd = MCIWndCreate(hwndParent,
hInstance,dwStyle,szFile);
其中,hwndParent为父窗口句柄(拥有
MCIWnd的窗口),hInstance是程序句柄(通
常可以利用AfxGetInstanceHandle()获得程
序句柄),dwStyle定义了MCIWnd的窗口类
型,szFile是供回放的MCI文件名,可以是
MCI支持的各种类型文件,可以为NULL。
MCIWndCreate()返回MCIWnd的窗口句
柄,用于其他MCI Wnd函数。
MCIWndCreate()与Windows API的
CreateWindow()有许多相似之处,
MCIWndCreate()同样可以在dwStyle中使用
WS_窗口类型常量,缺省为WS_CHILD|
WS_BORDER|WS_VISIBLE。另外,
MCIWndCreate()还可以使用MCIWNDF_常
量定义有关MCIWnd的类型,这些常量包
括∶
MCIWNDF_NOAUTOSIZEWINDOW
MCIWNDF_NOPLAYBAR
MCIWNDF_NOAUTOSIZEMOVIE
MCIWNDF_NOMENU
MCIWNDF_SHOWNAME
MCIWNDF_SHOWPOS
MCIWNDF_SHOWMODE
MCIWNDF_SHOWALL
MCI提供了两种方法对媒体播放进行
控制∶
? 利用MCIWnd窗口上的按钮或菜单
进行直接控制,这些控件提供了各种可能的
对媒体播放的控制;。
? 用户编制程序进行间接控制
MCIWnd API提供了许多函数(实际上
是宏)对媒体播放进行控制,所有这些函数
都使用创建时获取的HWND句柄作为参
数,返回一个long的值,0代表成功,其它
为错误码。一些常用的控制函数如下∶
MCIWndHome(hWnd) 至起始位置
MCIWndPause(hWnd) 暂停
MCIWndPlay(hWnd) 开始播放
MCIWndPlayFrom(hWnd,lPos) 从lPos播放
MCIWndPlayFromTo(hWnd,lStart,lEnd)
从lStart播到lEnd
MCIWndPlayTo(hWnd,lPos) 播放至lPos
MCIWndResume(hwnd) 暂停后继续
MCIWndSeek(hWnd,lPos) 寻道
MCIWndSetVolume(hWnd,iVol) 设置音量
MCIWndStop(hWnd) 停止播放
另外,MCIWnd还通过一些函数提供有
关MCIWnd的信息,这些信息与MCIWnd
所控制的MCI设备有关。这些函数有∶
? LRESULT MCIWndCanPlay(hWnd)
MCI设备能否播放数据
? LRESULT MCIWndCanEject(hWnd)
MCI设备是否具有“弹出”特性
? LONG MCIWndGetEnd(hWnd)
结束位置(对Video为,最后桢号)
? LONG MCIWndGetLength(hWnd)
长度(对Video为桢数)
? LONG MCIWndGetPosition(hWnd)
当前位置(对Video为桢号)
? LONG MCIWndGetVolumn(hWnd)
当前音量
? MCIWndClose(hWnd)
关闭MCI设备(并不关闭MCIWnd)
? MCIWndDdetroy(hWnd)
关闭MCIWnd
? MCIWndSendString(hWnd,sz)
向MCI设备发送sz命令