1. 程式人生 > >通過jna簡單實現java後臺監聽鍵盤觸發修改系統時間

通過jna簡單實現java後臺監聽鍵盤觸發修改系統時間

      由於玩某網遊需要在出副本時等一分鐘,而修改系統時間+1分鐘可以提前出副本,避免麻煩寫了個java後臺監聽鍵盤觸發修改系統時間的指令碼,當按下設定好的鍵盤組合即呼叫修改函式。

   

修改時間的函式程式碼如下(呼叫CMD命令):

  

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class changeTime
{
	static void plus_min(int min) throws IOException {
		Long millis = Long.valueOf(System.currentTimeMillis() + 60000*min);
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(millis.longValue());
		Date newDate = c.getTime();
		SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd");
		System.out.println(date.format(newDate));
		SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
		System.out.println(time.format(newDate));
		String cmd = " cmd /c date " + date.format(newDate);
		Runtime.getRuntime().exec(cmd);
		cmd = " cmd /c time " + time.format(newDate);
		System.out.println(cmd);
		Runtime.getRuntime().exec(cmd);
	}
	
}

後臺通過jna實現的鍵盤監聽程式碼如下(當按下的鍵盤組合符合設定好的條件,呼叫上述函式):

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.KBDLLHOOKSTRUCT;
import com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc;
import com.sun.jna.platform.win32.WinUser.MSG;

import java.io.IOException;
import java.util.ArrayList;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

/** Sample implementation of a low-level keyboard hook on W32. */
public class KeyHook {
	private static volatile boolean quit;
	private static HHOOK hhk;
	private static LowLevelKeyboardProc keyboardHook;
	
	//設定按鍵組合的vkCode,具體vkCode與鍵盤的對照表可百度
	private static ArrayList<Integer> keyList=new ArrayList<Integer>(){{add(65); add(83);add(68);add(38);}};
	private static ArrayList<Integer> inputList=new ArrayList<Integer>();
	private static Long listSetTime;
	private static int min=1;    //每次增加一分鐘
	
	static void setJframe(){   //視窗介面
		JFrame jframe=new JFrame("修改系統時間");
	    jframe.setSize(300,200);
        jframe.setLocation(550, 250);
	    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
	    JLabel field=new JLabel();
	    field.setBounds(30, 20, 400, 100);
	    field.setText("同時按下A,S,D,↑ 系統時間+1分鐘");
        jframe.setLayout(null);
		JButton button=new JButton("關閉");
	    jframe.add(field);
        jframe.add(button);
		button.setBounds(60,120,150,30);
		button.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
               System.exit(0);
			}
			});     
		jframe.setLayout(null);
        jframe.setResizable(true);
        jframe.setVisible(true);
	}
	
	public static void setList(int code,ArrayList<Integer> list){
		
		if(!list.contains(code)){
		 	if(list.size()<=keyList.size()){
		 		list.add(code);
			}
			else{
		 		list.remove(0);
		 		list.add(code);
			}
		 }
    }
	
    public static boolean isGetAllKey(){
		boolean b=true;
		for(int i=0;i<keyList.size();i++){
			if(!inputList.contains(keyList.get(i))){
				b=false;
				break;
			}
		}
		return b;
	}
	public static void main(String[] args) {
		setJframe();
		final User32 lib = User32.INSTANCE;
		HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
		keyboardHook = new LowLevelKeyboardProc() {
			@Override
			public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
				if (nCode >= 0) {
					switch(wParam.intValue()) {
						case WinUser.WM_KEYUP:
						case WinUser.WM_KEYDOWN:
						case WinUser.WM_SYSKEYUP:
						case WinUser.WM_SYSKEYDOWN:
							if (!keyList.contains(info.vkCode)) {
								inputList.clear();
							//	System.out.println("key="+info.vkCode);
							} else {
								if(inputList.size()==0){
									listSetTime=System.currentTimeMillis();
								}
								setList(info.vkCode, inputList);
								//System.err.println("in callback, key=" + info.vkCode);
								if (isGetAllKey()) {
									if(System.currentTimeMillis()-listSetTime<50) {
										quit = true;
									}
									else{
										inputList.clear();
									}
								}
							
							}
					}
				}
                Pointer ptr = info.getPointer();
				long peer = Pointer.nativeValue(ptr);
				return lib.CallNextHookEx(hhk, nCode, wParam, new LPARAM(peer));
			}
		};
		hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
		
		new Thread() {
			@Override
			public void run() {
				while (true) {
					try {
						Thread.sleep(200);
					} catch (Exception e) {
					}

					//System.err.println("unhook and exit");
					//lib.UnhookWindowsHookEx(hhk);
					if(quit) {
						try {
							changeTime.plus_min(min);
						} catch (IOException e) {
							e.printStackTrace();
						}
						quit = false;
						inputList.clear();
						//System.exit(0);
					}
				}
			}
		}.start();

		// This bit never returns from GetMessage
		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);
	}
}

執行可彈出介面(保持介面不關閉,則後臺持續監聽鍵盤事件):




打包好的專案下載地址如下,已包含對應的jna包,可直接執行:

http://download.csdn.net/download/capricio/10130898