using System;
using System.Collections;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace ChessGame
{
/// <summary>
/// 用于播放音乐
/// </summary>
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);
}
}
}
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类打开一个文件选择对话框,让用户选择一个文件名,然后你调用函数来播放。这取决于你的具体需要了。