| The .NET platform does not
provide intrinsic classes to play sounds- these are handled natively in
the Windows APIs resident in the Winmm.dll library. However, once you've
isolated the API calls, it's no more difficult to play WAV files, and
even WAV files stored in your assembly as embedded resources - than in
any other language.
I wanted to embed a couple of handy WAV files in an assembly to be able
to play them on demand for various events raised in one of my creations,
and so I put together this handy class, which can simply be added to any
project, to provide static access to the PlaySound export for embedded
resources. There are several overloads, the one we want accepts a byte
array containing the resource, an IntPtr and UInt32 flags parameter which
as with many API calls is the result of performing an OR method against
defined constants. The beauty of my little creation is that it can normally
be added to any project as is, and uses Reflection to get the namespace
of the assembly dynamically.
To add WAV files as embedded resources, simply ADD them to your project
and set the property attribute of each to "Embedded Resource",
and .NET takes care of the rest.
First, here's the class - you can see I've given it a namespace and class
name that reflect where the call is being made to:
using
System;
using System.Runtime.InteropServices;
using System.Resources;
using System.IO;
namespace Win32
{
public class Winmm
{
public const UInt32 SND_ASYNC = 1;
public const UInt32 SND_MEMORY = 4;
// these 2 overloads we dont need ...
// [DllImport("Winmm.dll")]
// public static extern bool PlaySound(IntPtr rsc, IntPtr hMod, UInt32
dwFlags);
// [DllImport("Winmm.dll")]
// public static extern bool PlaySound(string Sound, IntPtr hMod,
UInt32 dwFlags);
// this
is the overload we want to play embedded resource...
[DllImport("Winmm.dll")]
public static extern bool PlaySound(byte[] data, IntPtr hMod, UInt32
dwFlags);
public Winmm()
{
}
public static void PlayWavResource(string wav)
{
// get the namespace
string strNameSpace=
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToString();
// get the resource into a stream
Stream str =
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(
strNameSpace +"."+ wav );
if ( str == null )
return;
// bring stream into a byte array
byte[] bStr = new Byte[str.Length];
str.Read(bStr, 0, (int)str.Length);
// play the resource
PlaySound(bStr, IntPtr.Zero, SND_ASYNC | SND_MEMORY);
}
}
}
|
To use the class, we would make the call as follows:
private void button2_Click(object
sender, System.EventArgs e)
{
Win32.Winmm.PlayWavResource("chimes.wav");
}
N.B. Reader Jim McLendon converted the class
to VB.NET for those who are interested, and has posted his code on our
forums. You can
view it here.
That's all there is to it! The download has a complete
solution, including the famous "chimes.wav" and "chord.wav"
that everyone has, I am sure, heard many times.
Download
the code that accompanies this article
| Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform. Pete's samples at GotDotNet.com have been downloaded over 41,000 times. You can read Peter's UnBlog Here. --><-- NOTE: Post QUESTIONS on FORUMS! |  |
Do you have a question or comment about this article? Have a programming problem you need to solve? Post it at eggheadcafe.com forums and receive immediate email notification of responses.
|