我在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)。在我看来,可能的解决方案是对函数进行一些“重置”,以便它再次等待按键并再次返回258
(258
==等待)。但我不知道该怎么做。
如果有人知道,如何做到这一点,或者是否有另一种解决方案,我将不胜感激任何信息。
答案 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);
}