简体   繁体   English

使用 JNA 的“全局”KeyListener

[英]“global” KeyListener using JNA

I have in plan making of program in Java running under Windows that can map diffenrent "macros" on different keys runnig at background.我计划在 Java 中运行 Windows 中的程序,可以 map 在后台运行的不同键上的不同“宏”。 Problem is - how to make Java listen to keys pressed when the application is not being focused.问题是 - 如何让 Java 在应用程序没有被聚焦时监听按键。

I have found lot of opinions that this is not possible.我发现很多意见认为这是不可能的。 But I have also found this written by Stefano here on SO.但我也在 SO 上找到了 Stefano 写的这篇文章。 This solution is, well, not good enough for me, at least there is not one impotant information.这个解决方案对我来说不够好,至少没有一个重要的信息。 The function MsgWaitForMultipleObjects() returns one value if the key is not pressed...that's ok.如果未按下该键,则 function MsgWaitForMultipleObjects()返回一个值……没关系。 After key press, it returns different value...that would be ok, if the function wouldn't return the same value whatever happens after the key press event.按键后,它返回不同的值......那没关系,如果 function 在按键事件之后不会返回相同的值。

Here is the thread testing this:这是测试这个的线程:

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

This little program (using this thread) reacts on pressing ALT+X .这个小程序(使用这个线程)对按下ALT+X做出反应。 After this is pressed, the text Key pressed is written out to the console until the program stops (the function returns 0 all the time).按下此键后, Key pressed的文本将写入控制台,直到程序停止(function 始终返回 0)。 Possible solution is in my opinion some "reset" of the function so it will wait for the key press again and return 258 again ( 258 == waiting).在我看来,可能的解决方案是 function 的一些“重置”,因此它将再次等待按键并再次返回258258 == 等待)。 But I have no idea how to do this.但我不知道该怎么做。

If somebody knows, how to do this, or is there is another solution, I would be grateful for any information.如果有人知道如何做到这一点,或者是否有其他解决方案,我将不胜感激任何信息。

I don't know about JNA solution, but there is a well-established global hotkey library called JIntelliType我不知道 JNA 解决方案,但是有一个完善的全球热键库,称为JIntelliType

EDIT: Correct answer to this problem was to use GetMessage instead of MsgWaitForMultipleObjects.编辑:这个问题的正确答案是使用 GetMessage 而不是 MsgWaitForMultipleObjects。 I wrote a simple example using BridJ and it works great:我用 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);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM