天天看點

java 實作驅動級鍵盤事件

最近想玩網遊,想用按鍵精靈來自動做一些事情,可惜遊戲屏蔽了按鍵精靈,也沒辦法用普通的window消息來實作。

郁悶中,偶然發現一個winIO,可以實作驅動級模拟,

http://apps.hi.baidu.com/share/detail/22536342

不過呢本人對vb不熟,于是萌生了改成java版的念頭。

首先是java調用dll,不用說了,最容易的是jnative。

首先實作winIO部分api

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;


public class WinIOAPI {
	public static final int CONTROL_PORT = 0x64;
	public static final int DATA_PORT = 0x60;
	static{
		System.loadLibrary("WinIo32");
		JNative.setLoggingEnabled(true);
		if(!InitializeWinIo()){
			System.err.println("Cannot Initialize the WinIO");
			System.exit(1);
		}
		
	}
	
	
	
	public static void KBCWait4IBE() throws Exception{
		int val=0;
		do {
			Pointer p=new Pointer(MemoryBlockFactory.createMemoryBlock(8));
			if(!GetPortVal(CONTROL_PORT,p, 1)){
				System.err.println("Cannot get the Port");
			}
			val = p.getAsInt(0);
			
		} while ((0x2&val)>0);
		
		
		
		
	}
	
	public static boolean InitializeWinIo() {
		
		try{
		 JNative jnative = new JNative("WinIo32","InitializeWinIo");
		 jnative.setRetVal(Type.INT);
		 jnative.invoke();
		 int re=jnative.getRetValAsInt();
		 jnative.dispose();
		 return re>0;
		}catch (Exception e) {
			e.printStackTrace();
			return false;
		}finally{
			
		}
		 
	}
	
	
	public static boolean GetPortVal(int portAddr, Pointer pPortVal, int size) throws Exception{
		
		JNative j2 = new JNative("WinIo32","GetPortVal");
		 j2.setRetVal(Type.INT);
		 
		 j2.setParameter(0, portAddr);
		 j2.setParameter(1, pPortVal);
		 j2.setParameter(2, size);
		 j2.invoke();
		 int re=j2.getRetValAsInt();
		 j2.dispose();
		 return re>0;
		
	}
	
	public static boolean SetPortVal(int portAddr, int portVal, int size) throws Exception{
		
		JNative j2 = new JNative("WinIo32","SetPortVal");
		 j2.setRetVal(Type.INT);
		 j2.setParameter(0, portAddr);
		 j2.setParameter(1,portVal);
		 j2.setParameter(2, size);
		 j2.invoke();
		 int re=j2.getRetValAsInt();
		 j2.dispose();
		 return re>0;
		
	}
	

}
           

 由于輸入的不是VK值,是以我們還需要一個函數來把vk轉化為鍵盤值

import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;


public class User32 extends org.xvolks.jnative.util.User32{
	private static Map<Integer,Integer> keycache=new HashMap();
	public static int MapVirtualKeyA(int key) throws Exception{
		if(!keycache.containsKey(key)){
			JNative jnative=new JNative(DLL_NAME, "MapVirtualKeyA");
			jnative.setRetVal(Type.INT);
			jnative.setParameter(0, key);
			jnative.setParameter(1, 0);
			jnative.invoke();
			int re=jnative.getRetValAsInt();
			keycache.put(key, re);
		}
		return keycache.get(key);
	}
	
	
}
           

 最後就是按鍵部分

public class VirtualKeyBoard {
	
	public static void KeyDown(int key) throws Exception{
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.CONTROL_PORT,0xd2,1);
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.DATA_PORT,key,1);
	}
	public static void KeyDownEx(int key) throws Exception{
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.CONTROL_PORT,0xd2,1);
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.DATA_PORT,0xe0,1);
		
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.CONTROL_PORT,0xd2,1);
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.DATA_PORT,key,1);
		
	}
	public static void KeyUpEx(int key) throws Exception{
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.CONTROL_PORT,0xd2,1);
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.DATA_PORT,0xe0,1);
		
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.CONTROL_PORT,0xd2,1);
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.DATA_PORT,(key|0x80),1);
		
	}
	public static void KeyUp(int key) throws Exception{
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.CONTROL_PORT,0xd2,1);
		WinIOAPI.KBCWait4IBE();
		WinIOAPI.SetPortVal(WinIOAPI.DATA_PORT,(key|0x80),1);
		
	}
	
	public static void KeyPress(int key) throws Exception{
		KeyDown(key);
		KeyUp(key);
	}

}
           

最後附上源碼,界面如下

java 實作驅動級鍵盤事件