代码之家  ›  专栏  ›  技术社区  ›  Mark Ingram

如何正确使用setwindowshookex&callnexthookex

  •  8
  • Mark Ingram  · 技术社区  · 16 年前

    我可以正确设置一个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(...);
            ...
    }
    

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

    编辑: 主要问题是hhook是从setWindowsHookex返回的,需要传递给callNexthookex函数。

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

    1 回复  |  直到 16 年前
        1
  •  10
  •   Charlie    16 年前

    根据文档,正确的做法是将您直接收到的参数传递给callnexthookex,与您收到的参数完全相同。不管您是否决定处理hook消息,您也应该调用callnexthookex。

    According to MSDN ,的第一个参数 CallNextHookEx 在NT/XP/2003上被忽略,对于基于Win95的旧操作系统,它应该是 HHOOK 你在注册你的钩子时收到的 SetWindowsHookEx .这些文档没有为Windows2000指定值,但是由于它是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 那将绕过 长喙鱼 .