在此,顺便推荐一个笔记本软件,感觉还是挺好用的,云效益记录本: 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);
}
}