一个PlaySound示例:
程序块
using System;
using System.Collections;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace ChessGame
{
///
/// 用于播放音乐
///
internal class Helpers
{
[Flags]
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000, /* play synchronously (default) */ //同步
SND_ASYNC = 0x0001, /* play asynchronously */ //异步
SND_NODEFAULT = 0x0002, /* silence (!default) if sound not found */
SND_MEMORY = 0x0004, /* pszSound points to a memory file */
SND_LOOP = 0x0008, /* loop the sound until next sndPlaySound */
SND_NOSTOP = 0x0010, /* don't stop any currently playing sound */
SND_NOWAIT = 0x00002000, /* don't wait if the driver is busy */
SND_ALIAS = 0x00010000, /* name is a registry alias */
SND_ALIAS_ID = 0x00110000, /* alias is a predefined ID */
SND_FILENAME = 0x00020000, /* name is file name */
SND_RESOURCE = 0x00040004 /* name is resource name or atom */
}
[DllImport("winmm")]
public static extern bool PlaySound( string szSound, IntPtr hMod, PlaySoundFlags flags );
}
public class Sound
{
public static void Play( string strFileName )
{
//Helpers.PlaySound( strFileName, IntPtr.Zero, Helpers.PlaySoundFlags.SND_FILENAME | Helpers.PlaySoundFlags.SND_ASYNC );
switch(strFileName)
{
case "start": strFileName=@"..\..\sound\start.WAV"; break;
case "back": strFileName=@"..\..\sound\back.WAV"; break;
case "fall": strFileName=@"..\..\sound\fall.WAV"; break;
case "huiqi": strFileName=@"..\..\sound\huiqi.WAV"; break;
case "huiqiend": strFileName=@"..\..\sound\huiqiend.WAV"; break;
case "jiangjun": strFileName=@"..\..\sound\jiangjun.WAV"; break;
case "kill": strFileName=@"..\..\sound\kill.WAV"; break;
case "win": strFileName=@"..\..\sound\win.WAV"; break;
case "move": strFileName=@"..\..\sound\move.WAV"; break;
case "hold": strFileName=@"..\..\sound\hold.WAV"; break;
case "no": strFileName=@"..\..\sound\no.WAV"; break;
case "popup": strFileName=@"..\..\sound\popup.WAV"; break;
case "mayfall": strFileName=@"..\..\sound\mayfall.WAV"; break;
case "return_red": strFileName=@"..\..\sound\return_red.WAV"; break;
case "return_blue": strFileName=@"..\..\sound\return_blue.WAV";break;
}
Helpers.PlaySound(strFileName, IntPtr.Zero, Helpers.PlaySoundFlags.SND_FILENAME | Helpers.PlaySoundFlags.SND_ASYNC);
}
}
}
2007年12月17日 14:13Vecent 0登录进行投票你好!我是一个初学者。对概念掌握得不好。我想请问一下:API和DLL哪个范围更大些?我个人认为应该是DLL包括API吧。还有。Native API是什么啊?
如果你要是想调用声音文件,你会怎么做呢?是用控件还是用函数?
2007年12月17日 14:35Vecent 0登录进行投票ChengKing你好!
你能给我简单讲讲这个程序的含义吗?我没太看懂。“0x0000、0x0004……”是什么意思?还有
strFileName=@"..\..\sound\start.WAV"; ……。这些是winmm.dll里的函数参数吧。它们代表什么函义啊?还有[flags]在这里表示什么?(我在MSDN里没找到)能给我讲讲吗?
先谢谢啦!
2007年12月17日 15:37RickyLin版主 0登录进行投票我的理解是:
API是应用程序接口,DLL是动态链接库。DLL相当于一个载体,API算是一种概念。我觉得可以这么说,DLL中载有API。
有了.NET,就有了托管和非托管之说,Native API一般就是那种非托管语言写出来的API,托管语言写出来的API一般都编译为MSIL,应该算是一种与具体硬件无关的代码,而Native DLL则是被编译成硬件相关的二进制代码,比如针对X86架构的代码,所以叫本地代码。
2007年12月17日 15:43RickyLin版主 0登录进行投票[Flags]请参考:FlagsAttribute 类
ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref2/html/T_System_FlagsAttribute.htm
0x0004代表16进制数字4。
[DllImport("winmm")]
public static extern bool PlaySound( string szSound, IntPtr hMod, PlaySoundFlags flags );
这个才是winmm.dll里的函数。
包含0x0000、0x0004的只是定义了一个枚举,符合winmm.dll中PlaySound函数的PlaySoundFlags参数的要求格式。
2007年12月18日 2:01Vecent 0登录进行投票 RickyLin你好!你给的链接我点不进去啊。我看了一下MSDN。FlagsAttribute 类里面没有带中括号的这种啊。加了中括号表示什么啊?是托管吗?还是表示数组维数?还有就是“0x0000、0x0004……”是固定的还是自己定义的呢?
哦。对了。还有,http://msdn2.microsoft.com/zh-cn/library/ms229685.aspx这是MSDN上的相关介绍。它调用的是CoreDll.DLL,用的是“WCE_PlaySound”和“WCE_PlaySoundBytes”函数。它们有什么区别吗?
2007年12月18日 9:27RickyLin版主 0登录进行投票[Flags]这种写法是属性的语法,你也可以写成[FlagsAttribute],通常可以省略Attribute而写成[Flags],具体可以查查MSDN上有关属性(Attribute)的内容。
连接点不进去,可能你没有在本地安装MSDN相关的内容。
ox0000等是那个函数的参数的固定要求,我们必须遵守。
那些PlaySound函数,我不懂,没用过。
2007年12月18日 11:55Vecent 0登录进行投票您好!感谢你的热心帮助。我还有一个问题。如果我想让声音返复播放。应该怎么办呢?是不是把SND_LOOP = 0x0008中的“0x0008”改成其他数值?如果是改成什么数值呢?还有就是语句
case "start": strFileName = @"D:\vbfun10\tada.wav"中地址是不是写死了的。也就是说我生成可执行程序后放到其他机器上是不是就不能用吗?是否能放到indowsApplication1.Properties.Resources中呢?
2007年12月18日 14:49RickyLin版主 0登录进行投票SND_LOOP = 0x0008这是定义,不应该改的。
参考前面的例子,应该写成:
Helpers.PlaySound(strFileName, IntPtr.Zero, Helpers.PlaySoundFlags.SND_FILENAME | Helpers.PlaySoundFlags.SND_ASYNC|PlaySoundFlags.SND_LOOP);
就是把SND_LOOP也或到参数中,这样SND_LOOP就会整合到其他2个枚举值当中,让3个枚举值同时起作用
你要明白PlaySoundFlags是一个枚举,而且这里PlaySoundFlags枚举是可以按位进行或运算的。
拿枚举中的前4个声明举例
SND_SYNC = 0x0000
SND_ASYNC = 0x0001
SND_NODEFAULT = 0x0002
SND_MEMORY = 0x0004
SND_LOOP = 0x0008
0x0000代表两个字节(等于一个字),就是16位二进制数字位。
为了说明这种可以按位或的枚举如何可以让多个枚举值同时其作用,我们简化一下,简化成
SND_SYNC = 0x00
SND_ASYNC = 0x01
SND_NODEFAULT = 0x02
SND_MEMORY = 0x04
SND_LOOP = 0x08
也就是说简化成用1个字节的二进制位定义
0x00转换成十进制就是0(16进制0-9和十进制0-9对应相等),换成一个字节8位二进制位就是 0000 0000
0x01换成一个字节8位二进制位就是 0000 0001
0x02-------------------------------------------> 0000 0010
0x04-------------------------------------------> 0000 0100
0x08-------------------------------------------> 0000 1000
看出什么特点了吗?
每个定义,占用8个二进制位中的1个。
二进制或是什么意思呢?就是按照顺序每一位进行比较,如果2个位中其中有一个是1,结果就是1。
这样Helpers.PlaySoundFlags.SND_ASYNC|PlaySoundFlags.SND_LOOP的计算结果就是 0000 1001
如果我们是计算机的话,我们就可以这么认为,8位二进制位,从右向左,某一位是1的话,对应的功能就启用,否则就不启用。
这样对于0000 1001,参照枚举定义,就知道SND_ASYNC和SND_LOOP启用,将来我们想增加一个SND_MEMORY,就把它或到当前的计算中,计算结果是 0000 1101,按照上面计算机的逻辑,自然SND_ASYNC、SND_LOOP、SND_MEMORY都起作用了。
说的有点啰嗦,应该能看懂吧。
至于switch... case...,因为是写例子,所以写死了。正常的话,可以用OpenFileDialog类打开一个文件选择对话框,让用户选择一个文件名,然后你调用函数来播放。这取决于你的具体需要了。
2007年12月19日 5:02Vecent 0登录进行投票非常感谢!说得很详细。
还有最后一个问题(不好意思,忘了问了):case "start": strFileName = @"C:\WINDOWS\Media\start.wav"中的“@”表示什么含义?它属于关键字还是运算符?不用它直接用路径字符串不行吗?还是说这个API函数中的参数就是要求这样输入?
2007年12月19日 6:25feiyun0112MVP, 版主 0登录进行投票 Vecent 写: 非常感谢!说得很详细。
还有最后一个问题(不好意思,忘了问了):case "start": strFileName = @"C:\WINDOWS\Media\start.wav"中的“@”表示什么含义?它属于关键字还是运算符?不用它直接用路径字符串不行吗?还是说这个API函数中的参数就是要求这样输入?
用 @ 引起来的优点在于换码序列“不”被处理,这样就可以轻松写出字符串
@"c:\Docs\Source\a.txt" // rather than "c:\\Docs\\Source\\a.txt"
这是C#的基本概念,和api无关
另外说一下CoreDll.dll 是Windows CE 中的文件
2007年12月19日 6:39Vecent 0登录进行投票呵呵,问题越问越多。
我想了解一下“@”这个符号的用法。能给个MSDN或者其它网站的地址吗?
还有,Windows CE是什么?是不是在windows xp中就没有这个DLL?
不好意思。麻烦各位了。
2007年12月19日 7:11feiyun0112MVP, 版主 0登录进行投票
http://msdn2.microsoft.com/zh-cn/library/362314fe(VS.80).aspx
http://wiki.ccw.com.cn/Windows_CE 2007年12月19日 8:03Vecent 0登录进行投票我明白了。非常感谢!
2007年12月19日 8:18Vecent 0登录进行投票还有,我想标记一个帖子为答案、多个帖子为“有帮助”。应该怎样弄?
2007年12月19日 10:32Vecent 0登录进行投票哦。我又想到一个问题。声音文件是否可以添加到“Resources”文件夹下。用WindowsApplication1.Properties.Resources来调用?
2007年12月19日 17:49Shiny ZhuMVP, 版主 0登录进行投票此帖恐怕是中文论坛里最火的吧?
偶也一直在关注.讨论非常有意义.
我来回答上面的问题,
声音文件可以添加到Resources文件夹下,具体操作步骤如下:
打开项目的属性页: 右键项目,然后选择属性.
然后选择Resources这个Tab,这个时候应该会看到字符串的一个表格.
在表格左上角,有一个下拉框,选择Audio.
可以直接Ctrl+C,Ctrl+V把声音文件添加进来.
保存即可.
另外,标记解答和标记有帮助,直接在每个回复的上面有一栏,直接点击就行了.
2007年12月20日 2:21RickyLin版主 0登录进行投票看来是最火的帖子,呵呵。
虽然可以放到Resources里面,但是我记得当需要取出来的时候,只能用流(Stream)的形式取出。你要播放的话,需要用支持流输入的播放控件才行吧,或者把流再存到一个磁盘文件中去……
2007年12月20日 4:18Vecent 0登录进行投票呵呵。是因为我水平太菜了。什么都不会。什么都不知道。所以才这么火。
“Shiny Zhu”:你好!你说的“右键项目,然后选择属性.”是说的点击解决方案“WindowsApplication1”的属性吗?
我点了。怎么没有啊?
http://photo9.hexun.com/p/2007/1220/156621/b_9265E50B39D7357E31739898E2B57188.jpg
我用的是VS2005
2007年12月20日 4:30feiyun0112MVP, 版主 0登录进行投票程序块
[DllImport("winmm.dll", EntryPoint = "sndPlaySound")]
public static extern bool sndPlaySound(ref Byte snd, int fuSound);
System.Byte[] sound = new Byte[Properties.Resources.Windows_XP_Startup.Length];
Properties.Resources.Windows_XP_Startup.Read(sound, 0, (int)Properties.Resources.Windows_XP_Startup.Length);
sndPlaySound(ref sound[0], 0x05);
不过我建议如果还有问题,最好再开新贴吧
2007年12月20日 6:42Shiny ZhuMVP, 版主 0登录进行投票就这个,在左边的TAB里选择"资源".
2007年12月20日 7:54Vecent 0登录进行投票找到了。谢谢!
2007年12月20日 9:32东软的辉煌 0登录进行投票感觉LZ问的某些问题。。应该先自己看书。。。然后在问。。。
2008年1月4日 13:05ChengKing版主 0登录进行投票To 楼主:
1.
A: 你能给我简单讲讲这个程序的含义吗?我没太看懂。“0x0000、0x0004……”是什么意思?
Q: 0x0000,0x0004 等是一些枚举常量的值, 比如: 用来控制播放声音时是同步还是异步.
strFileName
2.
A: strFileName=@"..\..\sound\start.WAV"; ……。这些是winmm.dll里的函数参数吧。它们代表什么函义啊?
Q: 这里不是winmm.dll函数的, 是自己定义的一些声音文件路径, 这些声音是我预先准备到项目sound文件夹中的.
2008年1月4日 13:06ChengKing版主 0登录进行投票To 楼主:
1.
A: 你能给我简单讲讲这个程序的含义吗?我没太看懂。“0x0000、0x0004……”是什么意思?
Q: 0x0000,0x0004 等是一些枚举常量的值, 比如: 用来控制播放声音时是同步还是异步.
strFileName
2.
A: strFileName=@"..\..\sound\start.WAV"; ……。这些是winmm.dll里的函数参数吧。它们代表什么函义啊?
Q: 这里不是winmm.dll函数的, 是自己定义的一些声音文件路径, 这些声音是我预先准备到项目sound文件夹中的.
源可以运行的程序在这里:
http://blog.csdn.net/chengking/archive/2005/11/06/524162.aspx
中的第六个. 你可以下载运行一下.