// we do not have read-write access or the file does not (now) exist
if (!dosave(null))
{
trace(traceappmsg, 0, "warning: file save with new name failed.\n");
return false;
}
}
else
{
if (!dosave(m_strpathname))
{
trace(traceappmsg, 0, "warning: file save failed.\n");
return false;
}
}
return true;
}
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())
{
...//
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)
{
trace(traceappmsg, 0, "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
}
cdocument::dosave函数继续调用onsavedocument(...)函数来完成写入任务。
bool cdocument::onsavedocument(lpctstr lpszpathname)
{
cfileexception fe;
cfile* pfile = null;
pfile = getfile(lpszpathname, cfile::modecreate |
cfile::modereadwrite | cfile::shareexclusive, &fe);
...//
carchive savearchive(pfile, carchive::store | carchive::bnoflushondelete);
savearchive.m_pdocument = this;
savearchive.m_bforceflat = false;
try
{
cwaitcursor wait;
serialize(savearchive); // save me
savearchive.close();
releasefile(pfile, false);
}
...//
setmodifiedflag(false); // back to unmodified
return true; // success
}
该函数创建了一个与要保存的文件相关联的carchive实例savearchive,并调用了函数 cmydoc::serialize(carchive&ar);
void cmydoc::serialize(carchive& ar)
{
if (ar.isstoring())
{
// todo:在此添加存储代码/写入
}
else
{
// todo:在此添加加载代码/读出
}
}
看看该函数,你有些傻眼了,空函数几乎什么也没有,这又对了,因为mfc不知道你的数据是什么样式的,所以它没有这个能力越俎代庖。如果你没有为该函数添加代码,则该函数也就到此为止了,但我们要把其奥秘挖掘出来就不能到此结束,我们也用类似侯捷老师的scribble例子给cmydoc类加一点代码,改为:
class cstroke:public cobject//线条类
{ ...//
protected: uint m_npenwidth;
public: carray<cpoint,cpoint>m_pointarray;
}
class cmydoc:public cdocument
{
...//
ctypedptrlist<coblist,cstroke*>m_stroklist;
}
void cmydoc::serialize(carchive& ar)
{
if (ar.isstoring())
{
// todo:在此添加存储代码/写入
}
else
{
// todo:在此添加加载代码/读出
}
m_stroklist.serialize(ar);
}
void cstroke::serialize(carchive& ar)
{