钩子问题
#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,如果不用这个应该用什么?
--------------------编程问答-------------------- 补充一点,我不想用全局钩子,只要线程的钩子。 --------------------编程问答--------------------
--------------------编程问答-------------------- 按这里解释的来看的话,貌似没啥问题
HWND windowHandle = FindWindow(NULL, _T("SomeOtherApp"));
DWORD threadId = GetWindowThreadProcessId(windowHandle, NULL);
http://www.cnblogs.com/del/archive/2008/02/25/1080516.html
SetWindowsHookEx(
idHook: Integer; {钩子类型}
lpfn: TFNHookProc; {函数指针}
hmod: HINST; {包含钩子函数的模块(EXE、DLL)句柄; 一般是 HInstance; 如果是当前线程这里可以是 0}
dwThreadId: DWORD {关联的线程; 可用 GetCurrentThreadId 获取当前线程; 0 表示是系统级钩子}
): HHOOK; {返回钩子的句柄; 0 表示失败}
dwThreadid可以使用当前线程(通过GetCurrentThreadId)
第一个参数也是兼容线程级的
WH_CALLWNDPROC = 4; {系统级或线程级; 截获发送到目标窗口的消息, 在 SendMessage 调用时发生}
钩子不起作用表现在什么方面呢?
补充:Java , Java SE