开发者

ExitInstance not called in MFC app

Until now, I never really needed the Winapp ExitInstance() of a large MFC (Single Document Interface if it matters) app I'm working on. But now I do, mainly to cleanup memory alocations, unload some DLLs, etc. Well I soon learned by the obvious memory leaks and such that ExitInstance was not being called. Have I missed something obvious? Do I need to manually add something to the message map to make sure my ExitInstance override is called?

I guess i can do my cleanup elsewhere, but it's the best place if I can get it to run. Interestingly, I found quite a few instances of this by typing strings like "ExitInstance never called" and such into Google, and in no case were any real answers offered. The app normall开发者_JAVA技巧y closes when someone clicks the close box or the "Exit" from the File menu, and the OnClose() of the mainframe window certainly does always get called. I even tried forcing things by putting AfxGetMainWnd()->DestroyWindow(); in that mainframe OnClose() event, but still I can't get the ExitInstance() to actually run. Maybe it's just a big dummy function? Or maybe I'M just a big dummy? :-)


I had a similar problem to you...mine was caused by mixing Unicode and MBCS built code....maybe that was your underlying cause?

I had to convert an MBCS application to Unicode, but it was impossible to convert the whole project, so I had to mix Unicode compiled (the application) and MBCS compiled code (the DLLs).

Some of the MBCS DLLs were MFC extension DLLs, others were regular DLLs.

One of the MFC extension DLLs contained resources (bitmap image list, and common dialogs).

I didn't convert the DLL to UNICODE because it had a lot of dependent DLLs which would also have had to be converted, and in addition I didn't need the controls in the common dialogs to support Unicode text.

So I kept the DLL as MBCS, and used AfxSetResourceHandle prior to using any class in the MBCS DLL that used resources.....this was to make the resources get pulled from the DLL directly, instead of through the MFC resource chain, because MFC couldn't find the non-unicode resources otherwise.

I guess MFC doesn't like it when you have a mix of Unicode and non-unicode compiled code containing resources.....lookups in the resource chain fail (I guess has something to do with the conversion of resource IDs to an ID string i.e. via MAKEINTRESOURCE).

I made the main application UNICODE, and made sure the C++ headers of classes in the MBCS DLLs used CStringA in the function prototypes, or accepted wide strings and did the conversion internally.

What I found was my application wouldn't exit properly...it would stay in the MFC CWinThread::PumpMessage/AfxInternalPumpMessage() call, and ExitInstance would never be called.

To solve it, in my CMainFrame::OnDestroy() I put the following as the last 2 statements:

void CMainFrame::OnDestroy() 
{
    ....

    CFrameWnd::OnDestroy();

    AfxPostQuitMessage(0);
}


I had the same problem. Turns out it was caused by some messages being pretranslated by the CWinApp object after the mainframe was destroyed. It would hit some validty check during that processing and just bail out instead of exiting through the normal exitinstance.

Overriding the apps PreTranslate message and returning immediately when there was no main frame resolved the issue.

BOOL CYourAppClass::PreTranslateMessage( MSG* pMsg )
{
    // If the main window has gone away there is no need to do pre-translation.
    // If the pre-translation were allowed to proceed the
    //  CWinAppEx::PreTranslateMessage may bail out without calling
    /// the app's ExitInstance nor destructing the app object.
    if ( !m_pMainWnd )
        return FALSE;

return CWinAppEx::PreTranslateMessage( pMsg );
}


You say that "the OnClose() of the mainframe window certainly does always get called". I had a problem with one of my MFC apps; I had put some thread-cleanup code into my window's OnClose() event handler, and it wasn't getting called. After some pain, I put the thread-cleanup code into an OnDestroy() event-handler, and now it always gets called. So you may want to check whether or not your OnClose() event-handler always gets called.


I had exactly the same problem.

In my case, the issue was solved by overriding PostNcDestroy in CMainFrame. It seems that treating this last message in the main frame window makes it all work:

virtual void PostNcDestroy();

void CMainFrame::PostNcDestroy()
{
}


Another possibility is that there is an assertion failure happening in the middle of the shut down process. For example while destroying a window. I found that when this happens, ExitInstance also gets skipped.

So, just before closing your application, clear the output/debug log window and see if such a message is printed. If that's the case, solve the problem and see if ExitInstance gets called again.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜