java - 在 Windows 上的 Eclipse RCP 应用程序中使用时如何禁用 swt 浏览器点击声音?

标签 java maven internet-explorer swt tycho

我已在 Eclipse RCP 应用程序中嵌入了 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>

这是 64 位版本。

<build>
    <plugins>
        <plugin>
            <groupId>org.eclipse.tycho</groupId>
            <artifactId>target-platform-configuration</artifactId>
            <configuration>
                <environments>
                    <environment>
                        <os>win32</os>
                        <ws>win32</ws>
                        <arch>x86_64</arch>
                    </environment>
                </environments>
            </configuration>
        </plugin>
    </plugins>
</build>

另外,不要忘记在片段 list 中设置相应的平台过滤器,如下所示

Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86))
Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86_64))

然后我们将沉默代码放置在每个片段的一个类中。这个类应该实现主机插件中的接口(interface)。 主机插件定义了一个扩展点,它采用一个实现主机插件中的接口(interface)的类。然后,片段声明一个扩展并在片段中提供类名。

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

示例:

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);
    }
}

主机插件中的接口(interface)

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.");
        }
    }
}

由于 BrowserSilencer 被标记为 @Creatable,您只需将其注入(inject)到您的类中并调用 silence() 方法

如果不清楚如何创建和扩展点,我可以在后续帖子中展示。

关于java - 在 Windows 上的 Eclipse RCP 应用程序中使用时如何禁用 swt 浏览器点击声音?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30525518/

相关文章:

java - 使用javascript修改固定在顶部的元素的css属性

使用 Apache Tika 库编译 Java 程序 - 依赖项

android - 无法将 War 文件从 Google Cloud 中的本地目录传输到 Tomcat 的 Webapps 目录

html - IE7下拉菜单出现在图像后面

asp.net - 登录/注销时未清除 ASP ASPXAUTH 身份验证 cookie

css - 即 : CSS Misalignment issue in UL/LI

Java 2 Objective-C NSArray

java - 网络应用程序 : Delete files during runtime

java - 如何从 POM.xml 中读取 application.properties

java - XMLBeans get_store() 方法返回 null