アプリ内のみで Web ブラウザの「クリック音」を無効にする方法
質問
問題の「クリック音」は実際にはシステム全体の設定であるため、アプリケーションにフォーカスがある場合にのみ無効にし、アプリケーションが閉じたりフォーカスを失ったりしたときに再び有効にしたいと考えています。
もともと、ここ stackoverflow でこの質問をしたかったのですが、まだベータ版ではありませんでした。そこで、答えを求めてグーグル検索して、ほんの少しの情報しか見つけられなかった後、次のことを思いつき、ベータ版なのでここに投稿することにしました。
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;
}
}
}
}
次に、メイン フォームで、次の 3 つのイベントで上記のコードを使用します。
- アクティブ化された
- 無効化されました
フォームの終了
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; }
現在私が感じている問題の 1 つは、プログラムがクラッシュした場合、アプリケーションを再起動するまでクリック音が鳴らないことですが、彼らはそのことを知りません。
皆さんはどう思いますか?これは良い解決策でしょうか?どのような改善が可能でしょうか?
解決
WebBrowser.DocumentText ではなく WebBrowser.Document.Write を使用すると、クリック音が発生しないことに気付きました。
したがって、これの代わりに:
webBrowser1.DocumentText = "<h1>Hello, world!</h1>";
これを試して:
webBrowser1.Document.OpenNew(true);
webBrowser1.Document.Write("<h1>Hello, world!</h1>");
他のヒント
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);
}
これを無効にするには、Internet Explorer のナビゲーション サウンドのレジストリ値を「NULL」に変更します。
Registry.SetValue("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\Explorer\\Navigating\\.Current","","NULL");
そして、ナビゲーション サウンドの Internet Explorer レジストリ値を「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");
確かにハッキングのように感じますが、これについてはかなり前に調査を行ったものの、他の解決策が見つからなかったので、おそらく最善の策でしょう。
さらに良いのは、煩わしいページのリロードを何度も必要としないようにアプリケーションを設計することです。たとえば、iframe を更新してサーバー上の更新を確認する場合は、代わりに XMLHttpRequest を使用します。(「AJAX」という用語が生まれる前の時代に私がこの問題に取り組んでいたことがわかりますか?)
Windows レジストリの置き換えを使用する場合は、これを使用します。
// 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);