Thread: Intercept Close Message?

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    7

    Intercept Close Message?

    Hi, just found these forums, hopefully the start of a long, loving relationship.

    Anyway, in a c++ program I've written I start up an external application using CreateProcess, anyway that all works fine, now what I want to do is have control over whether the program closes. I want to intercept the close message, so that I can choose what to do then.

    So can anybody tell me how I might do this?

    Cheers
    Last edited by OneMan; 07-21-2004 at 06:21 PM.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Welcome to the forums!

    If you just need to know when the remote process terminates, you can use:
    Code:
    WaitForSingleObject(hProcess, INFINITE);
    If you really need to know when the remote process receives WM_CLOSE you can use a hook:
    Code:
    SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC) CallWndProc, hDll, dwThreadID);
    If you really need to control what happens when the remote process receives WM_CLOSE, I think you will have to do a remote subclass. See this sample.

  3. #3
    Registered User
    Join Date
    Jul 2004
    Posts
    7
    Hmmm, seems the way to go is using HHOOK, anybody familiar with this?
    woops, didn't see the above post

    Basically what I want to do is instead of closing the program I want to hide it. I'd like to do so without adding a dll if at all possible.
    Last edited by OneMan; 07-21-2004 at 09:51 PM.

  4. #4
    Registered User Draco's Avatar
    Join Date
    Apr 2002
    Posts
    463
    What do you more specifically mean by hiding? Do you want to make your program a background program?

  5. #5
    Registered User
    Join Date
    Jul 2004
    Posts
    7
    My app is called SunTray find here
    Basically it allows Mozilla Sunbird, a calendar program, to be minimized to the System Tray. If Sunbird is minimized I hide it, and users use the system tray icon to restore it. Its working quite well.

    So anyway, what I want to do is add another option, which will instead of closing Sunbird, minimize it to the system tray. So I want to intercept the close message, send a hide window message to sunbird, and change my icon.

    So my problem is how to intercept the message.

    Thanks

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    I think you will need to use some form of remote subclassing.

    You can use a DLL as in the sample I posted above or use a hook to inject the code. You can do it without a DLL by copying the code accross but it is far more complex.

    This article has an overview of different remote subclass methods, including a no-dll sample:
    http://www.codeproject.com/threads/winspy.asp

    Another no-dll sample:
    http://win32.mvps.org/processes/remthread.html

    In this thread Benny shows how to subclass an already running program:
    http://cboard.cprogramming.com/showthread.php?t=46065

    Reading material:
    http://cboard.cprogramming.com/searc...searchid=46096

  7. #7
    Registered User
    Join Date
    Jul 2004
    Posts
    7
    Ok, I've found this example http://www.codeproject.com/useritems...ndowToTray.asp

    And I've modified this part, it intercepts all command messages so I can process my own.
    Code:
    LRESULT CALLBACK MenuCommandHookProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    	// return immediately if system required
        if (nCode < 0){
            return CallNextHookEx(g_hMenuCommandHook, nCode, wParam, lParam); 
    	}
    	// process the arrival message
    	MSG *msg = (MSG*)lParam;
    	switch (msg->message) {
    		case WM_SYSCOMMAND:
    			//Steve's Editing.
    			if(LOWORD(msg->wParam) == SC_CLOSE){
    				if(FindWindow("MozillaUIWindowClass","Mozilla Sunbird")==(HWND)msg->hwnd)
    				{
    					//Change message to minimize instead of close
    					msg->wParam=SC_MINIMIZE;
    				}
    			}
    			break;
    	}
    	
    	// call next hook
        return CallNextHookEx(g_hMenuCommandHook, nCode, wParam, lParam); 
    }
    And this works for when close is selected in the system menu, well for now its just changed to minimize, but that works. But I'm not sure what the message is for clicking on the close symbol.
    For the system menu its, WM_SYSCOMMAND, with wParam=SC_CLOSE

    Can anybody tell me?

  8. #8
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Quote Originally Posted by WM_SYSCOMMAND documentation
    In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are used internally by the system. To obtain the correct result when testing the value of wParam, an application must combine the value 0xFFF0 with the wParam value by using the bitwise AND operator.
    So:
    Code:
    if(LOWORD(msg->wParam) == SC_CLOSE)
    should be:
    Code:
    if((msg->wParam & 0xFFF0) == SC_CLOSE)
    I don't know if that will make it work.

  9. #9
    Registered User
    Join Date
    Jul 2004
    Posts
    7
    I'm not sure you understood what I said in my last post. That part works, I have successfully intercepted the call to close when it is done via the system menu. It worked with both versions of that particular line as well.

    What I don't know is what message is passed when a user clicks the close icon visible on the window. I've tried a few things with no success.

    Thanks for the help so far, much appreciated.

  10. #10
    Registered User
    Join Date
    Jul 2004
    Posts
    7
    Oh I don't know, I got this off msdn, about WM_SYSCOMMAND

    A window receives this message when the user chooses a command from the Window menu (formerly known as the system or control menu) or when the user chooses the maximize button, minimize button, restore button, or close button.
    So I don't know why it didn't work. The minimize/maximize/close buttons don't appear to be sending a SYSCOMMAND.
    Last edited by OneMan; 07-24-2004 at 01:28 AM.

  11. #11
    Registered User
    Join Date
    Jul 2004
    Posts
    7
    So nobody has any idea why the minimize/maximize/close buttons aren't sending the message like they are documented to??

    Also I was wondering if CreateProcess is a slow option? I'm having people using my program say that it takes minutes to start the program. For most people it starts quickly.
    I've used pretty much the standard way of using createprocess as they do it in the msdn docs, but I've added the option for the program to start minimized. Is there a method or any particular reason this might be slow on some machines?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 03-10-2008, 11:57 AM
  2. Just starting Windows Programming, School me!
    By Shamino in forum Windows Programming
    Replies: 17
    Last Post: 02-22-2008, 08:14 AM
  3. Problem with Printing message
    By robert_sun in forum C Programming
    Replies: 2
    Last Post: 05-16-2004, 02:09 PM
  4. arithmetic coding - end of message symbol
    By dnc_01 in forum C Programming
    Replies: 2
    Last Post: 04-11-2004, 04:20 AM
  5. Sending CChildView a Message :: MFC
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 04-06-2002, 03:00 PM