当前位置: 首页 > 面试题库 >

使用JNA的“全局” KeyListener

华涵意
2023-03-14
问题内容

我正在计划在Windows下运行的Java程序的计划制定工作,该程序可以在背景的不同键runnig上映射不同的“宏”。问题是-
如何使Java在应用程序未聚焦时监听按键。

我发现很多观点认为这是不可能的。但是我也发现Stefano在SO上写的这本书。这种解决方案对我来说还不够好,至少没有一个重要的信息。MsgWaitForMultipleObjects()如果没有按下该键,该函数将返回一个值。按键后,它会返回不同的值…如果函数在按键事件后不会返回相同的值,则可以。

这是测试的线程:

public class KeyListener extends Thread {

    /**
     * Constructor
     */
    public KeyListener() {
        super();
    }

    /**
     * RUN method
     */
    @Override
    public void run() {
        int x;
        User32 user32 = User32.INSTANCE;

        boolean res = user32.RegisterHotKey(Pointer.NULL, 1, User32.MOD_ALT | User32.MOD_CONTROL, WinKeys.VK_X);
        if (!res) {
            System.out.println("Couldn't register hotkey");
        }
        System.out.println("Starting and waiting");

        while (!isInterrupted()) {
            x = user32.MsgWaitForMultipleObjects(0, Pointer.NULL, true, 1000, User32.QS_HOTKEY);

            if (x == 0) {
                System.out.println("Key pressed");
            }
        }
    }
}

这个小程序(使用该线程)在按下时作出反应ALT+X。按下此键之后,Key pressed会将文本写到控制台,直到程序停止(该函数始终返回0)。在我看来,可能的解决方案是对该功能进行一些“重置”,以便它将再次等待按键并258再次返回(258==等待)。但是我不知道该怎么做。

如果有人知道如何执行此操作,或者还有其他解决方案,我将不胜感激。


问题答案:

我不知道JNA解决方案,但是有一个完善的全局热键库,称为JIntelliType

编辑:此问题的正确答案是使用GetMessage而不是MsgWaitForMultipleObjects。我使用BridJ编写了一个简单的示例,它很好用:

       if (!RegisterHotKey(null, id, MOD_ALT | MOD_NOREPEAT, 0x42)) {
            System.out.println("Error");
            return;
        }

        Pointer<MSG> msgPointer = Pointer.allocate(MSG.class);

        try {
            while (GetMessage(msgPointer, null, 0, 0) != 0) {
                MSG msg = msgPointer.get();
                if (msg.message() == WM_HOTKEY && msg.wParam() == id) {
                    System.out.println("YEAH");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            UnregisterHotKey(null, id);
        }


 类似资料:
  • 目前,我正试图使用JNA将非Java应用程序设置为焦点,我发现了以下代码。 我还将以下依赖项放入我的pom.xml,该项目是一个只有主文件的新项目。 这是我们的程序入口点: 理论上,在编译/运行时,程序应该只关注运行时打开的谷歌Chrome。 然而,Java给出了以下错误消息: 对于这个问题,我找到的唯一参考是使用JNA User32平台映射的NoSuchMethodError 这几乎是相同的错误

  • 我试图使用shobjidl_core. h库来运行代码,改变一个特定的监视器的壁纸,特别是我需要运行这两个函数:GetMonitor orDevicePathAt,SetWallfile。 现在,当我运行以下代码时: 我收到一个错误,提示“无法加载库'shobjidl'” 我已经尝试了任何变体的“舒比德”,但仍然找不到一个有效的。从我对JNA的理解来看,它需要一个包含库的dll,但是我找不到任何与

  • 本文向大家介绍使用use注册Vue全局组件和全局指令的方法,包括了使用use注册Vue全局组件和全局指令的方法的使用技巧和注意事项,需要的朋友参考一下 Vue中的组件和指令分为局部组件、局部指令和全局组件、全局指令。对于注册有一定数量的全局指令和全局组件时,官方文档中的方法就显得有些不够清爽了。 全局组件 在Vue官方文档中介绍的是使用Vue.component(tagName, options)

  • 问题内容: 我在上一个线程http://codingdict.com/questions/105948上问了类似的问题,但是我被引导使用JNI, “它并没有取得太大的成功。。。我已经阅读了一些教程,虽然有些可以很好地工作,但其他的我仍然无法获得我所需要的信息,这就是前台窗口的标题。 现在,我正在研究JNA,但我不知道如何访问GetForegroundWindow()…我认为一旦使用以下代码(在另一

  • 我有一个庞大的C源文件集,当编译时,这些文件将生成一个共享库。 还有一个Java版本使用JNA访问已经构建的c共享库。这些文件在另一个JAR中可用。此jar依赖于jna. 首先,我编译了c文件,然后编译了java代码。在java中,没有错误。只有当我试图将它移植到Android时,问题才会出现。我可以使用android的'ndk-build'工具轻松地编译c文件。这将成功创建共享库。 我无法在An

  • 有没有办法在Java中创建一个可以从其他类访问的方法,而不必使该方法成为静态的?正如我在网上看到的所有解决方案所说,使方法成为静态的方法对我不起作用,因为我试图从方法中引用一个非静态变量。我引用的变量是(指它所在的类)。