标题成绩:我念写法式节制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;