我计划在 Windows 下运行 Java 程序,该程序可以在后台运行的不同键上映射不同的“宏”。问题是 - 如何让 Java 在应用程序未获得焦点时监听按下的按键。
我发现很多意见认为这是不可能的。但我还发现了this由 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
时使用react。按下此按钮后,文本 Key Pressed
将被写入控制台,直到程序停止(该函数始终返回 0)。在我看来,可能的解决方案是对函数进行一些“重置”,这样它将等待再次按下按键并再次返回 258
(258
== waiting)。但我不知道该怎么做。
如果有人知道如何做到这一点,或者有其他解决方案,我将不胜感激任何信息。
最佳答案
我不知道 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);
}
关于java - "global"使用 JNA 的 KeyListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6174119/