WH_GETMESSAGE hook doesn't reveive SC_CLOSE on shutdown button only on menu.

Hi!
I'm trying to hook an application to prevent it from shutting down when the user presses the close button on the form. Instead i want to run my own code wich just closes that specific window and not the whole application.
The application loads the dll and i add a hook with .

      hMsgHook = SetWindowsHookEx(
        WH_GETMESSAGE,
        (HOOKPROC)MessageProc,
        (HINSTANCE)ThisDllHandle,
        GetCurrentThreadId());

And the hook proc looks like

LRESULT CALLBACK MessageProc(int code, WPARAM wParam, LPARAM lParam)
{
      MSG *msg = (MSG*)lParam;
      //if this is a command message we should look into it.
      if (msg->message == WM_COMMAND)
      {
            //Code to process commands that works well.

      }
      if (msg->message == WM_SYSCOMMAND || msg->message == WM_CLOSE)
      {
            if (msg->wParam == SC_CLOSE)
            {
                  int i = 1; //Breakpoint here;
            }
      }
}

When i use the right klick menu or window menu to close the form the HookProc get's called but when i press the x it doesn't.
I've tried a lot of different hook types and have found that WH_CALLWNDPROC get's the x but not the menus. The problem with WH_CALLWNDPROC is that modifying the message to WM_NULL as suggested in another thread doesn't stop the application from shutting down. The docuementation also describes that you cannot modify the message in a callback of this type.

I'm running on xp and is using VS2003 to make this.

I think the forms i'm trying to prevent from closing is a child form, could this have anything to do with it. I've tried WH_MSGFILTER without success.

If anyone can tell me how to provide more info i'll do so.
I'm stuck and don't know what to do next.

Fredrik Högberg
   
fhogbergAsked:
Who is Participating?
 
nonubikCommented:
When you set the hook, one of the last 2 params *must* be 0.
I.e. you want a system-wide hook, you call:

     SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MessageProc, (HINSTANCE)ThisDllHandle,  0);

and if you want a hook on a thread created by the current process, you call:

    SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MessageProc, NULL,  GetCurrentThreadId());

0
 
fhogbergAuthor Commented:
When looking at the messages in spy++ using the button causes two entries "Sent" and "Return" using the button makes a single entry "Posted". Don't know the difference.

Tried subclassing and this seams to work better as i receive all messages with that.

Still don't understand what was wrong with the hook though.

Fredrik Högberg
0
 
a_dubeCommented:
From your hook proc:

if (msg->message == WM_SYSCOMMAND || msg->message == WM_CLOSE)
     {
          if (msg->wParam == SC_CLOSE)
          {
               int i = 1; //Breakpoint here;
          }
     }

If msg->message == WM_CLOSE, msg->wParam would be != SC_CLOSE and you'll never stop at your breakpoint.
0
 
fhogbergAuthor Commented:
Still doesn't solved but I managed to get it working with subclassing.
Since I don't have time to test your solutions you get a 50/50 split in points.
Hope you think this is fair.

Thank you for helping.


Fredrik Högberg
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.