第一次深入MFC 调试一个小小的错误
作者:CrazyAzreal 来源:ccw 添加时间:2006-5-26 10:34:07 以前常认为自己mfc学得不错,因为有CSDN+MSDN+GOOGLE,可是今天收到一个网友(女的哦!)的消息,说他有个程序有点问题,她把程序发到我的邮箱里去了,我down了下来.研究了一吓,这个程序给我补了一些基础知识,并认识到其实自己还很菜.然后就写了这篇文章了.
那个程序(网友给我发的那个程序)是一个SDI程序,错误是在点击文件(自动生成的那个)->保存(打开\另存为)时会出错,是一个断言的错误提示形式,这时我就去看了看她的CXXXDoc里,OnSaveDocument()是怎样写的,去看了看,发现并没有重载这个函数,这时就郁闷啦?那到底错在哪里呢?我马上想到不如debug一吓吧,在debug下,我再点文件->保存,可是并没有断下来?它直接就弹出个错误框.不知道是为什么,苦思了一会,在没办法的情况下,又试了一吓,,看能不能断下来,可是还是断不下来,又在没办法+失望的情况下,我点了重试(ASSERT的提示框不是有三个按钮的吗,分别是终止\重试\忽略),这下就可以断下来了?哈,我看看是断到哪里,噢,断到了CDocument::DoSave(...)里去了,我看了看,这个函数被CDocument::DoFileSave()所调用,看看CDocument::DoFileSave()的实现:
BOOL CDocument::DoFileSave() { DWORD dwAttrib = GetFileAttributes(m_strPathName); if (dwAttrib & FILE_ATTRIBUTE_READONLY) { // we do not have read-write access or the file does not (now) exist if (!DoSave(NULL)) { TRACE0("Warning: File save with new name failed.\n"); return FALSE; } } else { if (!DoSave(m_strPathName)) { TRACE0("Warning: File save failed.\n"); return FALSE; } } return TRUE; } |
明显,第一个if是另存为时调用的,下面的则为保存时的.
然后我又看了看CDocument::DoSave(LPCTSTR lpszPathName, BOOL bReplace)
BOOL CDocument::DoSave(LPCTSTR lpszPathName, BOOL bReplace) // Save the document data to a file // lpszPathName = path name where to save document file // if lpszPathName is NULL then the user will be prompted (SaveAs) // note: lpszPathName can be different than 'm_strPathName' // if 'bReplace' is TRUE will change file name if successful (SaveAs) // if 'bReplace' is FALSE will not change path name (SaveCopyAs) { CString newName = lpszPathName; if (newName.IsEmpty()) { CDocTemplate* pTemplate = GetDocTemplate(); ASSERT(pTemplate != NULL); newName = m_strPathName; if (bReplace && newName.IsEmpty()) { newName = m_strTitle; // check for dubious filename int iBad = newName.FindOneOf(_T(" #%;/\\")); if (iBad != -1) newName.ReleaseBuffer(iBad); // append the default suffix if there is one CString strExt; if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) && !strExt.IsEmpty()) { ASSERT(strExt[0] == '.'); newName += strExt; } } if (!AfxGetApp()->DoPromptFileName(newName, bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, pTemplate)) return FALSE; // don't even attempt to save } CWaitCursor wait; if (!OnSaveDocument(newName)) { if (lpszPathName == NULL) { // be sure to delete the file TRY { CFile::Remove(newName); } CATCH_ALL(e) { TRACE0("Warning: failed to delete file after failed SaveAs.\n"); DELETE_EXCEPTION(e); } END_CATCH_ALL } return FALSE; } // reset the title and change the document name if (bReplace) SetPathName(newName); return TRUE; // success } |