windows 如何正确使用 SetWindowsHookEx & CallNextHookEx

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/214022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 05:34:40  来源:igfitidea点击:

How to correctly use SetWindowsHookEx & CallNextHookEx

windowswinapihook

提问by Mark Ingram

I can correctly setup up a windows hook, but I get confused by the line in MSDN that says "Calling the CallNextHookEx function to chain to the next hook procedure is optional, but it is highly recommended; otherwise, other applications that have installed hooks will not receive hook notifications and may behave incorrectly as a result. You should call CallNextHookEx unless you absolutely need to prevent the notification from being seen by other applications.".

我可以正确设置一个 windows 钩子,但我对 MSDN 中的一行感到困惑:“调用 CallNextHookEx 函数以链接到下一个钩子过程是可选的,但强烈建议这样做;否则,其他安装了钩子的应用程序将不接收挂钩通知,因此可能会出现错误行为。除非您绝对需要防止其他应用程序看到该通知,否则您应该调用 CallNextHookEx。”。

I want to be a good programming citizen and call the next hook. But, my hook procedure looks like this:

我想成为一名优秀的编程公民并调用下一个钩子。但是,我的钩子程序如下所示:

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(...);
        ...
}

So, what happens in the hook procedure if the code isn't the one I'm interested in? How do I call the next hook?

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

Edit:The main problem is that a HHOOK is returned from the SetWindowsHookEx, and that needs to be passed to the CallNextHookEx function.

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

Update:It seems the hook parameter is ignored on the NT platforms:
http://msdn.microsoft.com/en-us/library/ms644974.aspx
http://www.klenotic.com/pl/null_hhook/

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

采纳答案by Charlie

According to the docs, the proper thing to do is pass the arguments you received directly to CallNextHookEx, exactly as you received them. You should also call CallNextHookEx regardless of whether you decided to handle the hook message.

根据文档,正确的做法是将您收到的参数直接传递给 CallNextHookEx,就像您收到的一样。无论您是否决定处理钩子消息,您还应该调用 CallNextHookEx。

According to MSDN, the first parameter to CallNextHookExis ignored on on NT/XP/2003, and for older Win95-based operating systems it should be the HHOOKyou received when you registered your hook with SetWindowsHookEx. The docs don't specify a value for Windows 2000, but since it's part of the NT family, a reasonable guess is that it's ignored there as well.

根据 MSDN,第一个参数 toCallNextHookEx在 NT/XP/2003 上被忽略,对于较旧的基于 Win95 的操作系统,它应该是HHOOK您在SetWindowsHookEx. 文档没有指定 Windows 2000 的值,但由于它是 NT 系列的一部分,合理的猜测是它在那里也被忽略了。

Given all that, a good way to code the method for NT-family operating systems might be this:

鉴于所有这些,为 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
}

This makes sure that you always call the hook at the end of your processing, and makes it hard to accidentally add a returnthat will bypass CallNextHookEx.

这确保您始终在处理结束时调用钩子,并且很难意外添加return将绕过CallNextHookEx.