没有调用WH_KEYBOARD_LL挂钩

时间:2011-02-19 13:12:37

标签: c# c++ winapi visual-c++ hook

我遇到了WH_KEYBOARD_LL钩子的一些问题:

我使用全局LL挂钩的原因并不重要我只需要它用于我的应用程序(我尝试过其他类型的挂钩,但它们对我不起作用)。

钩子函数在dll中,dll在应用程序启动时加载,钩子也在主线程启动时设置。这非常有效。当我需要取消激活挂钩并重新激活它时,会出现问题。如果我从应用程序的主线程执行此操作它可以正常工作,但我需要的是从计时器执行此操作,这里出了问题。我使用计时器检查我的应用程序的窗口是否是前台窗口(活动窗口),如果是,则挂钩被激活,如果不是,则挂钩被停用。从计时器调用时SetWindowsHookEx的返回值总是正常(非空),根据MSDN意味着挂钩已成功设置,但我的挂钩函数永远不会被调用。

以下是我设置钩子的方法:

SetWindowsHookEx(WH_KEYBOARD_LL, keyboardHookProcedure,
                 GetModuleHandle(curModule.ModuleName), 0);

有没有人经历过这个?

我的唯一猜测是我的钩子函数在一个dll中,而计时器回调来自另一个dll,这与我的问题有什么关系吗?

3 个答案:

答案 0 :(得分:6)

钩子回调是在调用SetWindowsHookEx()的同一个线程上进行的。这一点魔法需要该线程泵送消息循环。哪个是摩擦,你的计时器回调方法是从线程池线程调用的。它没有泵,它甚至不能足够长时间才能获得钩子回调。

调用UI线程或使用同步计时器。或者考虑暂时禁用你在钩子回调中做的任何事情而不是完全禁用或替换钩子,这当然是最有意义的。

答案 1 :(得分:0)

对于它的价值,我在代码中使用GetModuleHandle(0)来表示SetWindowsHookEx。我不知道这是不是你的问题 - 我的代码是单线程的。

答案 2 :(得分:0)

您可以检查钩子函数中的前景窗口,并完全删除计时器线程。这就是我在TouchCursor中所做的。您可以查看my code on SourceForge - 第553行的钩子函数。