子线程设置的钩子(HOOK)为什么钩不到消息?

其实无论在子线程还是主线程中,设置的钩子都是一样的。但是,如果只是像在主线程中那样调用完SetWindowsHookEx函数就以为没事了,那你有可能什么也钩不到。如果你设置的是鼠标钩子,你还会看到鼠标反应迟顿。这是为什么呢?

前些日子我就遇到过这事,在网上搜了半天也没找到解决方案。无奈,自己仔细研究,找到原因了,非常简单,与大家分享。

答案就是,调用完SetWindowsHookEx后,子线程中要启动消息泵,不能Sleep在那里,也不能因为等待事件而阻塞在任何地方。把下面的代码加到你的子线程中,你的钩子就可以起作用了:

 MSG msg;

 while(GetMessage(&msg, NULL, 0, 0))

    {       

      TranslateMessage(&msg);

      DispatchMessage(&msg);

    }

这是为什么呢?事实上这和Windows的消息驱动机制有关。Windows中几乎所有的线程、进程间通信都是使用“消息”来实现的。使用消息通知而不是直接调用你提供的函数代码,可以起到线程的隔离和保护作用,防止线程执行不安全的代码。

但这样一来,如果你不接收消息,你就不会得到任何消息。Windows事实上是把消息放到线程的消息队列中,然后线程自己使用GetMessage函数取出来,再使用DispatchMessage分发到各个响应函数中执行。如果你设置了钩子(HOOK)那么GetMessage会先调用那些钩子函数。当然不只是GetMessage, PeekMessage也可以。如果你没调用这两个函数,不只是钩不到消息,说不定你的线程连个消息队列都还没建立呢!

这也解释了鼠标反应迟顿问题。系统把消息给你的线程之后,就等你的线程中的响应结果。可是你没理会它,那它只好在每个消息后都等一会儿。这样就反应迟顿了。

那后来为什么又好了呢?估计是你的消息队列占满了,系统一看这小子太懒了,索性就不把消息给你了,也就不用等了。这样鼠标就又正常了。

更多内容可以看我的上一篇文章:谁在调用那些回调函数

为了让更多人能搜到答案,我多写几个关键字:钩子,线程,子线程,HOOKSetWindowsHook, SetWindowsHookEx,钩不到,不起作用,没作用,没用。

 

作者:苏林

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值