-
September 16th, 2009, 11:53 PM
#1
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
-
September 17th, 2009, 01:29 AM
#2
Re: How can I terminate an MFC application programatically?
-
September 17th, 2009, 06:42 AM
#3
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);
-
September 17th, 2009, 07:34 AM
#4
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!
-
September 17th, 2009, 03:33 PM
#5
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
-
September 17th, 2009, 03:39 PM
#6
Re: How can I terminate an MFC application programatically?
Are you allocating some objects and not cleaning up?
Gort...Klaatu, Barada Nikto!
-
September 17th, 2009, 03:41 PM
#7
Re: How can I terminate an MFC application programatically?
Originally Posted by Mike Pliam
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
-
September 17th, 2009, 04:57 PM
#8
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.
-
September 17th, 2009, 09:44 PM
#9
Re: How can I terminate an MFC application programatically?
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
-
September 17th, 2009, 10:12 PM
#10
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.
-
September 18th, 2009, 12:09 AM
#11
Re: How can I terminate an MFC application programatically?
Originally Posted by Mike Pliam
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).
-
September 18th, 2009, 10:44 AM
#12
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
-
September 18th, 2009, 11:40 AM
#13
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?
-
September 18th, 2009, 11:52 AM
#14
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
-
September 18th, 2009, 11:56 AM
#15
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|