问题:
一个MFC –SDI程序在关闭的时候自动提示”是否保存对XXX的更改”,而本身不希望出现这样的提示。同时发现,在打开一个文档后,再打开一个文档,同样会出现这样的提示。
解决过程:
1、 在void CMainFrame::OnClose()中插入断点,发现提示对话框是通过CFrameWndEx::OnClose()产生的。
2、 追踪CFrameWndEx::OnClose()函数的实现,发现该函数的实现是在afxframewndex.cpp文件中。将该文件通过vs打开,进行跟踪,发现提示是在CFrameWnd::OnClose()函数中产生的。
3、 继续追踪,发现是在winfrm.cpp中实现的。该函数为:
/ // CFrameWnd closing down void CFrameWnd::OnClose() { if (m_lpfnCloseProc != NULL) { // if there is a close proc, then defer to it, and return // after calling it so the frame itself does not close. (*m_lpfnCloseProc)(this); return; } // Note: only queries the active document CDocument*pDocument = GetActiveDocument(); if (pDocument != NULL &&!pDocument->CanCloseFrame(this)) { // document can't close right now -- don't close it return; } CWinApp*pApp = AfxGetApp(); if (pApp != NULL && pApp->m_pMainWnd == this) { CDataRecoveryHandler*pHandler = pApp->GetDataRecoveryHandler(); if ((pHandler != NULL) &&(pHandler->GetShutdownByRestartManager())) { // If the application is being shut down by the RestartManager, do // a final autosave. This will mark all the documents as not dirty, // so the SaveAllModified call below won't prompt for save. pHandler->AutosaveAllDocumentInfo(); pHandler->SaveOpenDocumentList(); } // attempt to save all documents if (pDocument == NULL && !pApp->SaveAllModified()) return; // don't close it if ((pHandler != NULL) &&(!pHandler->GetShutdownByRestartManager())) { // If the application is not being shut down by the RestartManager, // delete any autosaved documents since everything is now fullysaved. pHandler->DeleteAllAutosavedFiles(); } // hide the application's windows before closing all thedocuments pApp->HideApplication(); // close all documents first pApp->CloseAllDocuments(FALSE); // don't exit if there are outstanding component objects if (!AfxOleCanExitApp()) { // take user out of control of the app AfxOleSetUserCtrl(FALSE); // don't destroy the main window and close down just yet // (there areoutstanding component (OLE) objects) return; } // there are cases where destroying the documents maydestroy the // main window ofthe application. if (!afxContextIsDLL && pApp->m_pMainWnd== NULL) { AfxPostQuitMessage(0); return; } } // detect the case that this is the last frame on thedocument and // shut down with OnCloseDocument instead. if (pDocument != NULL &&pDocument->m_bAutoDelete) { BOOLbOtherFrame = FALSE; POSITIONpos = pDocument->GetFirstViewPosition(); while (pos != NULL) { CView*pView = pDocument->GetNextView(pos); ENSURE_VALID(pView); if (pView->GetParentFrame() != this) { bOtherFrame= TRUE; break; } } if (!bOtherFrame) { pDocument->OnCloseDocument(); return; } // allow the document to cleanup before the window isdestroyed pDocument->PreCloseFrame(this); } // then destroy the window DestroyWindow(); }
发现该函数中的pDocument->CanCloseFrame(this)产生了是否保存的提示。
4、 于是在Doc类中重写虚函数BOOL CDoc::CanCloseFrame(CFrameWnd* pFrame)为:
BOOL COCRCharXDoc::CanCloseFrame(CFrameWnd* pFrame) { return true; //return CRichEditDoc::CanCloseFrame(pFrame); }
再次编译,发现关闭SDI时不再有保存的提示。
5.针对非第一次打开的文档提示保存的问题,原因在于文件的修改被自动地记录了。只要将自动记录的变量置为无效即可。可在CView类OnDraw()函数中添加以下代码:
COCRCharXDoc* pDoc = GetDocument(); pDoc->SetModifiedFlag(0);
至此问题解决。