CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    May 2002
    Posts
    1,798

    How can I terminate an MFC application programatically?

    I need to terminate an MFC application programmatically. My intention is to detect a 5 minute idle time, after which the user will be given a warning that the program is about to terminate unless he does something with it, then close the application, just as one would select File/Exit from the menu.

    I have tried a couple of preliminary methods as shown in the code below.
    Code:
    void CTimerEventView::TerminateApplication()
    {
    	CMainFrame * pMf = (CMainFrame*)AfxGetMainWnd();
    	//pMf->CloseWindow();
    	pMf->DestroyWindow();
    }
    Neither of these works satisfactorily. CloseWindow() simply reduces the window to the Task Bar. DestroyWindow terminates the program, but with a series of the usual messages
    TimerEvent MFC Application has encountered a problem and needs to close. We are sorry for the inconvenience. ... blah, blah, blah
    in addition to which there is a large memory leak. Not very pretty!

    Is there some orderly method of terminating an application programmatically (from within the application, not external to it)?

    FWIW, this code from Microsoft runs into the same problem as DestroyWindow() above:
    see http://support.microsoft.com/kb/117320
    Code:
    void ExitMFCApp()
       {
            // same as double-clicking on main window close box
            ASSERT(AfxGetMainWnd() != NULL);
            AfxGetMainWnd()->SendMessage(WM_CLOSE);
       }
    Last edited by Mike Pliam; September 16th, 2009 at 11:59 PM.
    mpliam

  2. #2
    Join Date
    Feb 2009
    Location
    India
    Posts
    444

    Re: How can I terminate an MFC application programatically?

    Try PostQuitMessage
    «_Superman
    I love work. It gives me something to do between weekends.

    Microsoft MVP (Visual C++)

  3. #3
    Join Date
    Mar 2008
    Location
    Turin / Italy
    Posts
    178

    Re: How can I terminate an MFC application programatically?

    How about sending a message as the user clicked the File->Exit?
    Like:

    PostMessage(WM_COMMAND,IDM_EXIT,0);

  4. #4
    Join Date
    Apr 1999
    Posts
    3,585

    Re: How can I terminate an MFC application programatically?

    As stated earilier, I would use PostQuitMessage (). However, I don't think that will clear up your other problems (ie. memory leak, etc.).
    Gort...Klaatu, Barada Nikto!

  5. #5
    Join Date
    May 2002
    Posts
    1,798

    Re: How can I terminate an MFC application programatically?

    Code:
    ::PostQuitMessage(1);
    closes the application with memory leaks

    Code:
    PostMessage(WM_COMMAND,ID_APP_EXIT,0);
    has no apparent effect whatsoever

    There must be an orderly way to shut down a pogram from the program itself, isnt there ?
    mpliam

  6. #6
    Join Date
    Apr 1999
    Posts
    3,585

    Re: How can I terminate an MFC application programatically?

    Are you allocating some objects and not cleaning up?
    Gort...Klaatu, Barada Nikto!

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: How can I terminate an MFC application programatically?

    Quote Originally Posted by Mike Pliam View Post
    Code:
    ::PostQuitMessage(1);
    closes the application with memory leaks
    What is leaking memory? If it's your own classes, data structures, etc. that shouldn't happen if you coded them correctly in terms of what happens when those objects go out of scope (i.e. destructors are called, RAII, etc.).

    Regards,

    Paul McKenzie

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How can I terminate an MFC application programatically?

    It's pretty simple.

    Add the following to the CWinApp derived class:

    myapp.h

    Code:
     
    public:
      afx_msg void OnAppExit();


    myapp.cpp

    Code:
    void CMyApp::OnAppExit()
    {
      CWinApp::OnAppExit( );
    }
    From anywhere in your app, to close the app call:

    Code:
     
    CMyApp* pApp = reinterpret_cast[SIZE=2]<CMyApp*>( AfxGetApp( ) );
    pApp->OnAppExit( );
    If you have memory leaks, it's because you aren't cleaning up the memory properly in your code.
    Last edited by Arjay; September 17th, 2009 at 05:00 PM.

  9. #9
    Join Date
    May 2002
    Posts
    1,798

    Re: How can I terminate an MFC application programatically?

    What is leaking memory?
    It appears that ,at least in part, a timer that has been started is the cause of this problem.

    The debugger from afxwin2.inl indicates:
    Code:
    _AFXWIN_INLINE UINT_PTR CWnd::SetTimer(UINT_PTR nIDEvent, UINT nElapse,
    		void (CALLBACK* lpfnTimer)(HWND, UINT, UINT_PTR, DWORD))
    	{ ASSERT(::IsWindow(m_hWnd)); return ::SetTimer(m_hWnd, nIDEvent, nElapse,
    		lpfnTimer); }
    This app is really a simple trial app to programatically terminate an MFC SDI application at a user set time. The code to stop the timer which is invoked just prior to requesting the application exit is:
    Code:
    void CTimerEventView::OnExit() 
    {
    	// TODO: Add your control notification handler code here
    	//if(StopTimer(Timeval)==FALSE)
    	//	::MessageBox(NULL,"Error While Killing the Timer","ShutEvt",1);
    
    	::PostQuitMessage(1);
    
    }
    Note that the part that's commented out always returns false and gives that Error While Killing the Timer message. So maybe that is the source of the memory leak problem. Otherwise, ::PostQuitMessage(1) does terminate the program without an APPCRASH, but with the leak.

    Arjay's approach results in an APPCRASH, but obviously doesnt at all attend to killing the timer, yet I'm uncertain why it crashes.

    I am afraid this timer thing is a whole new can of worms.
    mpliam

  10. #10
    Join Date
    Feb 2009
    Location
    India
    Posts
    444

    Re: How can I terminate an MFC application programatically?

    When the program terminates, it shows you what memory was leaked until then.
    Once the process terminates, the OS will cleanup all the used and unfreed memory.
    There will no longer be any leaks after the process is completely terminated.
    «_Superman
    I love work. It gives me something to do between weekends.

    Microsoft MVP (Visual C++)

  11. #11
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How can I terminate an MFC application programatically?

    Quote Originally Posted by Mike Pliam View Post
    Arjay's approach results in an APPCRASH, but obviously doesnt at all attend to killing the timer, yet I'm uncertain why it crashes.
    It works for a bare bones app. It's up to you to handle your cleanup in the individual classes appropriately. Put some TRACE statements in the destructor's to narrow down where the leak may be (maybe stop the timer in the appropriate destructor as well).

  12. #12
    Join Date
    May 2002
    Posts
    1,798

    Re: How can I terminate an MFC application programatically?

    When the program terminates, it shows you what memory was leaked until then.
    Once the process terminates, the OS will cleanup all the used and unfreed memory.
    There will no longer be any leaks after the process is completely terminated.
    This seems to be a very important point. I remember it coming up in this forum some years ago, and there was some disagreement about it. In any case, if one terminates the same program using the File/Exit, no such memory leak is seen to occur. So I remain somewhat concerned about the leak.

    EDIT:
    Getting back to the original problem, my apologies to Arjay whose method works quite nicely, provided I eliminate a syntactical error:
    Code:
    	CTestAppApp* pApp = reinterpret_cast<CTestAppApp*>( AfxGetApp( ) );
    	pApp->OnAppExit( );
    Using this from the View terminates the app in orderly fashion without memory leaks. Note that using ::PostQuitMessage(1); from the FormView View terminates the application but with the terminal memory leak. The APPCRASH that I was witnessing was because I had tried to use KillTimer on an event object that had already been killed.
    Last edited by Mike Pliam; September 18th, 2009 at 11:24 AM. Reason: more info
    mpliam

  13. #13
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: How can I terminate an MFC application programatically?

    Are you using the older MFC project classes or the newer ones?

    Is your main app class derived from CWinApp or CWinAppEx?

  14. #14
    Join Date
    May 2002
    Posts
    1,798

    Re: How can I terminate an MFC application programatically?

    CWinApp

    Yeah. I figured you must be using a newer version of the compiler. I suppose I'll have to upgrade one of these days.
    mpliam

  15. #15
    Join Date
    Oct 2005
    Location
    Minnesota, U.S.A.
    Posts
    680

    Re: How can I terminate an MFC application programatically?

    Two notes:

    1. DestroyWindow() is the solution, you just don't have your OnDestroy() handler implemented. In your OnDestroy() you need to: A) Stop all non-message queue timers, B) stop all accessory threads, C) Save all data.

    P.S. Put all this before calling the default OnDestroy handler, no matter what MFC says.

    2. When you exit an app with stuff still allocated, you will get memory leaks. If you are using a DLL, it will still say you have leaks, even if you don't.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured