当前位置:编程学习 > JAVA >>

钩子问题

#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
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,