版本:Visual Studio 6.0 + Service Pack 5 下的MFC6
文档类:CRichEditDoc的派生类
视图类:包括CRichEditView派生类及非CRichEditView派生类在内的多个视图
问题:程序在关闭文档时出错。
分析:
在CDocument里void CDocument::OnCloseDocument(){ while (!m_viewList.IsEmpty()) { // get frame attached to the view CView* pView = (CView*)m_viewList.GetHead(); ASSERT_VALID(pView); CFrameWnd* pFrame = pView->GetParentFrame(); ASSERT_VALID(pFrame); // and close it PreCloseFrame(pFrame); pFrame->DestroyWindow(); // will destroy the view as well } ......}在CRichEditDoc里CRichEditView* CRichEditDoc::GetView() const{ POSITION pos = GetFirstViewPosition(); if (pos == NULL) return NULL; // find the first view that is a CRichEditView CView* pView; while (pos != NULL) { pView = GetNextView(pos); if (pView->IsKindOf(RUNTIME_CLASS(CRichEditView))) return (CRichEditView*) pView; } // can't find one--return NULL return NULL;}void CRichEditDoc::PreCloseFrame(CFrameWnd* pFrameArg){ ...... // deactivate any inplace active items on this frame GetView()->m_lpRichEditOle->InPlaceDeactivate(); ................................................................1 ......}
可以发现,CDocument::OnCloseDocument在关闭每一个视图的时候总会调用PreCloseFrame来处理一些善后的工作,而CRichEditDoc::PreCloseFrame总调用CRichEditDoc::GetView() 来获得这些视图类的指针,但是CRichEditDoc::GetView() 只返回类型为CRichEditView派生类的视图对象的指针,这就造成CRichEditDoc::GetView() 在遇到非CRichEditView派生类的视图对象时候只是返回一个NULL,于是在1处程序出错,所以在这种情况下我们必须在CDocument::OnCloseDocument被调用之前手动关闭掉所有与CRichEditDoc相关联的非CRichEditView的派生类的视图。
我不知到这是不是微软特意这样做,总之在往CRichEditDoc里添加View后,关闭的时候都要先手动关闭其他不是CRichEditView派生出来的View,不知各位有什么见解^_^