#include "com_hetc_emsbgf_tools_servicesmonitor_TaskBarMonitor.h"
#include <windows.h>
#include <tchar.h>//全局变量
HINSTANCE hInstance;//保存DLL实例句柄
HHOOK hHook;//钩子句柄
int WM_TASKBARCREATED;//TaskbarCreated消息代码
jobject jobj;//回调目标的Java对象
JavaVM *jvm;//Java虚拟机指针
jint jniVersion;//JNI版本
jmethodID jCallbackMid;//回调方法指针LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{//钩子处理函数,判断消息是否为TaskbarCreated,若是则回调Java方法
if(jvm)
{
CWPSTRUCT* pMsg=(CWPSTRUCT*)lParam;
if(pMsg->message==WM_TASKBARCREATED)
{
JNIEnv *env;//获取当前线程(应该会是AWT消息循环线程)的JNIEnv
if(JNI_OK==jvm->GetEnv((void **)&env,jniVersion))
env->CallVoidMethod(jobj,jCallbackMid);//回调Java方法
}
}
return CallNextHookEx(hHook,nCode,wParam,lParam);
}JNIEXPORT jboolean JNICALL Java_com_hetc_emsbgf_tools_servicesmonitor_TaskBarMonitor_installHook
(JNIEnv *env, jobject obj)
{//安装钩子,保存必要的全局引用
WM_TASKBARCREATED=RegisterWindowMessage(_T("TaskbarCreated"));
hHook=SetWindowsHookEx(WH_CALLWNDPROC,HookProc,hInstance,0);
if(hHook && WM_TASKBARCREATED)
{
jclass cls = env->GetObjectClass(obj);//获取监视器的Java类
if(cls)
{
jmethodID tempMid=env->GetMethodID(cls,"hookCallback","()V");//获取回调方法的局部引用
if(tempMid)
{
jniVersion=env->GetVersion();//获取JNI版本号
env->GetJavaVM(&jvm);//保存JVM指针
jobj=env->NewGlobalRef(obj);//创建监视器对象的全局引用
jCallbackMid=(jmethodID)env->NewGlobalRef((jobject)tempMid);
//创建回调方法的全局引用
return (jboolean)1;
}
}
}
return (jboolean)0;
}JNIEXPORT jboolean JNICALL Java_com_hetc_emsbgf_tools_servicesmonitor_TaskBarMonitor_unInstallHook
(JNIEnv *env, jobject obj)
{//撤销钩子,释放全局引用
if(hHook)
{
if(jobj)
env->DeleteGlobalRef(jobj);
if(jCallbackMid)
env->DeleteGlobalRef((jobject)jCallbackMid);
return (jboolean)UnhookWindowsHookEx(hHook);
}
else
return (jboolean)0;
}BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{//DLL入口函数,保存DLL实例句柄
if(fdwReason==DLL_PROCESS_ATTACH)
{
hInstance=hinstDLL;
}
return true;
}我想问一下hHook=SetWindowsHookEx(WH_CALLWNDPROC,HookProc,hInstance,0);这里的最后一个参数改成GetCurrentThreadId()为什么钩子就不起作用?我这个DLL主要是用于JNI,java调用的,是不是不该用GetCurrentThreadId()得到的线程ID,如果不用这个应该用什么?
#include <windows.h>
#include <tchar.h>//全局变量
HINSTANCE hInstance;//保存DLL实例句柄
HHOOK hHook;//钩子句柄
int WM_TASKBARCREATED;//TaskbarCreated消息代码
jobject jobj;//回调目标的Java对象
JavaVM *jvm;//Java虚拟机指针
jint jniVersion;//JNI版本
jmethodID jCallbackMid;//回调方法指针LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{//钩子处理函数,判断消息是否为TaskbarCreated,若是则回调Java方法
if(jvm)
{
CWPSTRUCT* pMsg=(CWPSTRUCT*)lParam;
if(pMsg->message==WM_TASKBARCREATED)
{
JNIEnv *env;//获取当前线程(应该会是AWT消息循环线程)的JNIEnv
if(JNI_OK==jvm->GetEnv((void **)&env,jniVersion))
env->CallVoidMethod(jobj,jCallbackMid);//回调Java方法
}
}
return CallNextHookEx(hHook,nCode,wParam,lParam);
}JNIEXPORT jboolean JNICALL Java_com_hetc_emsbgf_tools_servicesmonitor_TaskBarMonitor_installHook
(JNIEnv *env, jobject obj)
{//安装钩子,保存必要的全局引用
WM_TASKBARCREATED=RegisterWindowMessage(_T("TaskbarCreated"));
hHook=SetWindowsHookEx(WH_CALLWNDPROC,HookProc,hInstance,0);
if(hHook && WM_TASKBARCREATED)
{
jclass cls = env->GetObjectClass(obj);//获取监视器的Java类
if(cls)
{
jmethodID tempMid=env->GetMethodID(cls,"hookCallback","()V");//获取回调方法的局部引用
if(tempMid)
{
jniVersion=env->GetVersion();//获取JNI版本号
env->GetJavaVM(&jvm);//保存JVM指针
jobj=env->NewGlobalRef(obj);//创建监视器对象的全局引用
jCallbackMid=(jmethodID)env->NewGlobalRef((jobject)tempMid);
//创建回调方法的全局引用
return (jboolean)1;
}
}
}
return (jboolean)0;
}JNIEXPORT jboolean JNICALL Java_com_hetc_emsbgf_tools_servicesmonitor_TaskBarMonitor_unInstallHook
(JNIEnv *env, jobject obj)
{//撤销钩子,释放全局引用
if(hHook)
{
if(jobj)
env->DeleteGlobalRef(jobj);
if(jCallbackMid)
env->DeleteGlobalRef((jobject)jCallbackMid);
return (jboolean)UnhookWindowsHookEx(hHook);
}
else
return (jboolean)0;
}BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{//DLL入口函数,保存DLL实例句柄
if(fdwReason==DLL_PROCESS_ATTACH)
{
hInstance=hinstDLL;
}
return true;
}我想问一下hHook=SetWindowsHookEx(WH_CALLWNDPROC,HookProc,hInstance,0);这里的最后一个参数改成GetCurrentThreadId()为什么钩子就不起作用?我这个DLL主要是用于JNI,java调用的,是不是不该用GetCurrentThreadId()得到的线程ID,如果不用这个应该用什么?
解决方案 »
- 求解一个简单的JAVA问题,小菜鸟一枚,求各种老鸟大神路过的进来帮忙解决下,谢谢哈!
- java里有类似delphi中的char()方法吗?半夜了,谢谢!
- java面试题(请老鸟帮忙一下)急啊!!!!!!!!!!!!!
- 运行servlet,出现错误:The requested resource () is not available.
- 学习API文档?
- 怎么样可以是JFrame在显示后就自动最小化?
- 学习JAVA,各位大虾推荐几本好书
- static类型的变量是不是不能放在main函数中啊?为什么?
- Java 从何从带有构造函数的类中派生出一个新类?
- 怎么得到一个JAVA程序有多少个线程在运行中?
- 重写ClassLoader
- 在java中多线程中,如何让一个上一个线程执行完成后,才开始下一个线程执行
HWND windowHandle = FindWindow(NULL, _T("SomeOtherApp"));
DWORD threadId = GetWindowThreadProcessId(windowHandle, NULL);
idHook: Integer; {钩子类型}
lpfn: TFNHookProc; {函数指针}
hmod: HINST; {包含钩子函数的模块(EXE、DLL)句柄; 一般是 HInstance; 如果是当前线程这里可以是 0}
dwThreadId: DWORD {关联的线程; 可用 GetCurrentThreadId 获取当前线程; 0 表示是系统级钩子}
): HHOOK; {返回钩子的句柄; 0 表示失败}dwThreadid可以使用当前线程(通过GetCurrentThreadId)第一个参数也是兼容线程级的WH_CALLWNDPROC = 4; {系统级或线程级; 截获发送到目标窗口的消息, 在 SendMessage 调用时发生}钩子不起作用表现在什么方面呢?