Click here to Skip to main content
15,881,849 members
Articles / Programming Languages / C#
Article

Play Windows sound events defined in system Control Panel

Rate me:
Please Sign up or sign in to vote.
4.21/5 (19 votes)
11 Aug 2002CPOL3 min read 190.7K   1.1K   40   17
Play system sounds defined in Control Panel and other wave files.

Sample Image - windowssoundevents.jpg

Introduction

Windows plays sounds if you click somewhere, or if an error occurs. If you logoff, Windows plays a logoff sound. Did you ever want to use something similar in your application, e.g. if you'd like to play a certain sound if your application does something special?

The .NET framework support no sounds at this time, so we have to use the API method PlaySound located in the winmm.dll. We have to include this method into our C# Project like this.

cs"
[DllImport("winmm.dll", EntryPoint="PlaySound",CharSet=CharSet.Auto)]
private static extern int PlaySound(String pszSound, int hmod, int falgs);

First problem fixed...

Sound events

The sound events are stored in the registry, this is done by user. So the settings can be found under HKEY_CURRENT_USER. Windows supports Sections, this means every application can create/use it's own section. We're able to add a new Section for our application. But Windows knows also the Sound Schemes, which can be chosen and altered by the user. Because of this it's not very easy to read the sound events in registry, but it's possible.

Every sound event is based on :

  • .default Wave file defined by the vendor of the application.
  • .current Wave file currently used for this sound event.
  • HKEY_CURRENT_USER\AppEvents\EventLabels\<EVENTNAME> Description used to display sound event.

With this knowledge, we can rebuild the control panel view of the system sounds. We're also able to add our own sound events to registry. All we have to do is create some registry keys at the right position.

How to play sound events

The PlaySound method supports the playing of normal wave files stored on the disk. But it also supports playing sound events from registry. The registry key, which defines the sound event, is the verb we need to send to PlaySound method. Otherwise we have to send the file path to the method. There are different parameter flags used, defined in a C# Enum.

cs"
public enum SND
{
    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 pre d ID */
    SND_FILENAME     = 0x00020000, /* name is file name */
    SND_RESOURCE     = 0x00040004, /* name is resource name or atom */
    SND_PURGE        = 0x0040,  /* purge non-static events for task */
    SND_APPLICATION  = 0x0080 /* look for application specific association */
}

Playing a wave file located on the disk looks like this, pszSound is the file path.

C#
public static void PlaySound(String pszSound)
{
    if(File.Exists(pszSound))
    {
        PlaySound(pszSound,0,
          (int) (SND.SND_ASYNC | SND.SND_FILENAME | SND.SND_NOWAIT));
    }
}

Otherwise, if we play a sound event, it looks like this, pszSound is the event verb.

C#
public static void PlaySoundEvent(String pszSound)
{
    PlaySound(pszSound,0,
      (int) (SND.SND_ASYNC | SND.SND_ALIAS | SND.SND_NOWAIT));
}

How to display sound events

The next step is to fill a TreeView control like the one filled in the control panel. We have to read all the application sections, in the default scheme. After that, we could load sound events for each section. If you click a TreeNode, we play the sound defined by this sound event, sounds nice?

First we need to open the AppEvents\Schemes\Apps key located under HKEY_CURRENT_USER. After that, we could read all subkeys into a string array.

C#
RegistryKey rkey = Registry.CurrentUser;
RegistryKey rkey1=rkey.OpenSubKey("AppEvents\Schemes\Apps");
string[] sections = rkey1.GetSubKeyNames();

Now we've got the names of the application sections, next we read the display string for each section stored in the default value of the key.

C#
// open reg key
for(int i=0;i<sections.Length;i++)
{
    // read section name
    rkey1=rkey.OpenSubKey(
        @"AppEvents\Schemes\Apps\" + sections[i]);
    // read section name
    try 
    {
        string sectionName = rkey1.GetValue("").ToString();
    } 
    catch {}
}

Now we read the subkeys of the section key, these are the sound event verbs.

C#
// read subkeys
string[] subsections = rkey1.GetSubKeyNames();
for(int j=0;j<subsections.Length;j++)
{
    rkey1=rkey.OpenSubKey(
        @"AppEvents\EventLabels\" + subsections[j]);
    try 
    {
        string eventName = rkey1.GetValue("").ToString();
    } 
    catch {}
}

Finish our work and close all resources allocated.

C#
rkey1.Close();
rkey.Close();

If you like, you could fill this information into a TreeView, like I did it in my demo application. If you click on a TreeNode, you can play the sound event.

Have phun with it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Switzerland Switzerland
My interest is in the future because I am going to spend the rest of my life there. (Charles Kettering)

Biography

  • 1996 - 1998 PC Board PPL, HTML, DHTML, Javascript and ASP
  • 1999 - 2001 coding Centura against Sql Database (SqlBase,MSSQL,Oracle)
  • 2002 - 2004 C# Windows Forms
  • 2005 - 2006 C# ASP.NET, Windows Forms
  • 2006 - 2009 C#, WCF, WF, WPF
  • 2010 - 2012 C#, Dynamics CRM, Sharepoint, Silverlight
  • 2013 - 2013 C#, WCF DS (OData), WF, WPF
  • 2014 - 2016 C#, Azure PaaS, Identity, OWIN, OData, Web Api
  • 2017 - now C#, aspnet.core, IdentityServer4, TypeScript & Angular @ Azure IaaS or PaaS

Interests

  • family & friends
  • chilaxing ,)
  • coding

Comments and Discussions

 
GeneralNice tute Pin
koonkii9-Feb-10 1:36
koonkii9-Feb-10 1:36 
GeneralAdding Screensaver Event Sounds Pin
Brillo216-Nov-05 10:39
Brillo216-Nov-05 10:39 
GeneralPlay Explorer Navigating sound Pin
Mike Wild in New Zealand27-Jan-03 17:16
Mike Wild in New Zealand27-Jan-03 17:16 
GeneralRe: Play Explorer Navigating sound Pin
Shane Story26-Jan-04 12:08
Shane Story26-Jan-04 12:08 
Me too Mike.. I had my own code and get the same results.
Had hoped this would work but I get the same problem you do...

with my code or another.

I can't call my own custom events or even those of MSN Messenger.

The windows ones are read from the same control panel app...thus guaranteed to work.

if you have a solution please email me.


Shane

Shane
GeneralRe: Play Explorer Navigating sound Pin
Shane Story26-Jan-04 12:45
Shane Story26-Jan-04 12:45 
GeneralPlay sound (.wav) file from a resource . . . Pin
stantheman4-Oct-02 6:11
stantheman4-Oct-02 6:11 
GeneralRe: Play sound (.wav) file from a resource . . . Pin
Chris Richner4-Oct-02 11:01
Chris Richner4-Oct-02 11:01 
GeneralRe: Play sound (.wav) file from a resource . . . Pin
Chris Richner15-Oct-02 8:29
Chris Richner15-Oct-02 8:29 
GeneralRe: Play sound (.wav) file from a resource . . . Pin
BigRedwood6-Nov-02 13:17
BigRedwood6-Nov-02 13:17 
GeneralRe: Play sound (.wav) file from a resource . . . Pin
stantheman8-Nov-02 2:27
stantheman8-Nov-02 2:27 
GeneralVery Useful Article Pin
GWG23-Sep-02 3:40
GWG23-Sep-02 3:40 
GeneralRe: Very Useful Article Pin
Chris Richner23-Sep-02 9:39
Chris Richner23-Sep-02 9:39 
GeneralRe: Very Useful Article Pin
Karl Tarbet21-Feb-03 8:21
Karl Tarbet21-Feb-03 8:21 
GeneralRe: Very Useful Article Pin
Chris Richner21-Feb-03 11:50
Chris Richner21-Feb-03 11:50 
GeneralRe: Very Useful Article Pin
Jaykul14-Jan-04 9:24
Jaykul14-Jan-04 9:24 
GeneralRe: Very Useful Article Pin
Chris Richner14-Jan-04 9:45
Chris Richner14-Jan-04 9:45 
GeneralRe: Very Useful Article Pin
Jaykul14-Jan-04 10:05
Jaykul14-Jan-04 10:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.