使用JNA的“global”KeyListener

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

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

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

我不了解JNA解决方案,但有一个成熟的全球热键库叫做JIntelliType

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

  if (!RegisterHotKey(null, id, MOD_ALT | MOD_NOREPEAT, 0x42)) { System.out.println("Error"); return; } Pointer 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); }