Working example of JNA mouse hook

前端 未结 2 456
滥情空心
滥情空心 2020-11-30 11:58

Can any one provide me with a working example of JNA mouse hook, which would be able to track mouse movements/click outside my Java Swing application ?

Thanks in Adv

2条回答
  •  有刺的猬
    2020-11-30 12:25

    Yep, here is the code...

    public class CWMouseHook {
    public final User32 USER32INST;
    public final Kernel32 KERNEL32INST;
    public CWMouseHook()
    {
        if(!Platform.isWindows())
        {
            throw new UnsupportedOperationException("Not supported on this platform.");
        }
        USER32INST = User32.INSTANCE;
        KERNEL32INST = Kernel32.INSTANCE;
        mouseHook=hookTheMouse();
        Native.setProtected(true);
    
    }
    public static LowLevelMouseProc mouseHook;
    public HHOOK hhk;
    public Thread thrd;
    public boolean threadFinish = true;
    public boolean isHooked = false;
    public static final int WM_MOUSEMOVE = 512;
    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()
    {
        threadFinish = true;
        if (thrd.isAlive())
        {
            thrd.interrupt();
            thrd = null;
        }
        isHooked = false;
    }
    public boolean isIsHooked()
    {
        return isHooked;
    }
    public void setMouseHook()
    {
        thrd = new Thread(new Runnable() {
            @Override
            public void run()
                {
                      try
                      {
                            if(!isHooked)
                            {   
                                hhk = USER32INST.SetWindowsHookEx(14, mouseHook,KERNEL32INST.GetModuleHandle(null),0);
                                isHooked = true;
                                MSG msg = new MSG();
                                while ((USER32INST.GetMessage(msg, null, 0, 0)) != 0)
                                {
                                    USER32INST.TranslateMessage(msg);     
                                    USER32INST.DispatchMessage(msg);
                                    System.out.print(isHooked);
                                    if (!isHooked)
                                          break;
                                }
                            }
                            else
                                System.out.println("The Hook is already installed.");
                    }
                    catch (Exception e)
                    {   System.err.println(e.getMessage());
                        System.err.println("Caught exception in MouseHook!");
                    }
            }
        },"Named thread");
        threadFinish = false;
        thrd.start();
    
    }
    private interface LowLevelMouseProc extends HOOKPROC
    {
        LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);
    }
    public 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:
                            // do stuff
                            break;
                        case CWMouseHook.WM_RBUTTONDOWN:
                            //do stuff
                            break;
                        case CWMouseHook.WM_MBUTTONDOWN:
                            //do other stuff
                            break;
                        case CWMouseHook.WM_LBUTTONUP:
                             //do even more stuff
                             break;
                        case CWMouseHook.WM_MOUSEMOVE:
    
                            break;                         
                        default:
                            break;
                    }
                     /****************************DO NOT CHANGE, this code unhooks mouse *********************************/
                     if (threadFinish == true)
                      {                      
                         USER32INST.PostQuitMessage(0);
                      }
                    /***************************END OF UNCHANGABLE *******************************************************/
                }
                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;
    }
    

    That's all about there is to it. Cheers. It's a basically a ripoff of the code of a guy in Sun forums...but also tested by me, and it works so cheers again.

    Edit: I edited the code so it includes the LowLevelMouseProc but you can use your extension of HOOK which you can define elsewhere. It doesn't matter that much. Be wary that for some reason you have TO have the variable mouseHook as static otherwise hook just unhooks after a while.

提交回复
热议问题