- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
根据这个 stackoverflow 问题:
What is the correct way to programmatically quit an MFC application?
我正在使用 AfxGetMainWnd()->PostMessage(WM_CLOSE,0,0);
退出 MFC 程序。 (SDI,CFrameWnd 包含一个带有两个 CFormView 的 CSplitterWnd)
正如预期的那样,这会调用 DestroyWindow()
。
我面临的问题是,在派生的 CFormView 销毁之后,根据 MSDN:
After calling DestroyWindow on a non-auto-cleanup object, the C++ object will still be around, but m_hWnd will be NULL. [MSDN]
现在 CView
析构函数被调用,此时它执行
CDocument::RemoveView()...
CDocument::UpdateFrameCounts()
它在以下断言上失败:ASSERT(::IsWindow(pView->m_hWnd));
我检查过,m_hWnd
已经在之前调用的派生 CView 析构函数中设置为 NULL。
我做错了什么?
编辑:
这是一张图表,说明了为什么我要发送 WM_CLOSE 消息而不是 WM_QUIT。
我认为答案就在这个 MSDN Technical Note 中, 但我想不通。
编辑 2:
事物被调用的顺序:
1- AfxGetMainWnd()->PostMessage(WM_CLOSE,0,0);
2- 派生 CFrameWnd::OnClose()
3- CFrameWnd::OnClose()
调用 CWinApp::CloseAllDocuments(BOOL bEndSession);
调用 CDocManager::CloseAllDocuments(BOOL bEndSession)
调用 CDocTemplate::CloseAllDocuments(BOOL)
调用 CDocument::OnCloseDocument()
现在,在这个函数中
while (!m_viewList.IsEmpty())
{
// get frame attached to the view
CView* pView = (CView*)m_viewList.GetHead();
ASSERT_VALID(pView);
CFrameWnd* pFrame = pView->EnsureParentFrame();
// and close it
PreCloseFrame(pFrame);
pFrame->DestroyWindow();
// will destroy the view as well
}
所以我们看到 CWnd::DestroyWindow()
被调用了,所以:
4- 派生的 CFormView 析构函数
5- CScrollView::~CScrollView()
6- CView::~CView()
调用 CDocument::RemoveView(CView* pView)
调用 CDocument::OnChangedViewList()
调用 CDocument::UpdateFrameCounts()
这里崩溃了:ASSERT(::IsWindow(pView->m_hWnd));
因为 pView->m_hWnd
是 NULL
...
编辑 3:
我想通了问题是什么:
第一个 View 的析构函数正在删除一个未初始化的指针,即 UB。这会使析构函数挂起并且永远不会完成。
通常,第二个 View 的析构函数仅在第一个 View 完成时调用。但在这种情况下,尽管第一个从未完成,但它仍在执行。
由于从未调用过第一个 View 基类析构函数,因此从未为第一个 View 调用过此函数:
void CDocument::RemoveView(CView* pView)
{
ASSERT_VALID(pView);
ASSERT(pView->m_pDocument == this); // must be attached to us
m_viewList.RemoveAt(m_viewList.Find(pView));
pView->m_pDocument = NULL;
OnChangedViewList(); // must be the last thing done to the document
}
我们可以看到该 View 已从 m_viewList
中删除。
这意味着当第二个 View 析构函数完成时,在:
void CDocument::UpdateFrameCounts()
// assumes 1 doc per frame
{
// walk all frames of views (mark and sweep approach)
POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
...
pos 应该是 NULL
,但实际上不是。导致崩溃。
最佳答案
我认为您关闭框架的方式不是问题所在。我的猜测是您手动销毁了其中一个 View ,而您应该让 MFC 删除它们(您可能对其中一个 View 调用了 DestroyWindow)
关于c++ - MFC CView(CFormView)破坏崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32661010/
所以我有一个基于 MFC 的应用程序,它主要派生自 CDialog,带有一些控件等。 由于某些原因,它需要托管在另一个应用程序中,使用基于CView 的容器类。 所以必须有某种方式...在容器类中使用
我在 MDI 应用程序中打开了一个 MFC CDocument 和关联的 CView。我想分离并关闭 View (和关联的框架),同时保持文档打开。查看 MFC 代码以了解它是如何做到的,在 CDoc
我有一个 CFormView 和一个子 CListCtrl 控件。我能应付加速器事件,如 Ctrl+C、Ctrl+V ... 在 CFormView 中没有问题,通过定义以下消息处理程序: O
通过我的 MFC 应用程序,我能够使用 CView 类在屏幕上打印我的 CDocument。基本上,我使用 CDC 类在屏幕上编写文本和绘制多边形以提供我的文档的 View 表示。 现在假设我想在 M
我有一个派生自调用 OnFilePrint() 的 CView 的类,但无论我在打印对话框中输入多少拷贝,似乎都只会打印一份拷贝。这是一个已知错误,还是我做错了什么? 我可能会创建自己的 CPrint
我有一个 CView,我一直在上面画东西,效果很好。然后我意识到我需要向我的 CView 添加一些控件,如文本框和组合框。所以我试图将我的 CView 转换为没有默认构造函数的 CFormView。但
我需要将 CView 派生类放入 CDockablePane 中。某处有任何代码示例,或者有人可以提供这样的代码吗? 我尝试过的: 显然应该很简单,我在网上找到了诸如“只需创建 View 并将其父项设
根据这个 stackoverflow 问题: What is the correct way to programmatically quit an MFC application? 我正在使用 Af
我正在开发一个 View 继承 CFormView 的 SDI 项目。我正在尝试覆盖 CView::OnUpdate ,但编译器会这样提示: 'CMyFormView::OnUpdate' : 'vi
OnUpdate 的第三个参数是指向CObject 的指针。该指针必须在实现其自己的 OnUpdate 的 View 类中向下转型。检查转换是否成功的最佳方法是什么?使用 CObject::IsKin
所以我想采用我正在处理的当前程序并使所有内部窗口都可以停靠。唯一的问题是它们扩展了一个名为 CFBView 的类,该类扩展了 CView。如果我也扩展 CDockablePane,它将导致无法正确编译
当使用 VS2008(加上功能包)的 AppWizard 创建具有“Visual Studio”风格的 MDI 应用程序时,CMainFrame 类获得一个方法 CreateDockingWindow
我在 mfc 中有一个 cdialog,我想将它托管在 cview 中,因此当您单击另一个 cview 时,它会出现在顶部,这与普通对话框不同。 我尝试将 cview 设置为对话框的父级,但对话框没有
我的 c++ MFC MDI 应用程序在其 View 中显示工程图。将 CView 派生对象转储到 PDF 文件的好方法是什么?您可以建议哪些图书馆(不是免费的)? 我研究了一些图书馆,比如 Cair
我有一个使用 C++、MFC 和 C++6.0 的大型图形程序。 我需要它在不提示用户输入打印机设置和文件名的情况下打印到 PDF。 我用 CView::OnPrint()使用 Microsoft P
我使用 Visual Studio 2015,使用 MFC 多文档应用程序(功能区样式)。我正在尝试将 png 图像添加到 CView 并使用 WM_TIMER 制作幻灯片。首先,我出于相同的目的制作
我有一个相当简单的 MFC 应用程序,它只定义了自己的 CDocument、CView 和 CFrameWnd 子类,并通过CSingleDocTemplate 在 View 的树中显示文档的只读内容
我是一名优秀的程序员,十分优秀!