I have in plan making of program in Java running under Windows that can map diffenrent "macros" on different keys runnig at background. Problem is - how to make Java listen to keys pressed when the application is not be开发者_如何学Cing focused.
I have found lot of opinions that this is not possible. But I have also found this written by Stefano here on SO. 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. 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.
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
. 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). 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). 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
EDIT: Correct answer to this problem was to use GetMessage instead of MsgWaitForMultipleObjects. I wrote a simple example using BridJ and it works great:
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);
}
精彩评论