28

The 'click sound' in question is actually a system wide preference, so I only want it to be disabled when my application has focus and then re-enable when the application closes/loses focus.

Originally, I wanted to ask this question here on stackoverflow, but I was not yet in the beta. So, after googling for the answer and finding only a little bit of information on it I came up with the following and decided to post it here now that I'm in the beta.

using System;
using Microsoft.Win32;

namespace HowTo
{
    class WebClickSound
    {
        /// <summary>
        /// Enables or disables the web browser navigating click sound.
        /// </summary>
        public static bool Enabled
        {
            get
            {
                RegistryKey key = Registry.CurrentUser.OpenSubKey(@"AppEvents\Schemes\Apps\Explorer\Navigating\.Current");
                string keyValue = (string)key.GetValue(null);
                return String.IsNullOrEmpty(keyValue) == false && keyValue != "\"\"";
            }
            set
            {
                string keyValue;

                if (value)
                {
                    keyValue = "%SystemRoot%\\Media\\";
                    if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor > 0)
                    {
                        // XP
                        keyValue += "Windows XP Start.wav";
                    }
                    else if (Environment.OSVersion.Version.Major == 6)
                    {
                        // Vista
                        keyValue += "Windows Navigation Start.wav";
                    }
                    else
                    {
                        // Don't know the file name so I won't be able to re-enable it
                        return;
                    }
                }
                else
                {
                    keyValue = "\"\"";
                }

                // Open and set the key that points to the file
                RegistryKey key = Registry.CurrentUser.OpenSubKey(@"AppEvents\Schemes\Apps\Explorer\Navigating\.Current", true);
                key.SetValue(null, keyValue,  RegistryValueKind.ExpandString);
                isEnabled = value;
            }
        }
    }
}

Then in the main form we use the above code in these 3 events:

  • Activated
  • Deactivated
  • FormClosing

    private void Form1_Activated(object sender, EventArgs e)
    {
        // Disable the sound when the program has focus
        WebClickSound.Enabled = false;
    }
    
    private void Form1_Deactivate(object sender, EventArgs e)
    {
        // Enable the sound when the program is out of focus
        WebClickSound.Enabled = true;
    }
    
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        // Enable the sound on app exit
        WebClickSound.Enabled = true;
    }
    

The one problem I see currently is if the program crashes they won't have the click sound until they re-launch my application, but they wouldn't know to do that.

What do you guys think? Is this a good solution? What improvements can be made?

Chris
  • 6,761
  • 6
  • 52
  • 67
sieben
  • 2,161
  • 4
  • 23
  • 31
  • I had a problem with this line: isEnabled = value; I've just commented it, but i want to know what it was intended to be – Cristo Mar 31 '13 at 20:57

5 Answers5

39
const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
const int SET_FEATURE_ON_PROCESS = 0x00000002;

[DllImport("urlmon.dll")]
[PreserveSig]
[return: MarshalAs(UnmanagedType.Error)]
static extern int CoInternetSetFeatureEnabled(int FeatureEntry,
                                              [MarshalAs(UnmanagedType.U4)] int dwFlags,
                                              bool fEnable);

static void DisableClickSounds()
{
    CoInternetSetFeatureEnabled(FEATURE_DISABLE_NAVIGATION_SOUNDS,
                                SET_FEATURE_ON_PROCESS,
                                true);
}
Markus Safar
  • 6,324
  • 5
  • 28
  • 44
John black
  • 527
  • 2
  • 6
  • 9
  • 1
    Awesome, works like a charm and only disables it for just your app and doesn't rely on form focus. – Josh Feb 11 '12 at 10:52
12

I've noticed that if you use WebBrowser.Document.Write rather than WebBrowser.DocumentText then the click sound doesn't happen.

So instead of this:

webBrowser1.DocumentText = "<h1>Hello, world!</h1>";

try this:

webBrowser1.Document.OpenNew(true);
webBrowser1.Document.Write("<h1>Hello, world!</h1>");
Matt Hamilton
  • 200,371
  • 61
  • 386
  • 320
  • 2
    your suggested solution prevents the control from making that click noise but on the other side this approach causes the control to have serious focus issues. In my case, the webbrowser control steals back the focus at the end of the event loop. As far as I can tell there's no workaround for that. In my case I needed to get back to the DocumentText solution - but still I'm looking for disabling that annoying sound. Any other ideas? – Stefan Koell May 31 '09 at 09:28
  • 2
    Just found out, that James on this thread: http://stackoverflow.com/questions/393166/how-to-disable-click-sound-in-webbrowser-control has a great solution - at least for IE7 and IE8. I can use the DocumentText property, have no focus issues and best of all, I have no click sound. – Stefan Koell May 31 '09 at 10:23
1

You disable it by changing Internet Explorer registry value of navigating sound to "NULL":

Registry.SetValue("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\Explorer\\Navigating\\.Current","","NULL");

And enable it by changing Internet Explorer registry value of navigating sound to "C:\Windows\Media\Cityscape\Windows Navigation Start.wav":

Registry.SetValue("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\Explorer\\Navigating\\.Current","","C:\Windows\Media\Cityscape\Windows Navigation Start.wav");
user2612427
  • 159
  • 1
  • 4
0

Definitely feels like a hack, but having done some research on this a long time ago and not finding any other solutions, probably your best bet.

Better yet would be designing your application so it doesn't require many annoying page reloads.. for example, if you're refreshing an iframe to check for updates on the server, use XMLHttpRequest instead. (Can you tell that I was dealing with this problem back in the days before the term "AJAX" was coined?)

pix0r
  • 31,139
  • 18
  • 86
  • 102
0

If you want to use replacing Windows Registry, use this:

// backup value
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"AppEvents\Schemes\Apps\Explorer\Navigating\.Current");
string BACKUP_keyValue = (string)key.GetValue(null);

// write nothing
key = Registry.CurrentUser.OpenSubKey(@"AppEvents\Schemes\Apps\Explorer\Navigating\.Current", true);
key.SetValue(null, "",  RegistryValueKind.ExpandString);

// do navigation ...

// write backup key
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"AppEvents\Schemes\Apps\Explorer\Navigating\.Current", true);
key.SetValue(null, BACKUP_keyValue,  RegistryValueKind.ExpandString);
DjCzermino
  • 125
  • 1
  • 9