现在的位置: 首页 > 综合 > 正文

java运用jni调用dll实现屏蔽系统热键和任务栏

2018年01月30日 ⁄ 综合 ⁄ 共 7566字 ⁄ 字号 评论关闭

由于自己不懂写C/C++,所以在网上找了些C++的代码,通过自己的修改和调用,实现了对系统热键的屏蔽以及去掉任务栏功能
由于功能和代码我是分开去实现的,所以这里代码步骤也分开附上。
首先,屏蔽系统热键
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 <windows.h> 
#include <stdio.h> 

//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 <windows.h> 
#include <cstdlib> 
#include <iostream> 

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,全部搞定。

下面附上两个编译好的dll文件

http://leesonhomme.iteye.com/blog/549034

抱歉!评论已关闭.