多媒体应用程序的设计_第1页
多媒体应用程序的设计_第2页
多媒体应用程序的设计_第3页
多媒体应用程序的设计_第4页
多媒体应用程序的设计_第5页
已阅读5页,还剩42页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Windows

教材:VisualC++参考书:1.《C++程序设计教程》,,2《VisualC++程序设计-基础与实例分析》,朱晴婷编著第10讲多媒体应用程序的设计212.1利用音频函数

为了介绍多媒体程序的设计,我们先介绍一个非常简单的例子,希望读者能够通过这个简单的例子,了解音频文件的播放方法312.1.1一个简单的应用实例

【例12-1】设计一个简单的音频播放程序,程序启动时,播放windows系动启动时候的音乐1.创建工程文件MCIStart;打开Stdafx.h文件,在#ifndef_AFX_NO_AFXCMN_SUPPORT语句的上一行顶头加入语句#include<mmsystem.h>2.将winmm.lib与应用程序链接起来3.在MCIStartDlg.cpp的OnInitDialog()函数中的returnTRUE之前加上代码:sndPlaySound("SystemStart",SND_ASYNC);

412.1.2几个常用的音频函数

MessageBeep()函数:用来播放系统提示音

sndPlaySound()函数:播放wav音频

PlaySound()函数:播放来自资源中的声音PlaySound()sndPlaySound()MessageBeep()功能包含关系512.1.3用MCI控制波形声音的播放

MCIERRORmciSendCommand( MCIDEVICEIDIDDevice,//接收命令消息的MCI设备ID UINTuMsg, //发送的命令消息

DWORDfdwCommand,//命令消息的标志集

DWORD_PTRdwParam)//消息参数的结构体地址常用的MCI设备消息见教材表12-56在调用MCI设备时可用mciGetErrorString()检测错误,该函数的原型如下:

BOOLmciGetErrorString(DWORDfdwError,//错误代码

LPTSTRlpszErrorText,//指向错误内容字串的指针

UINTcchErrorText//错误内容的缓冲区容量)7【例12-2】编写一个音频播放器程序,可以选择音频文件,并控制其播放、暂停播放、暂停后的继续播放以及停止播放的功能

IDC_OPEN_BUTTONIDC_CLOSE_BUTTONIDC_START_BUTTONIDC_PAUSE_BUTTONIDC_STOP_BUTTONIDC_EXIT_BUTTON81.

将头文件mmsystem.h加入到文件Stdafx.h中,将多媒体函数库winmm.lib通过project菜单中的seetings命令来与程序链接起来2.在CMCIPlayerDlg类上增加Protected类型的成员变量,具体如下:

BOOLm_PSign(作为判断正在播放的标识)

BOOLm_ASign(作为判断正在播放的标识)、DWORDdwError(用来储存错误代码)、MCIDEVICEIDm_MCIDeviceID(用来储存打开设备的ID值)

charszErrorBuf[MAXERRORLENGTH](用来储存出错内容)

9BOOLCMCIPlayerDlg::OnInitDialog(){ CDialog::OnInitDialog(); … //TODO:Addextrainitializationhere m_PSign=FALSE; //初始化正在播放标识

m_ASign=FALSE; //初始化正在暂停标识

m_MCIDeviceID=0; //初始化设备标识

returnTRUE;}10voidCMCIPlayerDlg::OnOpenButton()//打开一个文件{ CString; //定义CString类的用来存储文件名

CString; //定义CString类的用来存储文件扩展名

MCI_OPEN_PARMSmciOpenParms;//定义结构体变量用来存储打开文件的信息和返回的设备标识信息

DWORDdwError; //定义dwError用来储存返回的错误标识

staticcharszFilter[]="波形音频文件(*.wav)|*.wav|MIDI序列(*.mid)|*.mid\0"; Cdlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);//通过打开按钮时显示的内容11if(dlg.DoModal()==IDOK){(); //获取打开的文件名

(); //获取打开的文件扩展名

if(m_PSign) //如果程序正在播放,则关闭

{

dwError=mciSendCommand(m_MCIDeviceID,MCI_CLOSE,0,NULL); //关闭正在播放的声音if(dwError) //如果关闭不成功,则显示出错的原因

{if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH)) MessageBox(szErrorBuf,"MCI出错",MB_ICONWARNING);elseMessageBox("不明错误标识","MCI出错",MB_ICONWARNING);

//给出相应报告

return;}

}12//如果没有声音正在播放,则获取打开文件的后辍,并根据后辍决定相应的打开类型

if(!strcmp("wav",)) //当后辍为wav时

mciOpenParms.lpstrDeviceType="waveaudio"; elseif(!strcmp("mid",))//当后辍为mid时

mciOpenParms.lpstrDeviceType="sequencer"; mciOpenParms.lpstrElementName=; //将打开的文件名存入mciOpenParms结构体中

dwError=mciSendCommand(0,MCI_OPEN,MCI_OPEN_TYPE|MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpenParms);//发送打开文件命令,MCI_OPEN_TYPE参数说明设备类型名包含在mciOpenParms结构体中,//MCI_OPEN_ELEMENT参数说明要打开的文件名包含在mciOpenParams结构体中13if(dwError)//如果打开不成功,则显示出错的原因{if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH)) MessageBox(szErrorBuf,"MCI出错",MB_ICONWARNING);elseMessageBox("不明错误标识","MCI出错",MB_ICONWARNING); return;}m_MCIDeviceID=mciOpenParms.wDeviceID;//将获取的设备ID值赋给全局变量m_MCIDeviceIDm_PSign=FALSE;//设置正在播放标识为FALSEm_ASign=FALSE;//设置正在暂停标识为FALSE}}14voidCMCIPlayerDlg::OnStartButton()//从头开始播放{MCI_PLAY_PARMSmciPlayParms; //结构体变量存储播放相关信息

if(!m_PSign) //如果没有正在播放的声音

{mciPlayParms.dwCallback=(long)GetSafeHwnd(); //为发送MM_MCINOTIFY消息指定窗口句柄

mciPlayParms.dwFrom=0;//设置播放位置从头开始dwError=mciSendCommand(m_MCIDeviceID,MCI_PLAY,MCI_FROM|MCI_NOTIFY,(DWORD)(LPVOID)&mciPlayParms);//开始播放声音,参数MCI_FROM说明开始播放的位置包含在mciPlayParms结构体中

//参数MCI_NOTIFY的意义是播放完后发送MM_MCINOTIFY消息15if(dwError){if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH))

MessageBox(szErrorBuf,"MCI出错",MB_ICONWARNING);else

MessageBox("不明错误标识","MCI出错",MB_ICONWARNING);return;}m_PSign=TRUE;//设置正在播放标识为TRUE}}16voidCMCIPlayerDlg::OnPauseButton(){if(m_PSign)//如果有正在播放的声音{if(!m_ASign)//如果不是暂停状态{dwError=mciSendCommand(m_MCIDeviceID,MCI_PAUSE,0,NULL); //则暂停播放

if(dwError)

{if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH)) MessageBox(szErrorBuf,"MCI出错",MB_ICONWARNING); elseMessageBox("不明错误标识","MCI出错",MB_ICONWARNING); return; } m_ASign=TRUE; //设置正在暂停标识为TRUE

}17else //如果已经是暂停状态{dwError=mciSendCommand(m_MCIDeviceID,MCI_RESUME,0,NULL); //则继续播放

if(dwError){if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH)) MessageBox(szErrorBuf,"MCI出错",MB_ICONWARNING); else

MessageBox("不明错误标识","MCI出错",MB_ICONWARNING); return;}m_ASign=FALSE;//设置正在暂停标识为FALSE} }}18voidCMCIPlayerDlg::OnStopButton(){dwError=mciSendCommand(m_MCIDeviceID,MCI_STOP,MCI_WAIT,NULL); //发送停止命令消息,参数MCI_WAIT说明当命令执行结束后函数才返回值

if(dwError){if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH)) MessageBox(szErrorBuf,"MCI出错",MB_ICONWARNING);elseMessageBox("不明错误标识","MCI出错",MB_ICONWARNING); return;} m_PSign=FALSE; //设置正在播放标识为FALSE m_ASign=FALSE; //设置正在暂停标识为FALSE

MessageBox("如要播放新的文件,请在打开前先关闭现有文件","注意",MB_ICONQUESTION); //提请用户注意先关闭现有文件}19voidCMCIPlayerDlg::OnCloseButton() //关闭当前设备{if(m_MCIDeviceID)//若什么文件都没有打开过,就不执行关闭操作

{dwError=mciSendCommand(m_MCIDeviceID,MCI_STOP,MCI_WAIT,NULL);

if(dwError)

{if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH)) MessageBox(szErrorBuf,"MCI出错",MB_ICONWARNING);elseMessageBox("不明错误标识","MCI出错",MB_ICONWARNING); return;}dwError=mciSendCommand(m_MCIDeviceID,MCI_CLOSE,0,NULL);if(dwError){if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH)) MessageBox(szErrorBuf,"MCI出错",MB_ICONWARNING);elseMessageBox("不明错误标识","MCI出错",MB_ICONWARNING); return;}m_MCIDeviceID=0; //关闭文件后将变量设为0}}20voidCMCIPlayerDlg::OnExitButton() //点击确定的响应{ OnCloseButton(); //先执行关闭文件的操作

CDialog::OnOK(); //关闭窗口}21手动加入MM_MCINOTIFY消息的处理函数在MCIPlayerDlg.h中的函数classCMCIPlayerDlg:publicCDialog()的“//}}AFX_MSG”和“DECLARE_MESSAGE_MAP()”语句之间加入如下代码:

afx_msgLRESULTMciNotify(WPARAMwParam,LPARAMlParam);22在MCIPlayerDlg.cpp中的消息映射入口处加入如下代码:ON_MESSAGE(MM_MCINOTIFY,MciNotify)。样式如下:BEGIN_MESSAGE_MAP(CMCIPlayerDlg,CDialog) //{{AFX_MSG_MAP(CMCIPlayerDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_OPEN_BUTTON,OnOpenButton) ON_BN_CLICKED(IDC_START_BUTTON,OnStartButton) ON_BN_CLICKED(IDC_PAUSE_BUTTON,OnPauseButton) ON_BN_CLICKED(IDC_STOP_BUTTON,OnStopButton) ON_BN_CLICKED(IDC_CLOSE_BUTTON,OnCloseButton) //}}AFX_MSG_MAP ON_MESSAGE(MM_MCINOTIFY,MciNotify)END_MESSAGE_MAP()23

将函数MciNotify加入应用程序中:LRESULTCMCIPlayerDlg::MciNotify(WPARAMwParam,LPARAMlParam){ if(wParam==MCI_NOTIFY_SUCCESSFUL) //成功播放完成后重置标识

{m_PSign=FALSE;//设置正在播放标识为FALSE m_ASign=FALSE;//设置正在暂停标识为FALSEreturn0; }return-1;//否则返回错误}2412.2利用WindowsMediaPlayer控件实现多媒体程序设计

【例12-3】编写应用程序,使得用户可以分别选择一个视频文件和一个音频文件来同时播放或者分别播放

25为CPlayMediaView类添加四个成员,两个用来播放多媒体文件,两个用来保存待播放的文件名,修改后的CPlayMediaView.h文件如下:classCWMPPlayer4; //前示声明classCPlayMediaView:publicCView{protected: //createfromserializationonlyCPlayMediaView();DECLARE_DYNCREATE(CPlayMediaView)

//Attributespublic: CPlayMediaDoc*GetDocument();

CWMPPlayer4 *m_Video; //用来播放视频

CWMPPlayer4 *m_Music; //用来播放音频

CString m_strVideo; //视频文件名

CString m_strMusic; //音频文件名//Operations…};26初始化和释放指针,修改PlayMedia.cpp文件:#include"wmpplayer4.h"#include"wmpcontrols.h"#include"wmpsettings.h"

CPlayMediaView::CPlayMediaView(){ //TODO:addconstructioncodehere

m_Video=newCWMPPlayer4; m_Music=newCWMPPlayer4;

}

CPlayMediaView::~CPlayMediaView(){ deletem_Video; deletem_Music; }27

对于m_Video和m_Music两个变量,由于对应的是ActiveX控件,因此不但需要new来初始化指针,还需要使用它的Create函数来创建初始化ActiveX控件。由于两个控件是作为View的子窗口运行的,通常它们的创建是在View的OnCreate函数中完成,因此需要响应View的WM_CREATE消息,并在其中创建两个控件:28intCPlayMediaView::OnCreate(LPCREATESTRUCTlpCreateStruct)

{if(CView::OnCreate(lpCreateStruct)==-1) return-1; //TODO:Addyourspecializedcreationcodehere

HCURSORhCursor=::LoadCursor(NULL,IDC_ARROW); //获得标准箭头鼠标指针

m_Video->Create(AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_PARENTDC,hCursor,0,0),NULL,WS_VISIBLE|WS_CHILD,CRect(0,0,0,0),this,0);

//创建视频窗口

//由于使用单独的音频来播放,将视频设置为静音模式

m_Video->GetSettings().SetMute(TRUE);

m_Music->Create(AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_PARENTDC,hCursor,0,0), NULL,WS_VISIBLE|WS_CHILD,CRect(0,0,0,0),this,0);

//创建音频窗口

m_Music->ShowWindow(SW_HIDE);//将音频窗口设置为不可见

return0;}29们添加“操作”及相关菜单项

ID_OPER_OPENVID_OPER_PLAYVID_OPER_STOPV

ID_OPER_OPENAID_OPER_PLAYAID_OPER_STOPA30voidCPlayMediaView::OnOperOpenv(){staticcharBASED_CODEszFilter[]="VideoFiles(*.avi;*.mpg;*.mpeg)|*.avi;*.mpg;*.mpeg|"; //只允许打开视频文件C(TRUE,NULL,NULL,OFN_HIDEREADONLY,szFilter);if(()==IDOK)m_strVideo=();//获得视频文件名}

voidCPlayMediaView::OnOperPlayv(){m_Video->GetControls().stop();//首先停止正在播放的

m_Video->GetSettings().SetAutoStart(TRUE); //准备播放

m_Video->SetUrl(m_strVideo); //载入视频文件自动播放}31voidCPlayMediaView::OnOperStopv(){ m_Video->GetControls().stop(); //停止播放}

voidCPlayMediaView::OnOperOpena(){ //只允许打开音频文件

staticcharBASED_CODEszFilter[]= "AudioFiles(*.wav;*.mp3)|*.wav;*.mp3||"; C (TRUE,NULL,NULL, OFN_HIDEREADONLY,szFilter);if(()==IDOK)m_strMusic=();//获得音频文件名}32voidCPlayMediaView::OnOperPlaya(){m_Music->GetControls().stop(); //首先停止正在播放的

m_Music->GetSettings().SetAutoStart(TRUE);//准备播放

m_Music->SetUrl(m_strMusic); //载入视频文件自动播放}

voidCPlayMediaView::OnOperStopa(){ m_Music->GetControls().stop(); //停止播放}

33

有了以上代码,程序还不能够正常运行,需要为播放视频的控件设置窗口尺寸。为此需要响应View的WM_SIZE消息,该消息响应函数如下:voidCPlayMediaView::OnSize(UINTnType,intcx,intcy){CView::OnSize(nType,cx,cy); //TODO:AddyourmessagehandlercodehereCRectrect;GetClientRect(rect);m_Video->MoveWindow(rect);}

在播放视频时,该控件会自动显示出MediaPlayer的控制面板,可以通过在OnCreate函数中,在m_Video创建之后调用SetMode函数来隐藏该控件的控制面板。

m_Video->SetUiMode("none");3412.3常见格式图片的显示

Windows程序中经常要显示各种图片,对于普通的BMP、DIB等位图格式文件,GDI的LoadImage,LoadBitmap函数已经提供了支持,但是对于网页中常见的PNP、JPG、GIF以及矢量格式的WMF图片,VisualC++自带了一个实现这个功能的函数——OleLoadPicture。但是由于MSDN中只提到该函数支持BMP、ICO、WMF格式,因此该函数经常被大家忽视,这里将介绍如何使用该函数来显示各种格式的图片。

35【例12-4】使用AppWizard创建MFCSDI应用程序,用来装载并显示图片。创建ImageViewer工程文件。为显示图片,为CImageViewerView添加成员m_pPicture以装载图形,并定义载入图片的函数的声明:

LPPICTUREm_pPicture;private: voidLoadPicture(CStringstrFile);

接下来为m_pPicture成员添加初始化和释放的代码:CImageViewerView::CImageViewerView(){ m_pPicture=NULL; }

CImageViewerView::~CImageViewerView(){if(m_pPicture) m_pPicture->Release(); }36为实现打开文件,我们添加“操作&O”菜单,增加菜单项“载入图片”,其ID为ID_OPER_OPEN,然后映射消息响应函数:voidCImageViewerView::OnOperOpen(){TCHARsz]; //保存文件名的缓冲

ZeroMemory(szFile,MAX_PATH); //初始化该缓冲

OPENofn; //打开文件的关键结构

ZeroMemory(&ofn,sizeof(OPEN));//初始化该结构

ofn.lStructSize=sizeof(OPEN);//设置该结构的大小

//设置属性:文件必须存在、路径必须存在、隐藏只读文件

ofn.Flags=OFN_|OFN_PATHMUSTEXIST |OFN_HIDEREADONLY;ofn.hwndOwner=m_hWnd; //设置该文件框的父窗口37ofn.lpstrFilter=_T("SupportedFilesTypes(*.bmp;*.gif;*.jpg;*.ico;*.emf;*.wmf)\0*.bmp;*.gif;*.jpg;*.ico;*.emf;*.wmf\0Bitmaps(*.bmp)\0*.bmp\0GIFFiles(*.gif)\0*.gif\0JPEGFiles(*.jpg)\0*.jpg\0Icons(*.ico)\0*.ico\0EnhancedMetafiles(*.emf)\0*.emf\0WindowsMetafiles(*.wmf)\0*.wmf\0\0"); //设置支持的文件扩展名

ofn.lpstrTitle=_T("选择图片"); //对话框标题ofn.lpstrFile =szFile; //设置返回文件名的缓冲ofn.nMaxFile =MAX_PATH; //设置缓冲的长度if(IDOK==GetOpen(&ofn)) //调用对话框

LoadPicture(szFile); //载入该文件}38下面实现关键函数——LoadPicture:voidCImageViewerView::LoadPicture(CStringstrFile){ HANDLEh(str);

//打开文件

_ASSERTE(INVALID_HANDLE_VALUE!=hFile);

DWORDdw=Get(hFile,NULL);//获得文件大小

_ASSERTE(-1!=dw); LPVOIDpvData=NULL;

HGLOBALhGlobal=GlobalAlloc(GMEM_MOVEABLE,dw);

//分配全局内存,获得内存句柄

_ASSERTE(NULL!=hGlobal);

pvData=GlobalLock(hGlobal);//锁定内存,获得内存指针

_ASSERTE(NULL!=pvData);39 DWORDdwBytesRead=0; BOOLbRead=Read,pvData,dw,&dwBytesRead,NULL);//读取文件

_ASSERTE(FALSE!=bRead); GlobalUnlock(hGlobal); CloseHandle(hFile); LPSTREAMpstm=NULL; HRESULThr=CreateStreamOnHGlobal(hGlobal,TRUE,&pstm);//从内存数据创建IStream* _ASSERTE(SUCCEEDED(hr)&&pstm);40 if(m_pPicture) //创建IPicture m_pPicture->Release(); //从IStream接口中载入图片到IPicture中

hr=::OleLoadPicture(pstm,dw,FALSE,IID_IPicture,(LPVOID*)&m_pPicture); _ASSERTE(SUCCEEDED(hr)&&m_pPicture); pstm->Release(); //释放IStream接口Invalidate(); //强制重新绘制窗口 }通过以上调用,我们的程序已经将位图文件成功载入到m_pPicture变量中了41

下面就是显示的步骤,与一般的绘图程序类似,显示代码也是在OnDraw中完成。#defineHIMETRIC_INCH 2540voidCImageViewerView::OnDraw(CDC*pDC){CImageViewerDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);//TODO:adddrawcodefornativedatahereif(m_pPicture){longhmWidth;longhmHeight;m_pPicture->get_Width(&hmWidth);m_pPicture->get_Height(&hmHeight);42//converthimetrictopixels

intnWidth=MulDiv(hmWidth,GetDeviceCaps(pDC->GetSafeHdc(), LOGPIXELSX),HIMETRIC_INCH);intnHeight=MulDiv(hmHeight,GetDeviceCaps(pDC->GetSafeHdc(), LOGPIXELSY),HIMETRIC_INCH);CRectrc;GetClientRect(&rc);//displaypictureusingIPicture::Rende

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论