Java 在windows上的Eclipse RCP应用程序中使用swt浏览器时,如何禁用单击声音?

Java 在windows上的Eclipse RCP应用程序中使用swt浏览器时,如何禁用单击声音?,java,maven,internet-explorer,swt,tycho,Java,Maven,Internet Explorer,Swt,Tycho,我在EclipseRCP应用程序中嵌入了swt浏览器。我的问题是,在Windows上,浏览器的setUrl()和dispose()方法会导致(恼人的)internet explorer导航声音(“单击”),这是不受欢迎的 我发现这段代码成功地禁用了点击声音 OS.CoInternetSetFeatureEnabled(OS.FEATURE_DISABLE_NAVIGATION_SOUNDS, OS.SET_FEATURE_ON_PROCESS, true); 但是由于这是受限的API,我很难使

我在EclipseRCP应用程序中嵌入了swt浏览器。我的问题是,在Windows上,浏览器的
setUrl()
dispose()
方法会导致(恼人的)internet explorer导航声音(“单击”),这是不受欢迎的

我发现这段代码成功地禁用了点击声音

OS.CoInternetSetFeatureEnabled(OS.FEATURE_DISABLE_NAVIGATION_SOUNDS, OS.SET_FEATURE_ON_PROCESS, true);
但是由于这是受限的API,我很难使用Maven/Tycho构建应用程序

[ERROR] OS.CoInternetSetFeatureEnabled(OS.FEATURE_DISABLE_NAVIGATION_SOUNDS, OS.SET_FEATURE_ON_PROCESS, true);
[ERROR] ^^
[ERROR] OS cannot be resolved to a variable
[ERROR] 4 problems (4 errors)
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.eclipse.tycho:tycho-compiler-plugin:0.22.0:compile (default-compile) on project com.myapp: Compilation failure
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)...
有没有办法让Maven/Tycho在使用这个受限API时进行编译


或者有没有其他方法可以在Windows上禁用IE浏览器导航声音

我最终设法破解了这个问题,下面是如何破解的

由于这个限制性API存在于特定于平台的插件中,即SWT 32位和SWT 64位,因此我创建了两个特定于平台的片段来保存代码

要让maven编译片段,需要在build.properties文件中的32位片段中添加以下行:

extra.. = platform:/fragment/org.eclipse.swt.win32.win32.x86
对于64位片段build.properties

extra.. = platform:/fragment/org.eclipse.swt.win32.win32.x86_64
maven pom配置文件也应该是特定于平台的,这可以通过在32位片段的pom.xml中添加以下部分来完成

<build>
    <plugins>
        <plugin>
            <groupId>org.eclipse.tycho</groupId>
            <artifactId>target-platform-configuration</artifactId>

            <configuration>
                <environments>
                    <environment>
                        <os>win32</os>
                        <ws>win32</ws>
                        <arch>x86</arch>
                    </environment>
                </environments>
            </configuration>
        </plugin>
    </plugins>
</build>
然后,我们将沉默代码放在每个片段的一个类中。这个类应该在主机插件中实现一个接口。 主机插件定义了一个扩展点,该扩展点接受在主机插件中实现接口的类。然后片段声明一个扩展,并在片段中提供类名

当主机代码需要运行静默代码时,它需要检查扩展并实例化和调用静默代码

例如:

package com.mypackage;

import javax.inject.Inject;

import org.apache.log4j.Logger;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.e4.core.di.annotations.Creatable;

import com.mypackage.ISilencer;

@Creatable
public class BrowserSilencer {

    private static final Logger LOGGER = Logger.getLogger(BrowserSilencer.class);

    @Inject
    IExtensionRegistry exReg;

    public void silence=() {
        IConfigurationElement[] config = exReg.getConfigurationElementsFor("com.mypackage.silencer");
        try {
            for (IConfigurationElement e : config) {
                final Object o = e.createExecutableExtension("class");
                if (o instanceof ISilencer) {
                    executeExtension(o);
                }
            }
        } catch (CoreException ex) {
            LOGGER.error("Error finding the com.mypackage.silencer extension");
        }
    }

    private void executeExtension(final Object o) {
        ISafeRunnable runnable = new ISafeRunnable() {
            @Override
            public void handleException(Throwable e) {
                LOGGER.error("Exception while attempting to silence browser");
            }

            @Override
            public void run() throws Exception {
                ((ISilencer) o).silence();
            }
        };
        SafeRunner.run(runnable);
    }
}
主机插件中的接口

package com.mypackage;
public interface ISilencer {
   public void silence();
}
以及64位插件中的代码示例。32位几乎相同

package com.mypackage.fragment.win64;

import org.apache.log4j.Logger;
import org.eclipse.swt.internal.win32.OS;   // yes i DO mean win32 here

import com.mypackage.ISilencer;

@SuppressWarnings("restriction")
public class Silencer implements ISilencer {

    private static final Logger LOGGER = Logger.getLogger(Silencer.class);

    @Override
    public void silence() {
        // removes the annoying browser clicking sound!
        try {
            OS.CoInternetSetFeatureEnabled(OS.FEATURE_DISABLE_NAVIGATION_SOUNDS, OS.SET_FEATURE_ON_PROCESS, true);
        } catch (Throwable e1) {
            // I am just catching any exceptions that may come off this one since it is using restricted API so that if in any case it fail well it will just click.
            LOGGER.error("Caught exception while setting FEATURE_DISABLE_NAVIGATION_SOUNDS.");
        }
    }
}
由于Browser消音器被标记为
@createable
,您只需将其注入类中并调用
silence()
方法即可

如果不清楚如何创建和扩展点,我可以在后续文章中说明。

我必须解决(可能)在Windows中使用SWT浏览器(使用IE)时出现的导航声音问题,并且我能够找到不需要更改代码的解决方案

我发现可以通过禁用Windows控制面板中的特定声音来改变这种情况。我仅在Win 7中验证了:

控制面板=>声音=>声音=>Windows资源管理器=>开始导航
发件人:Windows导航开始.wav
致:无

我希望这能帮助任何正在寻找非代码解决方案的人。

//使Windows SWT.browser小部件免受可怕的点击。
// Silence Windows SWT.browser widget from making awful clicks. 
// For windows 32 and 64 bit SWT applications. 
// Uses reflection to call OS.CoInternetSetFeatureEnabled(OS.FEATURE_DISABLE_NAVIGATION_SOUNDS, OS.SET_FEATURE_ON_PROCESS, true);
// Without importing platform specific 
// #import org.eclipse.swt.internal.win32.OS  
private void silenceWindowsExplorer() {
    try {
        Class<?> c = Class.forName("org.eclipse.swt.internal.win32.OS");
        java.lang.reflect.Method method = c.getDeclaredMethod("CoInternetSetFeatureEnabled", Integer.TYPE, Integer.TYPE, Boolean.TYPE);
        method.invoke(null, new Object[] {21, 2, true});
    } catch (Throwable th)
    {
        // Might fail.. but probably will never do harm.
        th.printStackTrace();
    }
}
//适用于windows 32和64位SWT应用程序。 //使用反射调用OS.CoInternetSetFeatureEnabled(OS.FEATURE\u DISABLE\u NAVIGATION\u SOUNDS,OS.SET\u FEATURE\u ON\u PROCESS,true); //不导入特定于平台的 //#导入org.eclipse.swt.internal.win32.OS 私有void沉默Windows资源管理器(){ 试一试{ Class c=Class.forName(“org.eclipse.swt.internal.win32.OS”); java.lang.reflect.Method=c.getDeclaredMethod(“CoInternetSetFeatureEnabled”,Integer.TYPE,Integer.TYPE,Boolean.TYPE); invoke(null,新对象[]{21,2,true}); }捕获(可丢弃) { //可能会失败,但可能永远不会造成伤害。 th.printStackTrace(); } }
因此您需要将包含
OS
类的捆绑包或片段放到编译类路径上。哪个包或片段包含该类?oberlies,你是对的,但说起来容易做起来难。我在下面贴了一个答案,说明了如何去做。非常好的帖子!非常感谢您分享您的见解。这是一个不相关的答案,因为这对于运送到客户机上的软件不起作用
package com.mypackage.fragment.win64;

import org.apache.log4j.Logger;
import org.eclipse.swt.internal.win32.OS;   // yes i DO mean win32 here

import com.mypackage.ISilencer;

@SuppressWarnings("restriction")
public class Silencer implements ISilencer {

    private static final Logger LOGGER = Logger.getLogger(Silencer.class);

    @Override
    public void silence() {
        // removes the annoying browser clicking sound!
        try {
            OS.CoInternetSetFeatureEnabled(OS.FEATURE_DISABLE_NAVIGATION_SOUNDS, OS.SET_FEATURE_ON_PROCESS, true);
        } catch (Throwable e1) {
            // I am just catching any exceptions that may come off this one since it is using restricted API so that if in any case it fail well it will just click.
            LOGGER.error("Caught exception while setting FEATURE_DISABLE_NAVIGATION_SOUNDS.");
        }
    }
}
// Silence Windows SWT.browser widget from making awful clicks. 
// For windows 32 and 64 bit SWT applications. 
// Uses reflection to call OS.CoInternetSetFeatureEnabled(OS.FEATURE_DISABLE_NAVIGATION_SOUNDS, OS.SET_FEATURE_ON_PROCESS, true);
// Without importing platform specific 
// #import org.eclipse.swt.internal.win32.OS  
private void silenceWindowsExplorer() {
    try {
        Class<?> c = Class.forName("org.eclipse.swt.internal.win32.OS");
        java.lang.reflect.Method method = c.getDeclaredMethod("CoInternetSetFeatureEnabled", Integer.TYPE, Integer.TYPE, Boolean.TYPE);
        method.invoke(null, new Object[] {21, 2, true});
    } catch (Throwable th)
    {
        // Might fail.. but probably will never do harm.
        th.printStackTrace();
    }
}