经典论文范例

武汉科技大学本科毕业论文

摘 要

媒体控制接口 (Media Control Interface,MCI)是Windows提供的与设备无关的多媒体高层命令接口,可以控制CD声音、视频动画、Wave格式数字声音、MIDI音序器、录像机和激光视盘机等多种设备。MCI功能强大,是Windows多媒体编程的重要组成部分。混音器(Audio Mixer)是控制系统中各音源的音量控制设备。通过混音器编程可以实现混音和音量控制。

为了开发出具有个性的多媒体软件,

本课题掌握MCI编程的方法,将为深入多媒体应用编程奠定基础。本系统采用

C++6.0作为开发工具,使用MCI的主要函数与命令以及混音器的有关函数,制作了一个小巧的多媒体播放器,能够播放主流的多媒体影音文件,

列表里选定的文件,能够显示媒体文件的播放进度,并提供各种媒体播放控制,比如打开、暂停、快进、快退等,以及音量控制。并且界面小巧美观,使用方便,有完善的操作控制按钮、进度指示条等,还实现了显示界面和隐藏界面的迅速切换。本论文主要介绍了本课题的开发目的,所要完成的功能和开发的过程。重点说明了系统设计的重点、设计思想、难点技术和解决方案。

关键词: Visual C++ 6.0; MCI;

需要深入了解有关底层编程的方法。通过研究能够自动循环播放用户播放混音器 I Visual

武汉科技大学本科毕业论文

Abstract

Provided by Windows and unrelated to the equipment, Media Control Interface is a high-level multimedia command interface , which can control CD audio, video animation, digital audio of Wave form, MIDI sequencer, DVD recorder and laser videodisc, etc. With a powerful function, MCI is an important part of Windows Multimedia Programming. Audio Mixer is a kind of volume-control equipment, which controls sound sources of the system. Mixing sound and volume control can be achieved through Audio Mixer Programming.

In order to develop multimedia software with distinction, the method of low-level multimedia programming needs to be understood. MCI programming methods, which will make a foundation for further multimedia programming, will be acquired by study this subject. This system adopts Visual C++6.0 as development tool and uses main functions and orders of MCI as well as some correlative functions of Audio Mixer to produce a small and exquisite Multimedia player. It can automatically and circularly play many popular formats of multimedia documents, which are selected in the user’s list. It is also able to demonstrate broadcast progress of multimedia documents. This system not only provides many kinds of functions to control the multimedia player, such as opening, pause, speedily-forward, speedily-backward and so on, but also volume control. And the interface is small and delicate. There are complete operation control buttons and progress bar that make the player easy to operate. Meanwhile, revealing interface can switch rapidly to hiding interface. This thesis mainly introduces the purpose and procedure of development and functions to be completed about this subject. Key point, idea of design, key technology and solutions are mainly emphasized.

Key Words: Visual C++ 6.0; MCI; Audio Mixer

II

武汉科技大学本科毕业论文

目 录

1 绪论 .................................................................. 1

1.1 课题背景 ......................................................... 1

1.1.1 多媒体的发展历史 ........................................... 1

1.1.2 计算机多媒体介绍 ........................................... 1

1.1.3 多媒体未来的发展 ........................................... 2

1.2 课题主要内容 ..................................................... 2

1.3 研究课题的意义 ................................................... 3

2 媒体控制接口与混音器编程 .............................................. 4

2.1 Windows多媒体体系结构 ........................................... 4

2.2 Windows多媒体设计思想 ........................................... 5

2.3 媒体控制接口编程 ................................................. 6

2.3.1 媒体控制接口MCI ............................................ 6

2.3.2 MCI设备与时间格式 .......................................... 6

2.3.3 MCI函数与命令 .............................................. 7

2.3.4 MCI接口方式 ............................................... 10

2.4 混音器编程 ...................................................... 12

2.4.1 混音器服务的控制类型 ...................................... 12

2.4.2 混音器的函数 .............................................. 13

3 系统总体设计 ......................................................... 16

3.1 需求分析 ........................................................ 16

3.1.1 功能需求 .................................................. 16

3.1.2 界面要求 .................................................. 16

3.1.3 开发平台和开发工具 ........................................ 16

3.2 系统分析 ........................................................ 17

3.2.1 用例分析 .................................................. 17

3.2.2 对象分析 .................................................. 17 III

武汉科技大学本科毕业论文

3.2.3 功能分析 .................................................. 19

3.3 界面设计 ........................................................ 19

3.4 关键功能设计 .................................................... 20

3.4.1 媒体播放类设计 ............................................ 20

3.4.2 音量控制类设计 ............................................ 21

4 系统实现 ............................................................. 22

4.1 系统开发平台 .................................................... 22

4.2 设计对话框 ...................................................... 22

4.3 实现媒体播放类 .................................................. 24

4.4 实现音量控制类 .................................................. 27

4.5 界面实现 ........................................................ 28

4.5.1 实现播放器背景 ............................................ 28

4.5.2 创建异型按钮 .............................................. 29

4.5.3 创建位图按钮 .............................................. 30

4.5.4 实现隐藏窗口 .............................................. 31

4.5.5 实现播放进度条控制 ........................................ 32

4.5.6 实现音量控制 .............................................. 32

4.5.7 实现选择文件列表 .......................................... 33

4.5.8 实现对话框的移动 .......................................... 33

4.5.9 实现控件颜色的修改 ........................................ 34

4.6 系统运行 ........................................................ 34

5 结论 ................................................................. 35

参考文献 ................................................................ 36

致谢 .................................................................... 37

IV

武汉科技大学本科毕业论文

1 绪论

1.1 课题背景

1.1.1 多媒体的发展历史

多媒体技术初露端倪肯定是X86

技术全面发展的时间的话,准确地说应该是在

之前,显卡就已经出现了,至少显示芯片已经出现了。

已经初具处理图像的能力,但是这不能说明当时的电脑可以发展多媒体技术,声卡的出现,不仅标志着电脑具备了音频处理能力,

了一个崭新的阶段:多媒体技术发展阶段。

运动图像专家小组)的建立又对多媒体技术的发展起到了推波助澜的作用。进入代,随着硬件技术的提高,自80486以后,多媒体时代终于到来

自80年代之后,多媒体技术发展之速可谓是让人惊叹不已。不过,无论在技术上多么复杂,在发展上多么混乱,似乎有两条主线可循:一条是视频技术的发展,一条是音频技术的发展。从AVI出现开始,视频技术进入蓬勃发展时期。这个时期内的三次高潮主导者分别是AVI、Stream(流格式

存储奠定了一个标准,而Stream使得网络传播视频成为了非常轻松的事情,

则是将计算机视频应用进行了最大化的普及。而音频技术的发展大致经历了两个阶段,一个是以单机为主的WAV和MIDI,一个就是随后出现的形形色色的网络音乐压缩技术的发展[1]。

从PC喇叭到创新声卡,再到目前丰富的多媒体应用,多媒体正改变我们生活的方方面面。

1.1.2 计算机多媒体介绍

计算机多媒体技术是一种结合文本、图形、图像、动画、声音和视频等多种形式的信息,通过计算机进行获取、编辑、存储、检索、展示、传输等多种综合处理和控制,能支持完成一系列交互式操作的信息技术。计算机多媒体编程中经常涉及的媒体包括:数字化波形音频、MIDI、CD音频、图形图像及数字视频等。

多媒体技术提供对文字、图像、声音、视频等多种信息的数字处理方法。多媒体技 PC上第一块声卡出现后。早在没有声卡显示芯片的出现自然标志着电脑80年代也标志着电脑的发展终于开始进入19xx年MPEG(Moving Picture Expert Group,90年[1]。 )以及MPEG。AVI的出现无异于为计算机视频那么MPEG 1 时代的事情,如果真的要从硬件上来印证多媒体

武汉科技大学本科毕业论文

术的核心是多媒体应用软件。多媒体应用软件必须具备三个基本特性[2]:

(1)提供对多种媒体的处理能力; (2)良好的人机交互性能; (3)功能强大的多媒体操作系统。

多媒体操作系统是多媒体应用系统的支撑系统,多媒体操作系统内部具有视频/音频支撑系统(Audio/Video Support System , AVSS)和视频/音频核心(Audio/Video Kernel , AVK)。

多媒体操作系统的主要特性包括如下几方面(1)平台的独立性:利用多媒体工作平台应能进行各种多媒体应用的基本操作。(2)灵活性:提供一个能够管理和控制多媒体设备及数据的灵活操作环境。(3)可扩展性:多媒体技术在不断变化发展,不断出现新的媒体文件格式,因此多媒体操作系统应当能支持多媒体的改进和提高,能。

(4)高性能:多媒体操作系统应能协调处理各种媒体,节省计算机存储器开销。

1.1.3 多媒体未来的发展未来对多媒体的研究,主要有以下几个研究方面:模、多媒体信息的组织与管理、多媒体信息表现与交互、多媒体通信与分布处理、多媒体的软硬件平台、虚拟现实技术、多媒体应用开发。交融的交互式多媒体将成为从网络上接受信息、选择信息,还可以发送信息,其信息是以多媒体的形式传输。利用这一技术,人们能够在家里购物、点播自己喜欢的电视节目。技术的实现将以电视或者以个人计算机为基础, 多媒体的未来是激动人心的,加,质量上也将大大地改善。多媒体正在迅速的、意想不到的方式进入人们生活的多个方面,大的趋势是各个方面都将朝着当今新技术综合的方向发展,这其中包括:光碟存储器、国际互联网和交互电视。这个综合正是一场广泛革命的核心,信息的包装方式和我们如何运用这些信息,而且将改变我们互相通信的方式。1.2 课题主要内容本系统制作了一个小巧的多媒体播放器,能够播放主流的多媒体影音文件。由于MFC中没有用于多媒体编程的类,而使用

[2]:

并能随着硬件能力的提高而加强自身性

数据压缩、多媒体信息特性与建 展望未来,网络和计算机技术相21世纪多媒体发展方向。所谓交互式多媒体是指不仅可以21究竟谁将主宰未来的市场还很难说我们生活中数字信息的数量在今后几十年中将急剧增MCI命令与函数进行多媒体编程都要设置很

2

CPU、内存、外[1]。] 大容量它不仅影响

世纪的交互式多媒体

武汉科技大学本科毕业论文

多参数,使用不便。因此本系统采取自己创建用于媒体播放的类,封装要用到的MCI的方法和函数,隐藏所有MCI命令参数,仅留简单的操作接口,从而简化MCI编程方式,便于重用和访问。音量控制也采取创建可以复用的类,将Audio Mixer中的打开、关闭音频设备、控制音量等函数封装起来,简化使用,也便于以后重用。其中使用了以下关键技术:

(1)MCI主要函数与命令的使用方法; (2)MCI命令字符串的接口方式; (3)混音器编程;(4)异型按钮和位图按钮的实现;(5)在系统托盘中添加程序图标。1.3 研究课题的意义在Windows环境下开发多媒体应用程序,Director等,它们具有方便快捷的优点,但开发出来的应用程序功能不够强大、灵活。而VC功能强大,程序执行效率高,是强大的多媒体开发平台。它为进行多媒体开发提供了多方位的支持,如MCI为程序员提供了在高层次上控制媒体设备接口的能力,它向应用程序提供了一种与设备无关的控制多媒体设备的能力。打交道,而MCI则通过具体的设备驱动程序来控制相应的多媒体设备。为了提供可扩展性,MCI是围绕着应用特殊计的。MCI设备驱动器可以直接或通过利用MCI开发多媒体应用程序具有以下优点(1)程序员只要熟悉而不需了解每一种多媒体设备的工作原理和调用函数库方法,减轻了开发难度。(2)MCI是一种访问多媒体设备高层次的方法,独立于具体的多媒体设备,系统升级时,不需要修改应用程序的代码,大大提高了应用程序的开发利用率。(3)MCI充分发挥熟悉接调用的函数库。

虽然关于多媒体编程已有很多公开代码,有多种封装了不必进行复杂的MCI有关底层编程的方法。通过研究本课题掌握程奠定基础。

可以通过多媒体开发工具,MCI、MCIWnd、低级APIMCI调用使用方便,应用程序只需与MCI设备驱动程序来编译和执行Windows提供的低级多媒体函数控制硬件。[1]MCI,按MCI标准进行程序设计,C++语言的程序员的特长,提供了强大的、可在MCI编程的方法,将为深入多媒体应用编3

DirectX等。MCI就可以实现对多媒体的操作,MCI的类可以直接使用,Authoware、MCI

C语言中直

如函数、

命令的结构进行设:

编程,但是要开发出具有个性的多媒体软件,还是需要深入了解

武汉科技大学本科毕业论文

2 媒体控制接口与混音器编程

2.1 Windows多媒体体系结构

Windows操作系统从Windows95版本以后具备多媒体操作系统的基本特性,能够提供多媒体核心和管理接口,支持即查即用(Plug and Play ,

系统性能、软硬件管理方面满足多媒体技术需求。

Windows具有如下的多媒体特征[3]:

(1)提供对音频、视频和图像的压缩服务,具备开放的软件接口;

(2)内置Video for Windows运行版,Windows内置运行时,

可以对视频数据类型进行操作;可以在Windows环境中直接播放或剪辑数字视频;

(3)增强的MIDI支持;

(4)可控制视频设备,用户按“帧”对视频进行停止、开始、暂停等操作。Windows的多媒体体系具有模块化的层次结构,如图1.1

使用媒体控制接口(Media Control Interface , MCI)规范发送命令和数据。含命令和数据类型信息。MCI指令组成的MCI数据流传送给

MMSYSTEM.DLL,并由它进行解释执行。

音频服务将声音集成到应用程序中,包括播放波形数据文件的高级播放功能和控制播放压缩声音的低级功能。这些功能包括基本的

MMSYSTEM.DLL实现。应用程序调用MMSYSTEM.DLL

者录制音频数据。

音频压缩管理服务由ACM提供,支持音频数据的录制或者播放过程中的压缩与解压缩。ACM能在把音频数据传送给设备驱动程序之前对其进行解码或者编码,并提供明确的压缩、解压缩和过滤音频数据的功能。

Windows的MIDI功能使应用程序具备以下能力[3]:

(1)直接存取未做任何处理的MIDI数据;

(2)对MIDI消息添加时间标记;

(3)利用缓冲区传送或者接收具有时间标记的MIDI数据。

Windows还能增强数字视频显示:

(1)对压缩的视频进行解压缩;

(2)控制播放。

Windows的多媒体视频功能支持多种不同类型的视频格式或者压缩标准。 4 PnP),在GUI操作界面、 无需任何多余的硬件就 所示[2]。多媒体应用程序MCI指令包Windows的多媒体系统库频处理功能,并通过 Windows 音中的音频函数便可以播放或

武汉科技大学本科毕业论文

的多媒体视频播放方式取决于视频格式的文件头信息。Windows多媒体的体系结构如图

2.1所示[2]。

经典论文范例

图2.1 Windows的多媒体体系结构

音频命令和数据被送往合适的驱动程序。未压缩的数据流直接传送给驱动程序,而

压缩数据将先传送到音频压缩管理器(ACM)。ACM将分析数据流,判断其采用的压缩器/解压缩器(Codec),并对数据流进行解压缩后再传送到驱动程序。视频命令和数据的处理与音频基本相同。

2.2 Windows多媒体设计思想

多媒体服务的结构是围绕着可扩展性和设备无关的思想设计的。可扩展性使软件结

构可以跟上技术进步,而无需改变软件本身的结构;设备无关使得容易开发出能在提供不同级多媒体支持的、范围广泛的硬件上运行的多媒体应用程序。系统软件的三种不同的设计元素提供了扩展性和设备无关[4]:

(1)翻译层(WINMM),它将应用程序与设备驱动程序分隔开来,并将设备无关码集

中起来。

5

武汉科技大学本科毕业论文

(2)运行时链接,它允许翻译层链接到所需的驱动程序。

(3)清晰、一致的驱动程序接口,它减少了特殊情况码,并使安装和更新进程更容易。

2.3 媒体控制接口编程

2.3.1 媒体控制接口MCI

媒体控制接口 (Media Control Interface,MCI)是Windows提供的与设备无关的多媒体高层命令接口,可以控制CD声音、视频动画、Wave格式数字声音、MIDI音序器、录像机和激光视盘机等多种设备。它的好处是可以方便地控制绝大多数多媒体设备而不需要知道它们的内部工作状况。可以把MCI理解成设备面板上的一排按键,通过选择不同的按键(发送不同的MCI命令)即可让设备完成各种功能,而不必关心设备的内部实现,它是一种主要实现音频播放的方式[1]。MCI功能强大,是Windows多媒体编程的重要组成部分。MCI由Microsoft提供的MMSYSTEM .h文件定义[5],应在多媒体应用程序的源程序中包含该文件。

2.3.2 MCI设备与时间格式

MCI设备可以分为两类:简单设备和复合设备。

(1)简单设备:描述简单设备只需指定MCI设备名,比如CD音频只需指定Caudio. (2)复合设备:复合设备不仅要说明设备类型,而且还要指定一个设备元素或媒体元素。对大多数复合设备来说,其设备元素是一个源或目标数据文件,其元素名就是相应的文件名。比如要描述数字化波形声音,必须指定其设备名waveaudio,还要说明存储数字化波形声音的全路径及文件名[2]。主要的MCI设备类型如表2.1所示。

表 2.1 主要的MCI设备类型

经典论文范例

6

武汉科技大学本科毕业论文

在MCI编程中,既可以将设备描述当设备名,也可以将描述字符串当设备名。 MMSYSTEM.h文件定义了一系列时间格式常量,通过MCI_SET命令可以设定MCI时间格式。常用的MCI时间格式有以下几种,其中轨常用于音频,帧常用于视频[2]。

MCI_FORMAT_FRAMES(帧) MCI_FORMAT_MILLISECONDS(毫秒) MCI_FORMAT_HMS(小时/分/秒) MCI_FORMAT_MSF(分/秒/帧) MCI_FORMAT_SMPTE_24(SMPTE24帧)MCI_FORMAT_SMPTE_25(SMPTE25帧)

MCI_FORMAT_SMPTE_30(SMPTE30帧) MCI_FORMAT_TMSF(轨/分/秒/帧) MCI_FORMAT_BYTES(字节) MCI_FORMAT_SAMPLES(样本)

2.3.3 MCI函数与命令

应用程序通过向MCI设备发送命令消息或者命令字符串来控制MCI设备。MCI命令可以分为如下的四类[6]。

(1)系统命令:直接由MCI解释并由系统处理,不传送到MCI设备。

(2)通用命令:所有的MCI设备都支持。

(3)可选命令:MCI设备可以选用。

(4)专用命令:针对某类专门的MCI设备或集合。

主要的MCI

经典论文范例

命令如表2.2所示。

7

经典论文范例

武汉科技大学本科毕业论文

8

经典论文范例

武汉科技大学本科毕业论文

经典论文范例

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

MCI命令都可以带两个标志命令来控制命令的执行方式,即“wait”和“notify”。它们在命令消息和命令字符串接口中的形式和意义如表2.3所示。

表 2.3 MCI标志命令

所有的MCI函数名都以mci为前缀。MCI函数也分为命令消息函数和命令字符串函数两类,对应MCI命令消息和命令字符串接口方式,如表2.4所示。

表 2.4 MCI函数

经典论文范例

9

经典论文范例

武汉科技大学本科毕业论文

2.3.4 MCI接口方式

2.3.4.1 MCI命令消息接口方式

利用消息和数据结构来给多媒体设备发送命令并接收设备传来的信息。这种方式用函数mciSendCommand来发送命令消息,命令消息带有数据结构作为操作参数。接口函数主要有mciSendCommand ,mciGetDeviceID和mciGetErrorString[7]。函数定义如下:

MCIERROR mciSendCommand(

MCIDEVICEID wDevice , //设备ID

UINT uMsg , //命令消息

DWORD fdwCommand , //命令消息标志

DWORD dwParam); //命令消息使用的结构参数地址 使用任何一个MCI设备之前都应先用MCI_OPEN打开它,要指定相应的MCI_OPEN_PARMS结构,打开时将自动创建一个设备标识号。若打开成功,可由wDeviceID取得该设备标识号,后续的MCI命令将使用该值。如果mciSendCommand调用成功,则返回的MCIERROR值为0;否则表示设备驱动出错,mciGetErrorString函数可以获取错误信息。

MCI还提供一个特殊设备标识号MCI_ALL_DEVICE_ID,表示当前所有已打开的MCI设备[7]。MCI_OPEN_PARMS结构定义如下。

Typedef struct

{

DWORD dwCallback ; //回调窗口句柄

MCIDEVICEID wDeviceID ; //设备打开成功,返回的设备号 LPCSTR lpstrDeviceType ; //设备类型

LPCSTR lpstrElementName ; //复合设备的设备元素,通常为文件名 LPCSTR lpstrAlias ; //指定的设备别名

}MCI_OPEN_PARMS;

MCI_OPEN命令的消息标志及其说明如表2.5所示。

表 2.5 MCI_OPEN命令的消息标志及其说明

经典论文范例

10

武汉科技大学本科毕业论文

打开简单MCI设备不需指定设备元素,仅需指定MCI_OPEN_PARMS结构中的wDeviceID和lpstrDeviceType。

打开复合MCI设备有以下三种方式。

(1)指定设备的类型:只允许确定MCI设备性能,不能进行其他操作。

(2)指定设备元素(数据文件名)和设备类型:可进行各种操作。

(3)指定MCI设备元素(数据文件名),而把设备类型指定为NULL:使用隐含MCI设备时,MCI将根据设备元素的扩展名从系统定义中选择隐含约定的MCI设备。

三种打开方式的区别如下[7]:

(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);

注意mciSendCommand函数第三个参数的区别:

MCI_OPEN_TYPE:表示要使用MCI_OPEN_PARMS结构中的lpstrDiviceType参数,这可区分指定设备打开方式和自动识别方式之间的区别。在自动方式中,不需使用lpstrDeviceType参数。因此,也不需指定MCI_OPEN_TYPE。

MCI_OPEN_ELEMENT:表示lpstrDeviceType参数中的是设备表述字符串。 MCI_OPEN_TYPE_ID:表示lpstrDeviceType参数中的是设备描述。

使用完一个MCI设备后应使用MCI_CLOSE命令关闭并释放MCI设备。

11

经典论文范例

武汉科技大学本科毕业论文

在mciSendCommmand的dwParam参数中指定MCI_SYSINFO_PARMS结构的地址可获取MCI设备系统信息。

2.3.4.2 MCI命令字符串接口方式

使用ASCII字符串来发送驱动设备的命令,采用函数mciSendString把命令字符串发给设备,字符串命令直观方便,如“play cdaudio”, “stop waveaudio”等。接口函数有mciSendString和mciGetErrorString[7]。

MciSendString用于向MCI设备发送命令字符串,其函数定义如下。

MCIERROR mciSendString(

LPCTSTR lpszCommand, //控制命令字符串

LPTSTR lpszReturnString, //指向返回字符串缓冲区的指针

UINT cchReturn, //缓冲区的长度大小

HANDLE hwndCallback); //消息窗口句柄

2.4 混音器编程

混音器(Audio Mixer)是控制系统中各音源的音量控制设备。

现混音和音量控制。

最基本的混音器结构单元是音频线路(Audio Line)

源于单一音源或系统音源的数据声道[2]。混音器在管理计算机的音频线路时支持选路服务,允许将多个音频源线路中,即实现多个音源的混音操作。如果系统中已安装足够的硬件和软件驱动程序,选路服务是非常有用的。

每一个音频线路都有与其相关的混音控制。一个混音控制能执行许多的操作音量控制),相关的音源的性质决定了操作的方式和数量。

2.4.1 混音器服务的控制类型

混音器服务包括以下与音频线路相关的标准控制类型

(1)音频混音器定制控制

这类控制是最基本的混音器控制,允许混音器驱动程序定义控制的特性,并通过应用程序来控制。

(2)衰减器

这类控制能调整数值,具有线性的刻度,使用

MIXERCONTROLDETAILS_UNSIGNED结构来检索和设置控制细节。

12 通过混音器编程可以实(比如 [2]。 。音频线路包含一个或者多个发

武汉科技大学本科毕业论文

(3)列表

列表提供对复杂音频线路的单选或复选,用

MIXERCONTROLDETAILS_BOOLEAN结构来检索和设置属性。该结构也用于检索多项控制的文字描述。

(4)标尺

用于测量通过音频线路的数据。用结构MIXERCONTROLDETAILS_BOOLEAN, MIXERCONTROLDETAILS_SIGNED和MIXERCONTROLDETAILS_UNSIGNED结构来检索和设置控制的属性。

(5)数字

混音器允许用户输入与线路相关的数字型数据,表示为整数、无符号型整数或整数分贝值等。

用MIXERCONTROLDETAILS_SIGNED,MIXERCONTROLDETAILS_UNSIGNED结构来检索和设置控制属性。

(6)滑竿

使用滑竿能左右调整数值的水平控制。使用MIXERCONTROLDETAILS_SIGNED结构来检索和设置控制属性。

(7)开关

用MIXERCONTROLDETAILS_BOOLEAN结构来检索和设置开关控制值。

(8)时间控制

时间控制允许用户输入时间相关数据,比如回声延迟或声响。单位为微妙或毫秒,其取值范围为0至(232-1)。

2.4.2 混音器的函数

2.4.2.1 查询混音器设备

混音器服务提供了检测系统中混音器设备数量及其性能的函数,也可以用于检测混音器设备的标识号。

(1)mixerGetNumDevs函数

该函数用于确定系统中有多少混音器设备,其定义如下。

UINT mixerGetNumDevs(VOID);

该函数返回系统中混音器设备的数量。混音器设备用设备标识号来表示。设备标识号的值隐含地由系统中设备的数量来决定,其取值范围在0和(设备数量-1)之间。

(2)mixerGetDevCaps函数

该函数可以确定混音器设备的能力,其定义如下。

13 [8]

武汉科技大学本科毕业论文

MMRESULT mixerGetDevCaps(

UINT uMxId,LPMIXERCAPS pmxcaps,UNIT cbmxcaps);

其中uMxId为混音器设备的标识号;若调用成功,将设备的能力填写到指向结构MIXERCAPS的指针pmxcaps中;cbmxcaps为结构MIXERCAPS的大小。

结构MIXERCAPS包含混音器生产厂商的标识符、混音器产品标识符、混音器设备驱动程序的版本号、产品名称、支持的音频线路数量等信息。

(3)mixerGetID函数

该函数用于检索与指定的设备相关联的音频混音器设备的标识,其定义如下。 MMRESULT mixerGetID(

HMIXEROBJ hmxobj,UINT*puMxId,DWORD fdwId);

其中hmxobj为音频混音器设备对象句柄;获取的混音器设备标识号将在puMxId中返回;fdwId为映射hmxobj句柄的标志,用于指定音频混音器设备的类型。

2.4.2.2 打开和关闭混音器设备

使用混音器设备之前应先打开该设备,可以保证混音器设备一直存在,当音频线路和控制发生变化时,可以收到相应的通知。一旦混音器设备发生变化,应用程序不能访问该设备[2]。

(1)mixerOpen函数

该函数用于打开混音器设备,其定义如下。

MMRESULT mixerOpen(

LPHMIXER phmx,UINT uMxId,DWORD dwCallback,DWORD dwInstance,DWORD fdwOpen);

其中的phmx是一个指向设备句柄的指针,当函数调用成功之后,该指针指向所打开的混音器设备的句柄,该句柄是混音器设备的唯一标识符;uMxId为混音器设备的标识号,用于指定要打开的混音器设备;dwCallback为在混音器设备发生变化时接收通知消息的窗口的句柄;dwInstance是传给回调函数的用户实例数据;fdwOpen为打开设备的标志。

设备标识号和设备句柄是不同的。用mixerOpen来打开设备驱动程序时返回设备句柄;用mixerGetNumDevs检测设备数量获得设备标识号。

(2)mixerClose函数

该函数用于关闭混音器设备,其定义如下。

MMRESULT mixerClose(HMIXER hmx);

其中hmx为设备句柄。

14

武汉科技大学本科毕业论文

2.4.2.3 窗口回调服务

窗口回调服务使应用程序能够处理混音器驱动程序发送的消息。使用这类服务时,应该在调用mixerOpen函数打开设备时将参数fdwOpen设为CALLBACK_WINDOW,并将dwCallback指定为一个窗口的句柄。驱动程序消息将发送到该窗口的处理函数中。消息被指定为音频设备消息类型[2]。

2.4.2.4 查询音频线路和控制

混音器服务提供检测音频线路、音频线路控制和控制细节等信息的函数,同时也提供设置控制细节消息的函数[2]。

(1)mixerGetLineInfo函数

该函数可检索指定音频线路的信息,其定义如下。

MMRESULT mixerGetLineInfo(

HMIXEROBJ hmxobj,LPMIXERLINE pmxl,DWORD fdwInfo);

其中hmxobj为指定设备对象的句柄;若调用成功,源音频线路、目标音频线路和线路标识号等信息将返回到pmxl所指的MIXERLINE结构中;fdwInfo为检索信息的标志。

(2)mixerGetLineControls函数

该函数用于检索与音频线路相关的控制的通用信息,其定义如下。

MMRESULT mixerGetLineControls(

HMIXEROBJ hmxobj, LPMIXERLINECONTROLS pmxlc, DWORD fdwControls); 其中的hmxobj为指定设备对象句柄;若调用成功,指定的控制或控制组的信息将返回到pmxlc所指的MIXERLINECONTROLS结构中;fdwControls为检索信息的标志。

调用函数mixerGetLineControls可以获得:指定源线路的所有控制、指定源线路的指定控制及指定源线路的指定类的第一个控制。

(3)mixerGetControlDetails函数

该函数用于检索与音频线路相关的一个控制的属性,其定义如下。

MMRESULT mixerGetControlDetails(

HMIXEROBJ hmxobj,LPMIXERCONTROLDETAILS pmxcd,

DWORD fdwDetails);

Hmxobj为指定设备对象句柄;设备属性信息先填入pmxcd所指的MIXERCONTROLDETAILS结构中;fdwDetails为设置信息的标志。

15

武汉科技大学本科毕业论文

3 系统总体设计

3.1 需求分析

3.1.1 功能需求

(1)能够播放多种格式的多媒体影音文件:CD音乐曲目(.WAV)、MIDI文件(.mid,.rmi,.midi)、Windows Media文件(.asx,.wax,.m3u,.wvx)、电影文件(.mpeg,.mpg,.m1v,.mp3)件(.wav,.snd,.au,.aif,.aifc)。

(2)能够由用户选择文件,能选择整个目录或多个文件,并添加到用户的播放列表。(3)能够自动循环播放用户播放列表里选定的文件。(4)能够提供媒体播放控制:打开、播放、暂停、停止、快进、快退、上一首、下一首。

(5)能够控制播放音量大小。

(6)能够显示媒体文件的播放进度以及控制播放进度。(7)能够随意移动播放界面。

(8)能够隐藏界面,并且能在显示界面和隐藏界面之间迅速切换。3.1.2 界面要求

(1)界面小巧美观,使用方便,有完善的操作控制按钮、进度指示条等。(2)能隐藏任务栏,在托盘上添加图标,能迅速显示界面和隐藏界面。(3)采用椭圆形和三角形的异型按钮。

(4)能修改控件背景颜色,避免与显示界面不协调。3.1.3 开发平台和开发工具

操作系统:Windows XP 开发工具:

16

(.cda)、数字化波形声音(.asf,.wm,.wma)、媒体播放表(.avi,.wmv)

Visual C++6.0 、视频文件、音频文

武汉科技大学本科毕业论文

3.2 系统分析

3.2.1 用例分析

本系统用户使用播放器,播放器完成媒体播放和音量控制两大功能。UML用例图如图3.1所示。

经典论文范例

用户 图3.1 播放器UML用例图

3.2.2 对象分析

本系统主要实现两大功能,所以建立以下的对象。

(1)操作界面:

属性:媒体文件名、路径、媒体播放进度、状态、音量信息。

方法:显示媒体文件信息(文件名、路径);

媒体播放控制:打开文件、播放、暂停、停止、快进、快退、上一首、下一首、循环播放;

显示播放信息(播放进度、状态);

控制音量,显示音量大小;

隐藏/显示界面。

(2)媒体播放:

属性:媒体文件名、路径、操作控制命令。

方法:打开文件、播放、暂停、停止、快进、快退、播放上一首、播放下一首、 循环播放。

(3)音量控制:

17

武汉科技大学本科毕业论文

属性:音量大小。

方法:放大音量、减小音量。

音量控制和媒体播放对象对界面管理存在依赖关系,这两个对象要从界面获取控制指令,它们的属性要在界面上显示。播放器的类图如图3.2所示。

经典论文范例

图 3.2 播放器类图

由于MFC中没有用于多媒体编程的类,而使用MCI命令与函数进行多媒体编程都要设置很多参数,使用不便。因此本系统采取自己创建用于媒体播放的类,封装要用到的MCI的方法和函数,隐藏所有MCI命令参数,仅留简单的操作接口,从而简化了MCI编程方式,便于重用和访问。

音量控制直接采用Audio Mixer编程控制,但也考虑到Audio Mixer编程比较复杂,因此也采取创建可以复用的类,将Audio Mixer中的打开、关闭音频设备、控制音量等函数封装起来,简化使用,也便于以后重用和访问。

18

武汉科技大学本科毕业论文

3.2.3 功能分析

系统功能结构图如图3.3所示。

经典论文范例

图3.3 功能结构图

3.3 界面设计

界面设计考虑到小巧美观和使用方便,满足以下要求: (1)界面首先要布置一系列按钮控件实现所有要实现的功能;

(2)设置“播放进度条”来指示多媒体文件的播放进度,还应该可以用鼠标拖动进度条来实现快进、快退,改变播放进度;

(3)设置列表框来显示用户选择的多媒体文件列表;

(4)设置滑块控件控制播放音量,考虑到为了不干扰用户正常工作,可以在后台运行,隐藏操作系统的状态栏,收缩成系统托盘中的小图标,并且能在显示界面和隐藏界面状态之间迅速切换;

(5)界面的设计小巧美观,避免呆板的窗口界面,因此采用了位图按钮、椭圆形按钮以及三角形按钮。

(6)改变控件背景颜色,避免与显示界面不协调。

19

武汉科技大学本科毕业论文

3.4 关键功能设计

3.4.1 媒体播放类设计

封装要用到的MCI的方法和函数生成CMedia类,数据成员用于描述类的内部属性,函数成员封装MCI操作接口。CMedia类的头文件定义了用于播放多媒体文件的所有函数及用到的变量。关键函数功能设计如下。

(1)OpenFiles()

OpenFiles()用于打开CFileDialog对话框,选取一个或多个媒体文件。OpenFiles()首先建立CFileDialog对话框对象并设置参数,然后调用DoModal()以模式对话框形式打开。为了支持选取多个文件或选取整个文件夹,在Media.h中定义了Cstring类型的数组m_FileList用于保存媒体文件的全路径,m_FileList最大可容纳256个媒体文件。OpenFiles()用GetStartPosition()获取第一个文件的位置,再逐次读取所选取的媒体文件全路径,存入m_FileList,并保存累加选取文件数目。最后调用Stop()先停止正在播放的媒体文件,再调用Play()从头开始播放已选择的媒体文件。

(2)SaveList()

SaveList()用于保存曲目列表。在OpenFiles()中选取要播放的媒体文件列表需要保存到文件中,SaveList()创建一个CFile类的对象实例fileList作为保存媒体文件列表的文件,逐个从在OpenFiles()中填好的m_FileList数组中取出媒体文件路径,写入文件fileList。

(3)InitPath()

InitPath()用于初始化播放列表文件的全路径。SaveList()创建一个CFile类对象来保存媒体文件全路径列表,InitPath()函数将该文件指定到MultiMediaPlayer程序的目录下,程序目录用WINAPI函数GetModuleFileName()来获取,存到Cstring型的m_MusicFilePath变量中传给SaveList()。

(4)OpenList()

OpenList()读取媒体文件路径列表,打开保存媒体文件列表的文件,逐个进行播放。CFile:Open()打开文件时指定modeRead属性,以只读方式打开,不影响原文件。

(5)Play()

Play()用于播放媒体文件。设置播放标志PlayingFalg,然后设置MCI_OPEN_PARMS和MCI_PLAY_PARMS对象的参数,播放文件指向m_FileList的第iPlayed个元素所保存的 20

武汉科技大学本科毕业论文

路径。向MCI设备发送打开命令消息并获取媒体文件播放长度、起点和终点,向MCI设备发送播放命令消息,实现文件播放。

(6)Next()

Next()用于播放下一个媒体文件。播放下一个媒体文件,则先将当前已播放的媒体文件数加1,若当前已播放的媒体文件数大于等于总文件数表示已播放到最后一个文件,则将当前已播放的媒体文件数置为0,从头开始。播放下一个文件时先停止播放当前文件,再调用Play(),播放m_FileList的第iPlayed个元素所指向的文件。

(7)Previous()

Previous()用于播放上一个文件。将当前已播放的媒体文件数减1,若已经退到头则指向最后一个文件, 当前已播放的媒体文件数从0开始,总文件数从1开始,停止播放当前文件再调用Play()。

(8)SpeedForward()

SpeedForward()用于快进播放。将播放的起始位置在当前位置的基础上增加文件总长度的1/15;若剩余长度不足1/15,则将播放的终点作为起始位置,此时将停止播放。

(9)SpeedBackward()

SpeedBackward()用于在播放中快退。将播放的起始位置前推总长度的1/15;若剩余长度不足1/15,则直接将播放的起点作为起始位置,此时将重新播放。

(10)OnTimer()

OnTimer()用于媒体文件的自动播放,在主程序中设置一个定时器,然后在主程序中重载OnTimer()。根据播放标志是否为真来判断是否正在播放,若正在播放,则调用OnTimer(),用getinfo()获取当前播放长度的等于歌曲的长度,若等于则说明已经播放完,调用Next()播放下一首。

3.4.2 音量控制类设计

创建CVolumeCtrl类,将有关AudioMixer的函数、结构、消息封装到一个类中。在类的头文件VolumeCtrl.h中包含mmsystem.h文件。定义CVolumeCtrl的两种构造函数以及四种音量控制函数。On()将音量开最大,Off()将音量关闭即静音,GetControlValue()获得音量,SetControlValue()设置音量。CVolumeCtrl::On()和CVolumeCtrl::Off()中分别以参数0和1调用SetControlValue(),就可以将音量设为最大和最小。参数为0,则音量为最大。 21

武汉科技大学本科毕业论文

4 系统实现

4.1 系统开发平台

本系统使用Visual C++ 6.0 作为开发工具。Visual C++是当前Windows应用开发系统中与Windows平台本身最具亲和性的开发平台之一。Visual C++ 6.0是一个全面的应用程序开发环境,它为程序开发人员提供了使用面向对象的C++来开发Windows应用程序的强大手段。可以使用Windows SDK文档提供的API进行Windows应用程序开发,也可以使用功能强大的MFC进行应用系统设计。支持可视化编程和支持面向对象的编程技术。Visual C++提供了一系列的可视化编程工具,它提供了各种向导和工具帮助程序开发人员来实现所需的功能,如AppWizard和ClassWizard等,它们使Windows编程更为直观,在一定程度上实现了软件的自动生成和可视化编程[9]。Visual C++支持的面向对象的编程技术包装了Windows内在的复杂的运行机制,通过微软基础类库MFC使Windows编程更为简单易学。此外,Visual C++ 6.0还具有其他技术特点:如通过ActiveX技术来支持Internet编程,支持ODBC数据库编程等。

Visual C++ 6.0是Visual Studio 6.0集成开发工具中的C++开发工具,Visual C++ 6.0由集成开发环境(IDE)、编译/链接器、诊断工具、MSDN等几大部分组成。Visual Studio将所有的开发工具都集成到统一的界面上,称为集成开发环境(IDE),为编写代码、编译程序提供一个方便的集成环境[10]。Visual C++ 6.0开发环境由一套综合的开发工具组成,它提供了良好的可视化编程环境,主要包括文本编辑器、资源编辑器、工程创建工具、Debugger调试器等。在该环境下,可以对C和C++程序进行各种操作,包括建立、打开、浏览、编辑、保存、编译、链接、调试等,而这些操作都可以通过鼠标单击工具按钮来完成,非常方便有效。

4.2 设计对话框

在AppWizard向导的第一步中,选择创建Dialog Based应用程序选项。

在工程管理窗口中选择Resource View选项卡,在Dialog文件夹上右击鼠标,在随后出现的弹出式菜单中,选择Insert Dialog选项,开发环境以可视化的形式提供了一个默认的对话框[11],将ID设为IDD_MULTIMEDIAPLAYER_DIALOG,把预置的按钮控件OK和Cancel删掉,然后选择控件箱中的控件添加到对话框,生成如图4.1所示的对话框。 22

武汉科技大学本科毕业论文

图 4.1 对话框设计图

用鼠标右击控件,在弹出的菜单中选择“属性”选项,在随后弹出的对话框中修改控件属性(ID,Styles,标题)。分别修改各控件属性,各控件属性设计如表4.1所示。

表4.1 控件属性说明

经典论文范例

经典论文范例

23

武汉科技大学本科毕业论文

用鼠标右击控件,在弹出的菜单中选择“建立类向导”选项[12],在随后弹出的对话框中选择Member Variables选项卡。选择“Add Variable”按钮,打开Add Member Variable对话框,定义变量的名称、类型,使控件和成员变量关联起来,各成员变量设计如表4.2所示。

表4.2 控件成员变量说明

经典论文范例

再选择Message Maps选项卡,为各控件声明消息映射和对应的消息响应函数。 选中控件的Object_Ids,在Messages选择消息,再按下Add Function打开Add Member Function对话框,修改消息函数名。

Class Wizard会自动在程序中添加消息映射、消息响应函数的声明等相应的代码。选择Edit Code将跳转到消息响应函数的代码,然后进行消息响应函数的编写

4.3 实现媒体播放类

在工程管理窗口中选择Class View选项卡,选中MultiMediaPlayer classes右击鼠标,选择New Class,建立CMedia类[13]。在Media.cpp文件中主要函数的具体实现如下。

(1)OpenFiles()

OpenFiles函数用于打开CFileDialog对话框,选取一个或多个媒体文件。 CFileDialog dlgFile(true); //打开对话框对象 dlgFile.m_ofn.Flags |= OFN_ALLOWMULTISELECT; //目录列表方式 dlgFile.m_ofn.lpstrFilter="所有媒体类型\0*.*\0\0";

24

武汉科技大学本科毕业论文

if(dlgFile.DoModal()!=IDOK)return FALSE; POSITION pos=dlgFile.GetStartPosition(); //获取第一个文件位置 int i=0;

while(pos){

m_FileList[i]=dlgFile.GetNextPathName(pos); //读取文件到曲目路径列表 i++;}

//保存选中的媒体文件总数 iSelected=i;

Stop();

Play(); //播放打开的文件

先停止当前媒体文件的播放,再调用Play()播放新选择的文件。iSelected保存用户选择的媒体文件总数。

(2)InitPath()

InitPath函数用于初始化播放列表文件的全路径。

//初始化路径,取得播放曲目列表文件的全路径

TCHAR path[256]; //保存文件路径

GetModuleFileName(NULL,path,sizeof(path)) ; //获取当前程序路径 TCHAR * p = _tcsrchr(path,_T('\\')) ; //查找最后一个'\\'字符 if(p)

(3)Getinfo()

Getinfo()用于获取媒体文件信息,根据调用参数获取媒体文件信息。

MCI_STATUS_PARMS mcistatusparms; //定义MCI_STATUS_PARMS对象 mcistatusparms.dwCallback=NULL; //初始化各参数

mcistatusparms.dwItem=item;

mcistatusparms.dwReturn=0; //返回值初始化

mciSendCommand(m_count,MCI_STATUS,MCI_STATUS_ITEM,(DWORD)&mcistatusparms); // MCI_STATUS查询状态

return mcistatusparms.dwReturn;

若调用参数为MCI_STATUS_LENGTH获取总播放时间,若调用参数为MCI_STATUS_POSITION获取当前已播放时间。

(4)Play()

Play()用于播放媒体文件。

25 lstrcpy(p,_T("\\MPlayer.mdr")); //替换为完整路径 m_MusicFilePath=path; //保存到路径变量中,用于打开列表文件

武汉科技大学本科毕业论文

PlayingFalg=TRUE; //置播放标志

//打开消息数据结构 //播放消息数据结构 MCI_OPEN_PARMS mciopenparms; MCI_PLAY_PARMS mciplayparms;

mciopenparms.lpstrElementName=m_FileList[iPlayed]; //播放路径

mciopenparms.lpstrDeviceType=NULL; //NULL为各种类型

mciSendCommand(0,MCI_OPEN,MCI_DEVTYPE_WAVEFORM_AUDIO,

(DWORD)(LPVOID)&mciopenparms); //向MCI设备发送打开命令消息

m_count=mciopenparms.wDeviceID; //记录当前播放的媒体在列表中的位置 mciplayparms.dwCallback=NULL; //窗口拥有者句柄

ItemLength=Getinfo(MCI_STATUS_LENGTH); //得到播放长度 ItemTo=MCI_MAKE_HMS(MCI_HMS_HOUR(ItemLength),

MCI_HMS_MINUTE(ItemLength),

MCI_HMS_SECOND(ItemLength)); //根据长度计算出时、分、秒

mciplayparms.dwFrom=MCI_MAKE_HMS(0,0,0); //播放起点

mciplayparms.dwTo=ItemTo; //播放终点

mciSendCommand(m_count,MCI_PLAY,MCI_TO|MCI_FROM,

(DWORD)(LPVOID)& mciplayparms); //发送播放命令消息 先把标志PlayingFalg置为TRUE,然后设置MCI_OPEN_PARMS和MCI_PLAY_PARMS对象的参数,播放文件指向m_FileList的第iPlayed个元素所保存的路径。再用Getinfo()获取媒体文件播放长度、起点和终点,用mciSendCommand发送给MCI设备。

(5)Stop()

Stop()用于停止播放媒体文件,将播放标志PlayingFalg置为FALSE,然后将当前文件的播放位置设置为文件开头,发送关闭消息,最后将当前播放媒体在列表中的位置m_count置为0。

PlayingFalg=false;

//关闭正在播放标志 //播放位置归文件开头

//发出关闭消息 ItemFrom=MCI_MAKE_HMS(0,0,0);

m_count=0;

(6)Pause()

Pause()用于暂停播放媒体文件,将播放标志PlayingFalg置为FALSE,发送暂停消息。 PlayingFalg=false;

//发送暂停命令消息 mciSendCommand(m_count,MCI_PAUSE,0,NULL);

26 mciSendCommand(m_count,MCI_CLOSE,0,NULL);

武汉科技大学本科毕业论文

(7)Continue()

Continue()函数将播放标志PlayingFalg置为TRUE,发送继续播放消息。

PlayingFalg=true;

(8)Next()

Next()用于播放下一个媒体文件。

iPlayed++;

if(iPlayed>=iSelected)iPlayed=iPlayed%iSelected;

Stop();

Play();

其中iPlayed是当前已播放的媒体文件数,iSelected为总文件数。播放下一个媒体文件,则先将iPlayed加1,若iPlayed大于等于iSelected表示已播放到最后一个文件,则将iPlayed置为0,从头开始。播放下一个文件时先停止播放当前文件,再调用Play,播放m_FileList的第iPlayed个元素所指向的文件。

(9)SpeedForward()

SpeedForward()用于快进播放。

MCI_PLAY_PARMS mciplayparms; //播放消息数据结构 ItemNow=Getinfo(MCI_STATUS_POSITION); //获取当前播放位置 if(ItemNow+ItemLength/15 < ItemTo)

mciplayparms.dwFrom=ItemNow + ItemLength/15; //改变播放起点 mciplayparms.dwFrom=ItemTo; else

mciplayparms.dwTo=ItemTo; //播放终点

mciSendCommand(m_count,MCI_PLAY,MCI_TO|MCI_FROM,(DWORD)(LPVOID)& mciplayparms); //发送播放消息

在当前位置ItemNow的基础上,增加当前媒体文件总播放长度的1/15;若剩余长度不足1/15,则直接将播放的终点作为起始位置,此时将停止播放。 mciSendCommand(m_count,MCI_RESUME,0,NULL); //发送播放命令消息

4.4 实现音量控制类

创建CVolumeCtrl类,将有关AudioMixer的函数、结构、消息封装到一个类中。在类的头文件VolumeCtrl.h中包含mmsystem.h文件。

SetControlValue()只需指定一个unsigned short类型的函数,就可设置Mixer音量, 27

武汉科技大学本科毕业论文

unsigned short类型取值范围为0~65536。SetControlValue()函数实现如下。

if (!m_bSuccess) return m_bSuccess;

m_bSuccess = FALSE; MIXERCONTROLDETAILS mxcd; MIXERCONTROLDETAILS_UNSIGNED mxcd_u; mxcd.cbStruct = sizeof(mxcd); mxcd.dwControlID = m_iMixerControlID; mxcd.cChannels = m_dwChannels; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(mxcd_u); mxcd.paDetails = &mxcd_u; mmr = mixerGetControlDetails((HMIXEROBJ)m_HMixer, &mxcd, 0L); if (MMSYSERR_NOERROR != mmr) return m_bSuccess; mxcd_u.dwValue = dw; mmr = mixerSetControlDetails((HMIXEROBJ)m_HMixer, &mxcd, 0L); if (MMSYSERR_NOERROR != mmr) return m_bSuccess; m_bSuccess = TRUE; return m_bSuccess; //设置MIXERCONTROLDETAILS结构的属性值

CVolumeCtrl::On()和CVolumeCtrl::Off()中分别以参数0和1调用SetControlValue(),就可以将音量设为最大和最小。参数为0,则音量为最大。On()和Off()若执行成功则返回TRUE。

4.5 界面实现

4.5.1 实现播放器背景

用Photoshop制作播放器背景图片,将制作的位图保存为player.bmp,将位图文件复制到项目目录的res文件夹下,创建新位图资源,右击鼠标弹出属性框,将ID改为IDB_Player,将文件路径及文件名指向player.bmp。如图4.2所示。

28

武汉科技大学本科毕业论文

图4.2 位图资源属性

为CMultiMediaPlayerDlg类添加WM_INITDIALOG消息映射,在OnInitDialog函数中调用OnDisplay(),载入位图ID_Player。

再在OnPaint函数中加上以下代码,完成显示播放器窗口。

else

{

} CClientDC dc(this); CDC memDC; memDC.CreateCompatibleDC(&dc); //创建一个内存设备,与dc所指定的一致 CBitmap bmp; bmp.LoadBitmap(IDB_PLAYER); //载入位图 CBitmap *pOldBmp; pOldBmp = memDC.SelectObject(&bmp); //将当前位图存入旧位图 BITMAP bm; bmp.GetBitmap(&bm); //获取位图 dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY); memDC.SelectObject(pOldBmp); //将旧位图选回设备 bmp.DeleteObject(); CDialog::OnPaint();

4.5.2 创建异型按钮

实现非矩形的异型按钮采用了公开的专门的类CUniButton,将UniButton.h和UniButton.cpp加入项目,在MultiMediaPlayerDlg.h文件中添加:

#include "UniButton.H"

为椭圆形按钮“Exit”、“Hide”和进度条旁边的三角形按钮添加消息映射。

经典论文范例

29

武汉科技大学本科毕业论文

BEGIN_MESSAGE_MAP(CMultiMediaPlayerDlg, CDialog)

//{{AFX_MSG_MAP(CMultiMediaPlayerDlg) ON_BN_CLICKED(BTN_EXIT, OnExit) ON_BN_CLICKED(BTN_HIDE, OnHide) ON_BN_CLICKED(BTN_BACK, OnBack) ON_BN_CLICKED(BTN_AHEAD, OnAhead) ON_WM_VSCROLL()

//}}AFX_MSG_MAP

在CMultiMediaPlayerDlg类的声明中声明这几个按钮的资源:enum { BTN_HIDE = 1100, BTN_EXIT = 1099, BTN_AHEAD = 1098, BTN_BACK = 1097};

在OnInitDialog函数中创建异型按钮,先指定按钮的原色和鼠标停靠时的颜色color1和color2,再创建椭圆形按钮,按钮文字为“Exit”:

HRGN c;

c = CreateEllipticRgn(0, 0, 49, 21);

m_BtnExit.Create("Exit", WS_CHILD|WS_VISIBLE, CPoint(265, 37), c, this, BTN_EXIT, 2, color1, color2, color2, GetSysColor(COLOR_BTNFACE));

HDC hDC = CreateCompatibleDC(GetDC() -> GetSafeHdc());

再用同样办法创建按钮“Hide”。

创建进度条两边的三角形按钮时要用函数MoveToEx()、LineTo()、EndPath()建立封闭区域。

BeginPath(hDC); //Ahead按钮

MoveToEx(hDC, 0, 0, NULL);

LineTo(hDC, 15, 12);

LineTo(hDC, 0, 24);

EndPath(hDC);

c = CreateRectRgn(0, 0, 63, 63);

c = PathToRegion(hDC);

m_BtnAhead.Create(" ", WS_CHILD | WS_VISIBLE, CPoint(270,110), c, this, BTN_AHEAD, 2, color2, color1, color1, GetSysColor(COLOR_BTNFACE));

DeleteObject(c);

4.5.3 创建位图按钮

在资源编辑器中创建对应于打开、暂停、继续、停止、下一首、上一首、快进、快退按钮的位图,分别设置ID[14]。

30

武汉科技大学本科毕业论文

在OnInitDialog函数中为各按钮装载位图。例如为“打开”按钮装载位图。 m_BtnOpen.LoadBitmaps(IDB_Open,IDB_Open);

为了实现暂停与继续的交替显示,声明一个BOOL型标志变量IsPause,在构造函数中将其置为0,在播放媒体文件期间若单击暂停按钮,则IsPause置1,调用CMedia::Pause函数,IDC_Pause按钮装载位图IDB_Contiue:

m_BtnPause.LoadBitmaps(IDB_Continue,IDB_Continue);

再次单击则IsPause状态反转置0,调用CMedia::Contiue函数,IDC_Pause按钮装载IDB_Pause位图。最后在Open(),Next(),SpeedFoward()等各按钮的响应函数中调用相应的CMedia类的播放控制函数,完成消息映射函数,以OnOpen()为例消息响应函数实现如下。

m_Media.OpenFiles(); //打开CFileDialog对话框 m_PlayList.ResetContent(); { CString str = m_Media.m_FileList[i]; } if(m_Media.iSelected!=0) { } m_PlayList.SetCurSel(0); //媒体文件列表框显示第一个媒体文件 UpdateData(FALSE); //刷新界面 IsPlaying = TRUE; IsPause = FALSE; m_BtnPause.LoadBitmaps(IDB_Pause,IDB_Pause); //装载暂停位图 m_PlayList.AddString(str); for(int i=0;i<m_Media.iSelected;i++) //将已选的曲目显示到ComboBox框里

4.5.4 实现隐藏窗口

在CMultiMediaPlayerDlg::OnHide()函数中实现隐藏播放器的界面,需声明_NOTIFYICONDATA结构类型的变量tnd,再声明函数OnHide(),并在原文件的消息映射中加上自定义消息的消息映射:

ON_MESSAGE(WM_SHOW_DIALOG, OnShow) //自定义消息的消息映射 WM_SHOW_DIALOG为自定义的显示消息。

OnHide先隐藏窗口:ShowWindow(SW_HIDE);

然后为tnd各数据成员赋值,在系统托盘中显示图标:

tnd.cbSize=sizeof(NOTIFYICONDATA);

31

武汉科技大学本科毕业论文

tnd.hWnd=this->m_hWnd;

tnd.uID=IDI_ICON1;

tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;

tnd.uCallbackMessage=WM_SHOW_DIALOG;

tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1)); Shell_NotifyIcon(NIM_ADD,&tnd);

显示按钮响应函数OnShow()与OnHide()函数类似。

4.5.5 实现播放进度条控制

在对话框资源上放置一个Slider控件,将其ID设为IDC_PlaySlider,设置为横向,用ClassWizard添加WM_HSCROLL消息响应,创建数据变量ProgressBar[15]。

在OnInitDialog函数设置播放进度控制条的最大值、最小值、刻度等属性:

m_ProgressBar.SetRange(0,100,TRUE); m_ProgressBar.SetTic(0); m_ProgressBar.SetTicFreq(10);

拖动或单击播放进度条控制滑块会发出WM_HSCROLL消息,会调用消息响应函数OnHScroll()。若滑块超前,则快进,直到播放比例与进度条指示相同;若滑块滞后,则快进,直到播放比例与进度条指示相同。

4.5.6 实现音量控制

实现音量控制与播放进度条控制相似,在对话框资源上放置另一个Slider控件,设为IDC_VolumeSlider,设为Vertical类型,用ClassWizard添加WM_VSCROLL消息响应,创建int型数据变量m_iVolume和控制变量m_VolumeSlider[15]。

在OnInitDialog函数设置播放音量控制条的最大值、最小值、初始值等属性:

m_VolumeSlider.SetRange(0, 65000); m_VolumeSlider.SetPos(m_iVolume);

拖动或单击音量进度条控制滑块改变其位置,会调用WM_VSCROLL消息响应函数OnVScroll(),其中先获取滑块位置,再创建CVolumeCtrl类的对象mixer,以(65000-m_iVolume)为参数调用CVolumeCtrl::SetControlValue。

UpdateData(TRUE);

m_iVolume = m_VolumeSlider.GetPos(); //由音量滑块位置设定音量

CVolumeCtrl

mixer(m_hWnd,MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,

32

武汉科技大学本科毕业论文

NO_SOURCE,MIXERCONTROL_CONTROLTYPE_VOLUME);

mixer.SetControlValue(65000-m_iVolume);

UpdateData(FALSE);

CDialog::OnVScroll(nSBCode, nPos, pScrollBar);

4.5.7 实现选择文件列表

在媒体文件列表框中存储已选定的文件的全路径与文件名,这个功能在“打开”位图按钮响应函数OnOpen()中实现。

单击“打开”按钮时,首先调用CMedia::OpenFiles()函数打开通用文件选择对话框CFileDialog选择文件或目录,然后调用CcomboBox::ResetContent()来刷新ComboBox框,再逐个将已选文件加入ComboBox框,ComboBox框默认显示第一个选择的文件。

4.5.8 实现对话框的移动

通过三个消息响应函数OnLButtonDown(), OnMouseMove(),OnLButtonUp()实现控制对话框的移动,并添加相应消息映射。在资源编辑器中制作一个光标的资源。

当鼠标左键按下时,捕获光标,并得到当前光标的位置,将光标显示设置为光标资源(IDC_CURSOR1)。鼠标移动时,计算光标的位置,得到对话框的移动距离。当鼠标左键放开时,释放鼠标,恢复光标显示为箭头。OnLButtonDown()函数实现如下。

m_bIsMoveing = true;

m_cLastPoint = point;

m_iMoveCount = 0;

SetCapture(); //捕获光标

SetCursor( AfxGetApp()->LoadCursor( IDC_CURSOR1 ) );//光标显示置为光标资源 CDialog::OnLButtonDown(nFlags, point);

OnMouseMove()函数实现如下。在函数中计算出对话框的移动距离。

CRect rect;

GetWindowRect(rect);

int x = rect.left + point.x - m_cLastPoint.x ;

int y = rect.top + point.y - m_cLastPoint.y ;

SetWindowPos(NULL,x,y,0,0,SWP_NOZORDER|SWP_NOSIZE);

m_cLastPoint = point;

33

武汉科技大学本科毕业论文

4.5.9 实现控件颜色的修改

首先在CMultiMediaPlayerDlg类中建立一个画刷,在构造函数中初始化画刷时设置画刷的颜色。m_BkBrush.CreateSolidBrush( RGB(112,211,243) );

将画刷设置为与背景位图同样的颜色,避免不协调。并将媒体文件列表框保持为原来的颜色。

if( pWnd->GetDlgCtrlID() == IDC_PlayList ) //将PlayList保持为原来颜色 { } pDC->SetBkMode( TRANSPARENT ); //其余控件设置成背景位图的颜色 return m_BkBrush; HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); return hbr;

4.6 系统运行

运行MultiMediaPlayer.EXE播放歌曲和视频文件,结果如图4.3所示。

经典论文范例

图4.3 运行界面

34

武汉科技大学本科毕业论文

5 结论

整个系统的开发过程遵循了软件工程开发流程。首先进行了需求分析,分析了系统的背景、功能需求、界面要求、开发平台和开发工具;然后确定了系统的两大功能,并确定了系统的功能模块,随后进行了界面设计,最后着手进行系统的具体实现,后通过不断的调试使运行正确,并设置了黑盒测试内容,对系统进行了各方面的测试。本系统采取自己创建用于媒体播放的类,封装要用到的所有MCI命令参数,仅留简单的操作接口,音量控制也采取创建可以复用的类,将量等函数封装起来,简化使用,采用了三角形按钮、位图按钮和椭圆按钮。本系统实现了播放主流的多媒体影音文件以及自动循环播放和各种媒体播放控制功能,并实现了界面的隐藏和显示的迅速切换。但是本系统的功能还比较简单,只涉及到几个功能模块,还没有完全包括媒体播放器的所有功能。在吴志芳老师的指导下,通过本次设计,让我受益匪浅,我掌握了关于程方法以及关于Audio Mixer

从而简化MCIAudio Mixer中的打开、关闭音频设备、控制音同时本系统为了避免呆板的窗口界面,

35

完成之MCI的方法和函数,隐藏便于重用和访问。MCI的编

编程方式,也便于以后重用。

的编程,为深入多媒体应用编程奠定了基础。

武汉科技大学本科毕业论文

参考文献

[1] 陈坚,陈伟.Instant Visual C++.NET [M].北京:宇航出版社,北京希望电子出版社,

2002.255~271

[2] 杨富国.Visual C++程序开发案例解析[M].北京:清华大学出版社,北京交通大学出

版社,2006.157~191

[3] Jeffrey Richter. Programming Applications for Microsoft Windows[M]. New York:

Microsoft Press, 1999. 14~15

[4] 吕军,杨琦,刘路放.Visual C++与面向对象程序设计教程[M].(第2版).北京:高

等教育出版,2003.160~279

[5] George Shepherd, Scot Wingo. MFC Internals[M]. New York: Addison-Wesley, 1996.

112~146

[6] Charles Petzold. Programming Windows[M]. New York: Microsoft Press, 1999.

168~220

[7] 龚志翔.Visual C++编程实例与技巧集粹[M].北京:兵器工业出版社,北京希望电

子出版社,2004.350~425

[8] 隋成城,周博.Visual C++.NET基础教程[M].北京:机械工业出版社,2004.214~219

[9] 侯俊杰.深入浅出MFC [M].(第2版).武汉:华中科技大学出版社,2001.409~464

[10] 任哲.MFC Windows应用程序设计[M].北京:清华大学出版社,2004.149~203

[11] Chris H Pappas, William H Murray. Visual C++ 6参考大全[M].希望图书创作室译.

北京:北方交通大学出版社,1999.555~706

[12] Jeff Prosise. Programming Windows with MFC[M]. (2nd Ed). New York: Microsoft

Press, 1999. 3~29

[13] Andrew Koenig, Barbara E Moo. Accelerated C++ Practical Programming by

Example[M]. New York: Addison-Wesley, 2000. 55~81

[14] David J kruglinski. Programming Visual C++[M]. New York: Microsoft Press, 1998.

21~42

[15] 严华峰.Visual C++精彩编程百例[M].北京:中国水利水电出版社,2002.115~117

36

武汉科技大学本科毕业论文

致谢

本系统能够顺利完成首先要感谢我的毕业设计指导老师吴志芳在百忙之中抽出时间给予精心的指导和热情的帮助。

还要感谢班主任邵平凡老师四年来的谆谆教诲和关心帮助,感谢计算机学院的领导和老师的帮助、教导。

谨此向所有教育过我的老师们表示崇高的敬意和真挚的谢意。

也感谢同组的同学在毕业设计的过程中给予的支持和帮助,同样也要感谢同寝室成员的支持和鼓励,还要感谢王海龙和胡浩在VC编程方面给我排难解惑。

向这些给予我帮助的同学致以衷心的谢意。

最后,感谢身在远方的父母给我生活上的关怀和精神上的鼓励。

37

相关推荐