到目前为止,我从来没有真正需要大型MFC的Winapp ExitInstance()(如果重要的话是单文档界面)我正在努力的应用程序。但现在我这样做,主要是为了清理内存分配,卸载一些DLL等等。好吧,我很快就通过明显的内存泄漏来学习,并且没有调用ExitInstance。我错过了明显的东西吗?我是否需要手动向消息映射添加内容以确保调用我的ExitInstance覆盖?
我想我可以在其他地方进行清理工作,但如果能让它运行起来,这是最好的地方。有趣的是,通过键入“ExitInstance never never”这样的字符串,我发现了很多这样的例子,并且在Google中没有提供任何真正的答案。当有人点击文件菜单中的关闭框或“退出”时,应用程序通常会关闭,并且主机窗口的OnClose()肯定会被调用。我甚至尝试通过放置AfxGetMainWnd() - > DestroyWindow();在那个大型机OnClose()事件中,但我仍然无法让ExitInstance()实际运行。也许它只是一个很大的虚拟功能?或者我是只是一个大假人? : - )
答案 0 :(得分:1)
我遇到了类似的问题...我的问题是混合使用Unicode和MBCS构建的代码....这可能是你的根本原因?
我不得不将MBCS应用程序转换为Unicode,但是无法转换整个项目,所以我不得不混合Unicode编译(应用程序)和MBCS编译代码(DLL)。
某些MBCS DLL是MFC扩展DLL,其他是常规DLL。
其中一个MFC扩展DLL包含资源(位图图像列表和常用对话框)。
我没有将DLL转换为UNICODE,因为它有许多依赖的DLL也必须转换,此外我不需要常见对话框中的控件来支持Unicode文本。
所以我将DLL保留为MBCS,并在使用资源的MBCS DLL中的任何类之前使用AfxSetResourceHandle .....这是为了使资源直接从DLL中提取,而不是通过MFC资源链,因为MFC无法找到非unicode资源。
我猜MFC不喜欢它,当你混合使用包含资源的Unicode和非unicode编译代码时......资源链中的查找失败(我猜想与资源ID的转换有关)到ID字符串,即通过MAKEINTRESOURCE)。
我创建了主应用程序UNICODE,并确保MBCS DLL中的类的C ++头在函数原型中使用CStringA,或者接受宽字符串并在内部进行转换。
我发现我的应用程序无法正常退出...它将保留在MFC CWinThread :: PumpMessage / AfxInternalPumpMessage()调用中,并且永远不会调用ExitInstance。
要解决它,在我的CMainFrame :: OnDestroy()中,我将以下内容作为最后两个语句:
void CMainFrame::OnDestroy()
{
....
CFrameWnd::OnDestroy();
AfxPostQuitMessage(0);
}
答案 1 :(得分:1)
我遇到了同样的问题。事实证明,这是由于一些消息在大型机被销毁后被CWinApp对象预翻译引起的。它会在处理过程中遇到一些有效的检查,只是挽救而不是通过正常的退出实例退出。
覆盖应用PreTranslate消息并在没有主框架时立即返回解决问题。
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 );
}
答案 2 :(得分:0)
你说“大型机窗口的OnClose()肯定会被称为”。我的一个MFC应用程序出了问题;我已经将一些线程清理代码放入我的窗口的OnClose()事件处理程序中,并且没有被调用。经过一些痛苦之后,我将线程清理代码放入OnDestroy()事件处理程序中,现在它总是被调用。因此,您可能需要检查是否始终调用OnClose()事件处理程序。
答案 3 :(得分:0)
我有完全相同的问题。
就我而言,通过覆盖PostNcDestroy
中的CMainFrame
来解决问题。似乎在主框架窗口中处理这最后一条消息使它全部工作:
virtual void PostNcDestroy();
void CMainFrame::PostNcDestroy()
{
}
答案 4 :(得分:0)
另一种可能性是在关闭过程中发生断言失败。例如,在销毁窗口时。
我发现当发生这种情况时,ExitInstance
也会被跳过。
因此,在关闭应用程序之前,请清除输出/调试日志窗口并查看是否打印了此类消息。
如果是这种情况,请解决问题并查看是否再次调用ExitInstance
。