如何正确使用SetWindowsHookEx和CallNextHookEx函数

13

我可以正确地设置Windows钩子,但是MSDN中的一句话让我感到困惑:“调用CallNextHookEx函数链接到下一个钩子程序是可选的,但强烈建议这样做;否则,安装了钩子的其他应用程序将无法接收钩子通知,并可能因此表现不正常。除非您确实需要防止通知被其他应用程序看到,否则应调用CallNextHookEx。”

我希望成为优秀的编程人员并调用下一个钩子。但是,我的钩子过程看起来像这样:

LRESULT CALLBACK CBTProc(int code, WPARAM wp, LPARAM lp)
{
    if (code != HCBT_CREATEWND)
        {
                // What do I do here? It's not the event I requested so how do I pass it on?
        return 0;
    }

    // It's the code we want (create window)
        CallNextHookEx(...);
        ...
}

那么,如果钩子过程中的代码不是我感兴趣的,会发生什么?我该如何调用下一个钩子?

编辑:主要问题是,在SetWindowsHookEx中返回了HHOOK,并且需要将其传递给CallNextHookEx函数。

更新:在NT平台上忽略了钩子参数:
http://msdn.microsoft.com/en-us/library/ms644974.aspx
http://www.klenotic.com/pl/null_hhook/

1个回答

15
根据文档,正确的方法是将收到的参数直接传递给CallNextHookEx,就像你收到的那样。无论你决定如何处理钩子消息,都应该调用CallNextHookEx。根据MSDN,在NT/XP/2003上,CallNextHookEx的第一个参数被忽略,而对于基于旧Win95的操作系统,它应该是在使用SetWindowsHookEx注册钩子时收到的HHOOK。文档没有为Windows 2000指定值,但由于它是NT系列的一部分,一个合理的猜测是在那里也被忽略了。鉴于这一切,为NT系列操作系统编写该方法的好方法可能是这样的:
LRESULT CALLBACK CBTProc( int code, WPARAM wp, LPARAM lp )
{
    if( code == HCBT_CREATEWND )
        ProcessCreateWnd( wp, lp );
    return CallNextHookEx( 0, code, wp, lp );
}

void ProcessCreateWnd( WPARAM wp, LPARAM lp )
{
    // my code here
}

这样做可以确保你始终在处理结束时调用钩子,使得意外添加 return 以绕过 CallNextHookEx 变得困难。


嗯,你可能有点道理。我错过了关于在NT / XP / 2003上忽略“hhk”参数的部分。现在要进行一些测试。 - Mark Ingram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接