Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关闭捕获全局输入事件的钩子 简介_Java_Multithreading_Winapi_Hook_Jna - Fatal编程技术网

Java 关闭捕获全局输入事件的钩子 简介

Java 关闭捕获全局输入事件的钩子 简介,java,multithreading,winapi,hook,jna,Java,Multithreading,Winapi,Hook,Jna,这里有一个例子来说明这个问题。考虑我正在跟踪和显示鼠标全局当前位置和最后点击按钮和位置给用户。这是一张图片: 为了归档windows box上的捕获点击事件(该事件将被发送并将被发送到其他程序事件消息队列),我使用winapi即user32.dll库创建了一个钩子。这在JDK沙箱之外,所以我使用JNA调用本机库 这一切都很完美,但它并没有达到我预期的效果 我的问题是-如何正确关闭下面的示例程序 示例源 下面的代码并不是我完全写的,而是取自Oracle论坛的问题,部分已经修复 import ja

这里有一个例子来说明这个问题。考虑我正在跟踪和显示鼠标全局当前位置和最后点击按钮和位置给用户。这是一张图片:

为了归档windows box上的捕获点击事件(该事件将被发送并将被发送到其他程序事件消息队列),我使用winapi即
user32.dll
库创建了一个钩子。这在JDK沙箱之外,所以我使用JNA调用本机库

这一切都很完美,但它并没有达到我预期的效果

我的问题是-如何正确关闭下面的示例程序

示例源 下面的代码并不是我完全写的,而是取自Oracle论坛的问题,部分已经修复

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JLabel;

import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.HOOKPROC;
import com.sun.jna.platform.win32.WinUser.MSG;
import com.sun.jna.platform.win32.WinUser.POINT;

public class MouseExample {
    final JFrame jf;
    final JLabel jl1, jl2;
    final CWMouseHook mh;
    final Ticker jt;

    public class Ticker extends Thread {
        public boolean update = true;

        public void done() {
            update = false;
        }

        public void run() {
            try {
                Point p, l = MouseInfo.getPointerInfo().getLocation();
                int i = 0;
                while (update == true) {
                    try {
                        p = MouseInfo.getPointerInfo().getLocation();
                        if (!p.equals(l)) {
                            l = p;
                            jl1.setText(new GlobalMouseClick(p.x, p.y)
                                    .toString());
                        }

                        Thread.sleep(35);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        return;
                    }
                }
            } catch (Exception e) {
                update = false;
            }
        }
    }

    public MouseExample() throws AWTException, UnsupportedOperationException {
        this.jl1 = new JLabel("{}");
        this.jl2 = new JLabel("{}");
        this.jf = new JFrame();
        this.jt = new Ticker();
        this.jt.start();
        this.mh = new CWMouseHook() {
            @Override
            public void globalClickEvent(GlobalMouseClick m) {
                jl2.setText(m.toString());
            }
        };

        mh.setMouseHook();

        jf.setLayout(new GridLayout(2, 2));
        jf.add(new JLabel("Position"));
        jf.add(jl1);
        jf.add(new JLabel("Last click"));
        jf.add(jl2);
        jf.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                mh.dispose();
                jt.done();
                jf.dispose();
            }
        });
        jf.setLocation(new Point(0, 0));
        jf.setPreferredSize(new Dimension(200, 90));
        jf.pack();
        jf.setVisible(true);
    }

    public static class GlobalMouseClick {
        private char c;
        private int x, y;

        public GlobalMouseClick(char c, int x, int y) {
            super();
            this.c = c;
            this.x = x;
            this.y = y;
        }

        public GlobalMouseClick(int x, int y) {
            super();
            this.x = x;
            this.y = y;
        }

        public char getC() {
            return c;
        }

        public void setC(char c) {
            this.c = c;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }

        @Override
        public String toString() {
            return (c != 0 ? c : "") + " [" + x + "," + y + "]";
        }
    }

    public static class CWMouseHook {
        public User32 USER32INST;

        public CWMouseHook() throws UnsupportedOperationException {
            if (!Platform.isWindows()) {
                throw new UnsupportedOperationException(
                        "Not supported on this platform.");
            }
            USER32INST = User32.INSTANCE;
            mouseHook = hookTheMouse();
            Native.setProtected(true);
        }

        private static LowLevelMouseProc mouseHook;
        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 dispose() {
            unsetMouseHook();
            mousehook_thread = null;
            mouseHook = null;
            hhk = null;
            USER32INST = null;
        }

        public void unsetMouseHook() {
            isHooked = false;
            USER32INST.UnhookWindowsHookEx(hhk);
            System.out.println("Mouse hook is unset.");
        }

        public boolean isIsHooked() {
            return isHooked;
        }

        public void globalClickEvent(GlobalMouseClick m) {
            System.out.println(m);
        }

        private Thread mousehook_thread;

public void setMouseHook() {
    mousehook_thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                if (!isHooked) {
                    hhk = USER32INST.SetWindowsHookEx(14, mouseHook,
                            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:
                            globalClickEvent(new GlobalMouseClick('L',
                                    info.pt.x, info.pt.y));
                            break;
                        case CWMouseHook.WM_RBUTTONDOWN:
                            globalClickEvent(new GlobalMouseClick('R',
                                    info.pt.x, info.pt.y));
                            break;
                        case CWMouseHook.WM_MBUTTONDOWN:
                            globalClickEvent(new GlobalMouseClick('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;
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    new MouseExample();
                } catch (AWTException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

在你的线程中,你应该在这里调用

User32.PostQuitMessage(0)

通知本机线程(钩子)您不再需要它。 当您这样做时,在代码中

while((USER32INST.GetMessage), null,0,0))!=0)

看到您不再需要钩子并在本机端终止它。我建议您首先尝试使用内部for it事件关闭钩子,例如

CWMouseHook.WM_mbutdown

只是看看它是否正常工作

在这篇文章中:你可以看到一些应该对你有帮助的代码。干杯