使用JNA的“global”KeyListener

时间:2011-05-30 08:49:21

标签: java jna keylistener

我在Windows下运行Java程序的计划制作,可以在不同的密钥runnig上映射不同的“宏”。问题是 - 当应用程序没有被聚焦时,如何使Java听到按下的键。

我发现很多意见认为这是不可能的。但是我也发现了斯特凡诺在这里写的this。对我来说,这个解决方案不够好,至少没有一个重要的信息。如果没有按下键,函数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)。在我看来,可能的解决方案是对函数进行一些“重置”,以便它再次等待按键并再次返回258258 ==等待)。但我不知道该怎么做。

如果有人知道,如何做到这一点,或者是否有另一种解决方案,我将不胜感激任何信息。

1 个答案:

答案 0 :(得分:1)

我不了解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);
        }