views:

4815

answers:

2

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.".

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.

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/

+5  A: 

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.

According to MSDN, the first parameter to CallNextHookEx is ignored on on NT/XP/2003, and for older Win95-based operating systems it should be the HHOOK you 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.

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

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 return that will bypass CallNextHookEx.

Charlie
That doesn't work because CallNextHookEx takes a HHOOK parameter (returned from SetWindowsHookEx).
Mark Ingram
Oops sorry, I'll update my answer.
Charlie
Hmm, you could be onto something there. I missed the bit about the "hhk" parameter being ignored on NT/XP/2003. Going to give it a little test now.
Mark Ingram
A: 

See the dozens of MS samples in MSDN and Win SDK for all the hooks.