java jni 键盘_Java运用JNI调用dll(含源码)实现屏蔽系统热键和任务栏

由于功能和代码我是分开去实现的,所以这里代码步骤也分开附上。

首先,屏蔽系统热键

1、建一个Java包 shieldHK (把类建在包里,目的是为了其他的类方便的调用)

2、建一个类 ShieldHotKey

代码如下:

package shieldHK;

import java.util.logging.Level;

import java.util.logging.Logger;

/**

*

* @author Administrator

*/

public class ShieldHotKey {

static{

System.load("D:/shieldHK.dll");

}

public static native void Attach();//启动屏蔽

public static native void Detach();//关闭屏蔽

}

3、编译生成 ShieldHotKey.class 文件

4、运用.class文件生成.h头文件。

在命令行里敲指令进入到编译生成的 classes 文件夹里,输入 javah shieldHK.ShieldHotKey生成头文件。

5、用VC6.0编写生成dll文件。

5-1、新建一个dll工程,把刚生成的头文件 shieldHK.h 引入

头文件代码如下:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include "jni.h"

/* Header for class shieldHK_ShieldHotKey */

#ifndef _Included_shieldHK_ShieldHotKey

#define _Included_shieldHK_ShieldHotKey

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class:    shieldHK_ShieldHotKey

* Method:    Attach

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_shieldHK_ShieldHotKey_Attach

(JNIEnv *, jclass);

/*

* Class:    shieldHK_ShieldHotKey

* Method:    Detach

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_shieldHK_ShieldHotKey_Detach

(JNIEnv *, jclass);

#ifdef __cplusplus

}

#endif

#endif

5-2、编写 shieldHK.cpp 文件

代码如下:

/* Replace "dll.h" with the name of your header */

#include "shieldHK.h"

#define _WIN32_WINNT 0x0500 //Use WH_KEYBOARD_LL

#include

#include

//SAS window句柄

HWND hSASWnd = NULL;

//原有SAS window回调函数地址

FARPROC FOldProc = NULL;

//起屏蔽作用的新SAS window回调函数

LRESULT CALLBACK SASWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

//枚举所有窗体句柄的回调函数

BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam);

//Dll所创建线程的句柄

HANDLE hThread = NULL;

//Dll所创建线程的ID

DWORD dwThreadId = 0;

//Dll所创建线程的线程函数

DWORD WINAPI ThreadFunc();

//_H钩子句柄

HHOOK hHook = NULL;

//_H低级键盘钩子回调函数

LRESULT CALLBACK KeyboardProc(int,WPARAM,LPARAM);

//对外输出字符串

char szOutput[36];

BOOL APIENTRY Attach()

{

switch(DLL_PROCESS_ATTACH)

{

case DLL_PROCESS_ATTACH:

sprintf(szOutput,"Dll成功加载于 %d 号进程。",GetCurrentProcessId());

OutputDebugString(szOutput);

//创建更替SAS window回调函数的线程

if(FOldProc == NULL)

hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,&dwThreadId);

break;

case DLL_PROCESS_DETACH:

sprintf(szOutput,"Dll成功卸载。",GetCurrentProcessId());

//MessageBox(NULL, szOutput, "ZZ", MB_ICONINFORMATION | MB_OK);

OutputDebugString(szOutput);

//恢复原有SAS window的回调函数

if(FOldProc != NULL)

SetWindowLong(hSASWnd,GWL_WNDPROC,long(FOldProc));

//_H卸载低级键盘钩子

if(hHook != NULL)

{

if(!UnhookWindowsHookEx(hHook))

{

OutputDebugString("Unhook failed..");

//__leave;

break;

}

OutputDebugString("键盘钩子成功取消");

}

TerminateThread(hThread,1);

CloseHandle(hThread);

break;

case DLL_THREAD_ATTACH:

break;

case DLL_THREAD_DETACH:

break;

}

return TRUE;

}

BOOL APIENTRY Detach()

{

switch(DLL_PROCESS_DETACH)

{

case DLL_PROCESS_ATTACH:

sprintf(szOutput,"Dll成功加载于 %d 号进程。",GetCurrentProcessId());

OutputDebugString(szOutput);

//创建更替SAS window回调函数的线程

if(FOldProc == NULL)

hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,&dwThreadId);

break;

case DLL_PROCESS_DETACH:

sprintf(szOutput,"Dll成功卸载。",GetCurrentProcessId());

//MessageBox(NULL, szOutput, "ZZ", MB_ICONINFORMATION | MB_OK);

OutputDebugString(szOutput);

//恢复原有SAS window的回调函数

if(FOldProc != NULL)

SetWindowLong(hSASWnd,GWL_WNDPROC,long(FOldProc));

//_H卸载低级键盘钩子

if(hHook != NULL)

{

if(!UnhookWindowsHookEx(hHook))

{

OutputDebugString("Unhook failed..");

//__leave;

break;

}

OutputDebugString("键盘钩子成功取消");

}

TerminateThread(hThread,1);

CloseHandle(hThread);

break;

case DLL_THREAD_ATTACH:

break;

case DLL_THREAD_DETACH:

break;

}

return TRUE;

}

//Dll所创建线程的线程函数

DWORD WINAPI ThreadFunc()

{

//打开Winlogon桌面

HDESK hDesk = OpenDesktop("Winlogon",0,FALSE,MAXIMUM_ALLOWED);

//枚举桌面所有窗体

EnumDesktopWindows(hDesk,(WNDENUMPROC)EnumWindowsProc,0);

//修改SAS window的回调函数

if(hSASWnd != NULL)

{

FOldProc = (FARPROC)SetWindowLong(hSASWnd,GWL_WNDPROC,long(SASWindowProc));

}

CloseHandle(hDesk);

//_H同一桌面上进程之间只能发送窗口消息。无法跨进程与其他桌面发送它们。

//_H同样,Windows消息是限制应用程序定义挂钩。

//_H特定桌面中运行的进程挂钩过程将〈〈只获得针对同一桌面上创建窗口消息。〉〉

//_H详见http://support.microsoft.com/kb/171890/zh-cn

//_H所以,这里必须设置钩子所在线程的桌面为Default桌面

//_H才能使得钩子所在线程能接收到Default桌面的消息

hDesk = OpenDesktop("Default",0,FALSE,MAXIMUM_ALLOWED);

SetThreadDesktop(hDesk);

CloseHandle(hDesk);

//_H设置低级键盘钩子,屏蔽非SAS window的热键

//_H需要#define _WIN32_WINNT 0x0500

hHook = SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardProc,GetModuleHandle(NULL),0);

if (hHook == NULL)

{

OutputDebugString("Set hook failed..");

//__leave;

return 1;

}

OutputDebugString("键盘钩子成功设置");

//_H在非GUI线程中使用消息钩子必须主动接收并分发收到的消息

MSG msg;

while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return 1;

}

//枚举所有窗体句柄的回调函数

BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)

{

char ClassBuf[128];

//获得当前窗体的显示文本

GetWindowText(hwnd,ClassBuf,sizeof(ClassBuf));

//在"Winlogon"桌面中查询窗口"SAS window"。

if(strstr(ClassBuf,"SAS window")!=NULL)

{

//返回SAS window句柄

hSASWnd = hwnd;

return FALSE;

}

return TRUE;

}

//起屏蔽作用的新SAS window回调函数

LRESULT CALLBACK SASWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)

{

if(uMsg == WM_HOTKEY)

{

//屏蔽所有WM_HOTKEY消息

OutputDebugString("All SAS window's hotkeys are disabled");

return 1;

WORD wKey = HIWORD(lParam);

WORD wModifier = LOWORD(lParam);

bool IsCtrlDown = ((wModifier & VK_CONTROL) != 0);

bool IsAltDown = ((wModifier & VK_MENU) != 0);

bool IsShiftDown = ((wModifier & VK_SHIFT) != 0);

//Ctrl + Alt + Del组合键

if(IsCtrlDown && IsAltDown && wKey == VK_DELETE)

{

return 1; //屏蔽

}

//Ctrl + Shift + Esc组合键,这个组合键将显示任务管理器,可根据需要是否屏蔽。

else if(IsCtrlDown && IsShiftDown && wKey == VK_ESCAPE)

{

// Do nothing

}

}

return CallWindowProc((WNDPROC)FOldProc,hwnd,uMsg,wParam,lParam);

}

//_H低级键盘钩子回调函数

LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)

{

if (nCode == HC_ACTION)

{

switch (wParam)

{

case WM_KEYDOWN: case WM_SYSKEYDOWN:

//case WM_KEYUP:    case WM_SYSKEYUP:

PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;

if (p->vkCode == VK_F12)

{

//实现模拟按键代码

MessageBox(GetForegroundWindow(),"I'm in position..","ZZ",MB_OK);

}

//屏蔽ALT+TAB

else if ((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0))

{

OutputDebugString("ALT+TAB is disabled");

return 1;

}

//屏蔽ALT+ESC

else if ((p->vkCode == VK_ESCAPE) && ((p->flags & LLKHF_ALTDOWN) != 0))

{

OutputDebugString("ALT+ESC is disabled");

return 1;

}

//屏蔽CTRL+ESC

else if ((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0))

{

OutputDebugString("CTRL+ESC is disabled");

return 1;

}

//屏蔽CTRL+SHIFT+ESC,(SAS window中也已屏蔽)

else if ((p->vkCode == VK_ESCAPE) &&

((GetKeyState(VK_CONTROL) & 0x8000) != 0) &&

((GetKeyState(VK_SHIFT) & 0x8000) != 0))

{

OutputDebugString("CTRL+SHIFT+ESC is disabled");

return 1;

}

//屏蔽ALT+F4

else if ((p->vkCode == VK_F4) && ((p->flags & LLKHF_ALTDOWN) != 0))

{

OutputDebugString("ALT+F4 is disabled");

return 1;

}

//屏蔽左右windows键

else if (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN)

{

OutputDebugString("windows key is disabled");

return 1;

}

//此处无法屏蔽CTRL+ALT+DEL,已在SAS window中屏蔽

else if ((p->vkCode == VK_DELETE) &&

((GetKeyState(VK_CONTROL) & 0x8000) != 0) &&

((GetKeyState(VK_MENU) & 0x8000) != 0 ))

return 1;

break;

}

}

return CallNextHookEx(hHook,nCode,wParam,lParam);

}

JNIEXPORT void JNICALL Java_shieldHK_ShieldHotKey_Attach

(JNIEnv *env, jclass obj){

Attach();

}

JNIEXPORT void JNICALL Java_shieldHK_ShieldHotKey_Detach

(JNIEnv *env, jclass obj){

Detach();

}

5-3、编译生成 shieldHK.dll 文件

最后 shieldHK.dll 就可以在 ShieldHotKey 类里调用了。比如Attach()跟Detach();

至于去掉任务栏与上面的步骤是一样的

在这里附上C++代码:

/* Replace "dll.h" with the name of your header */

#include "registerHK.h"

#include

#include

#include

using namespace std;

void HideTaskBar(BOOL bHide);

void HideTaskBar(BOOL bHide)

{

int nCmdShow;

HWND hWnd;

LPARAM lParam;

hWnd = FindWindow("Shell_TrayWnd",NULL);

if(bHide == TRUE)

{

nCmdShow = SW_HIDE;

lParam = ABS_AUTOHIDE | ABS_ALWAYSONTOP;

}

else

{

nCmdShow = SW_SHOW;

lParam = ABS_ALWAYSONTOP;

}

ShowWindow(hWnd,nCmdShow);//隐藏任务栏

#ifndef ABM_SETSTATE

#define ABM_SETSTATE 0x0000000a

#endif

APPBARDATA apBar;

memset(&apBar, 0, sizeof(apBar));

apBar.cbSize = sizeof(apBar);

apBar.hWnd = hWnd;

if(apBar.hWnd != NULL)

{

apBar.lParam = lParam;

SHAppBarMessage(ABM_SETSTATE, &apBar); //设置任务栏自动隐藏

}

}

JNIEXPORT void JNICALL Java_shieldHK_RegisterHotKey_HideTaskBar

(JNIEnv *env, jclass obj, jboolean b){

HideTaskBar(b);

}

OK,全部搞定。

Java对象序列化ObjectOutputStream和ObjectInputStream示例 http://www.linuxidc.com/Linux/2012-08/68360.htm

0b1331709591d260c1c78e86d0c51c18.png

你可能感兴趣的:(java,jni,键盘)