Java 通过JNI实现监听键盘鼠标

在此,顺便推荐一个笔记本软件,感觉还是挺好用的,云效益记录本: www.ushooo.com,

支持markdown,富文本编辑,还免费,非常不错。

该测试是基于Windows 操作系统的。

Java 部分 : 
 

package robot;
public class KeyBoard {
	public native void listenDelegate(String className , String callback);
}

C 语言部分 :

头文件keyboard.h 该头文件需要使用javah 命令生成,教程这里不作讲解。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class robot_KeyBoard */

#ifndef _Included_robot_KeyBoard
#define _Included_robot_KeyBoard
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     robot_KeyBoard
 * Method:    listenDelegate
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_robot_KeyBoard_listenDelegate
  (JNIEnv *, jobject, jstring, jstring);

#ifdef __cplusplus
}
#endif
#endif

实现文件 :

keyboard.c

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "main.h"

#include <windows.h>
HHOOK g_ms_hook = 0;
HHOOK g_kb_hook = 0;

JNIEnv * env ;
jobject object ;
jmethodID _mtd ;
jmethodID _mtd_mouse ;
void callback_kay(char * keyboard , int type) ;

JNIEXPORT void JNICALL Java_robot_KeyBoard_listenDelegate(JNIEnv * _env,jobject obj,jstring classname, jstring callback)
{

  	env = _env ;
	const char *_classname =(*env)->GetStringUTFChars(env,classname, 0);

	printf("class:%s\\n",_classname);

	jclass  classObject = (*env)->FindClass(env,_classname);
	if(classObject==0){
  		printf("init class failed\\n");
  		return ;
  	}



	//默认构造函数,不传参数
	jmethodID _contrustor = (*env)->GetMethodID(env, classObject , "<init>", "()V");
       //通过NewObject来创建对象
	object = (*env)->NewObject(env, classObject ,_contrustor);

	const char *_mtdname =(*env)->GetStringUTFChars(env , callback , 0);

  	printf("_mtdname:%s\\n",_mtdname);

	_mtd = (*env)->GetMethodID(env,classObject ,_mtdname,"(Ljava/lang/String;I)V");
    _mtd_mouse = (*env)->GetMethodID(env,classObject ,"mousePress","(II)V");
	printf("_mtd : %p , _mtd_mouse : %p \\n" , _mtd , _mtd_mouse);

	if(_mtd==0){
    	printf("init class[%s] method[%s] failed",_classname,_mtdname);
    	return;
	}
	if(object==0) {
			printf("init class[%s] object failed\\n",_classname);
    	return;
	}

	printf("object: %p\\n",object);


	//callback_kay("Hello , I am C language .");

	_init_keyboard ();
}

void callback_kay(char * keyboard , int type){

	(*env)->CallVoidMethod(env, object , _mtd , (*env)->NewStringUTF(env , keyboard) , type);

}

void mouse_press(int direction , int type) {
    (*env)->CallVoidMethod(env, object , _mtd_mouse , direction , type);
}

LRESULT CALLBACK kb_proc (int code, WPARAM w, LPARAM l)
{
    int keycode = ((PKBDLLHOOKSTRUCT)l)->vkCode ;
    char string[25];
    callback_kay(itoa(keycode, string, 10) , w==WM_KEYDOWN ? 1 : 0);
    //printf((w==WM_KEYDOWN)?"按下%c\\n":"抬起%c\\n",((PKBDLLHOOKSTRUCT)l)->vkCode);
    return CallNextHookEx (g_kb_hook, code, w, l);
}
LRESULT CALLBACK ms_proc (int code, WPARAM w, LPARAM l)
{

    if(w == WM_LBUTTONDOWN || w == WM_LBUTTONUP || w == WM_RBUTTONDOWN
       || w == WM_RBUTTONUP) {
        mouse_press(w == WM_LBUTTONDOWN || w == WM_LBUTTONUP ? 0 : 1,
                w == WM_LBUTTONUP || w == WM_RBUTTONUP ? 0 : 1);
     }

    /*if(w == WM_LBUTTONDOWN)
        printf("按下左键\\n");
    else if(w == WM_LBUTTONUP)
        printf("抬起左键\\n");
    else {
    	//printf("x:%d\\ty:%d\\n",((PMSLLHOOKSTRUCT)l)->pt.x,((PMSLLHOOKSTRUCT)l)->pt.y);
	}*/

    return CallNextHookEx (g_ms_hook, code, w, l);
}
void _init_keyboard ()
{
    g_kb_hook = SetWindowsHookEx (WH_KEYBOARD_LL,kb_proc,GetModuleHandle (NULL),0);
    g_ms_hook = SetWindowsHookEx (WH_MOUSE_LL, ms_proc,GetModuleHandle(NULL),0);

    if (g_kb_hook == NULL || g_ms_hook == NULL)
    {
        printf("安装钩子出错\\n");
        return ;
    };
    MSG msg;
    while (GetMessage (&msg, NULL, 0, 0))
    {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    };
    UnhookWindowsHookEx (g_kb_hook);

}

我这里是使用CodeBlock开发工具来进行编译生成dll动态链库的。在新建项目时选择dll library,

在Global compiler settings 中的,Search directories 选项卡下的compiler 选项卡加入Java

的两个库。

例 :C:\\Program Files\\Java\\jdk1.8.0_91\\include

C:\\Program Files\\Java\\jdk1.8.0_91\\include\\win32

dll的使用 :

package robot;

public class TestRobot {

	 static{  
		System.loadLibrary("keyboard");  
	}  
	public static void main(String[] args) {
		new KeyBoard().listenDelegate("robot/TestRobot","keyboardListen"); 
	}
	//(Ljava/lang/String;)V
	//String keyCode
	public void keyboardListen(String keyCode , int type) {
		System.out.println("keyCode:" + keyCode + " , type : " + type);
		//System.out.println(" java key event : " + KeyEvent.VK_0 + " , pad : " + KeyEvent.VK_NUMPAD0);
	}
	
	/**
	 * direction : 0 鼠标单击左键, 1 鼠标单击右键
	 * type : 0 按下 ,1 松开
	 */
	public void mousePress(int direction , int type) {
		System.out.println(" direction : " + direction+ " , type : " + type);
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值