#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,如果不用这个应该用什么?

解决方案 »

  1.   


    HWND windowHandle = FindWindow(NULL, _T("SomeOtherApp"));
    DWORD threadId = GetWindowThreadProcessId(windowHandle, NULL);
      

  2.   

    按这里解释的来看的话,貌似没啥问题http://www.cnblogs.com/del/archive/2008/02/25/1080516.htmlSetWindowsHookEx(
      idHook: Integer;   {钩子类型}
      lpfn: TFNHookProc; {函数指针}
      hmod: HINST;       {包含钩子函数的模块(EXE、DLL)句柄; 一般是 HInstance; 如果是当前线程这里可以是 0}
      dwThreadId: DWORD  {关联的线程; 可用 GetCurrentThreadId 获取当前线程; 0 表示是系统级钩子}
    ): HHOOK;            {返回钩子的句柄; 0 表示失败}dwThreadid可以使用当前线程(通过GetCurrentThreadId)第一个参数也是兼容线程级的WH_CALLWNDPROC     = 4;  {系统级或线程级; 截获发送到目标窗口的消息, 在 SendMessage 调用时发生}钩子不起作用表现在什么方面呢?