Skip to Main Content

Java HotSpot Virtual Machine

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

JNA based mousehook getting stuck

843829Sep 15 2009 — edited Jun 20 2010
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;
    }
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jul 18 2010
Added on Sep 15 2009
6 comments
1,756 views