Hello,
Hopefully I've got the right forum this time.
I need to capture mouse events using JNA. I've come up with some code after browsing around.
It works, but unreliably - suddenly stops capturing mouse events. I have not been able to figure out where and why it gets stuck.
Any help/suggestions would be greatly appreciated - thanks!
I'm using vers 3.2.2 of jna & examples
public class CWMouseHook {
final User32 USER32INST;
public CWMouseHook() {
if(!Platform.isWindows()) {
throw new UnsupportedOperationException("Not supported on this platform.");
}
USER32INST = User32.INSTANCE;
Native.setProtected(true);
}
private HHOOK hhk;
private boolean isHooked = false;
public static final int WM_LBUTTONDOWN = 513;
public static final int WM_LBUTTONUP = 514;
public static final int WM_RBUTTONDOWN = 516;
public static final int WM_RBUTTONUP = 517;
public static final int WM_MBUTTONDOWN = 519;
public static final int WM_MBUTTONUP = 520;
public void unsetMouseHook() {
USER32INST.UnhookWindowsHookEx(hhk);
isHooked = false;
System.out.println("Mouse hook is unset.");
}
public boolean isIsHooked() {
return isHooked;
}
public void setMouseHook() {
Thread mousehook_thread = new Thread(new Runnable() {
@Override
public void run() {
try {
if(!isHooked) {
hhk = USER32INST.SetWindowsHookEx(
User32.WH_MOUSE_LL,
hookTheMouse(),
Kernel32.INSTANCE.GetModuleHandle(null),
0);
isHooked = true;
System.out.println("Mouse hook is set. Click anywhere.");
// message dispatch loop (message pump)
MSG msg = new MSG();
while ((USER32INST.GetMessage(msg, null, 0, 0)) != 0) {
USER32INST.TranslateMessage(msg);
USER32INST.DispatchMessage(msg);
if (!isHooked)
break;
}
} else
System.out.println("The Hook is already installed.");
} catch (Exception e) { System.err.println("Caught exception in MouseHook!"); }
}
});
mousehook_thread.start();
}
private interface LowLevelMouseProc extends HOOKPROC {
LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);
}
private LowLevelMouseProc hookTheMouse() {
return new LowLevelMouseProc() {
@Override
public LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT info) {
if (nCode >= 0) {
switch(wParam.intValue()) {
case CWMouseHook.WM_LBUTTONDOWN:
System.out.println("L ["+info.pt.x+","+info.pt.y+"]");
break;
case CWMouseHook.WM_RBUTTONDOWN:
System.out.println("R ["+info.pt.x+","+info.pt.y+"]");
break;
case CWMouseHook.WM_MBUTTONDOWN:
System.out.println("M ["+info.pt.x+","+info.pt.y+"]");
break;
default:
break;
}
}
return USER32INST.CallNextHookEx(hhk, nCode, wParam, info.getPointer());
}
};
}
public class Point extends Structure {
public class ByReference extends Point implements Structure.ByReference {};
public NativeLong x;
public NativeLong y;
}
public static class MOUSEHOOKSTRUCT extends Structure {
public static class ByReference extends MOUSEHOOKSTRUCT implements Structure.ByReference {};
public POINT pt;
public HWND hwnd;
public int wHitTestCode;
public ULONG_PTR dwExtraInfo;
}
}