MFC技术内幕系列之(五)---MFC文档序列化内幕[5]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 bigwhite20xx 的 blog

 dword nclassindex;
 if ((nclassindex = (dword)(dword_ptr)(*m_pstoremap)[(void*)pclassref]) != 0)
 {
  // previously seen class, write out the index tagged by high bit
  if (nclassindex < wbigobjecttag)
   *this << (word)(wclasstag | nclassindex);
  else
  {
   *this << wbigobjecttag;
   *this << (dwbigclasstag | nclassindex);
  }
 }
 else
 {
  // store new class
  *this << wnewclasstag;
  pclassref->store(*this);//***

  // store new class reference in map, checking for overflow
  checkcount();
  (*m_pstoremap)[(void*)pclassref] = (void*)(dword_ptr)m_nmapcount++;
 }
  }
  最终调用void cruntimeclass::store(carchive& ar) const;来存储class information;
  到这就"写"完了。下面总结一下:
  我们看看本程序到底向硬盘中写了什么?
  按顺序应该是:ctypedptrlist中的元素个数---〉新旧类标志---〉版本号(m_wschema)---〉
                类名称字符串中的字符个数----〉类名称(ansi码)---〉调用其它成员的                              serialize 函数。---〉以此类推。
                       //////////////////////////////////////
                       /*        3.“读文件”        */
                       //////////////////////////////////////  
  看完了“写文件”,让我们看看“读文件”的内幕吧!“读文件”顾名思义,即当你打开一个文件时,应用程序从硬盘中将文件的数据读出的过程。
   当你选中“文件”菜单中的“打开”或在工具栏中单击“打开”项时,应用程序将连续调用以下序列的函数:
   cwinapp::onopenfile()——>cdocmanager::onfileopen()-->cwinapp::opendocumentfile(lpctstr lpszfilename)-->cdocmanager::opendocumentfile(lpctstr lpszfilename)--->
csingledoctemplate::opendocumentfile(lpctstr lpszpathname,bool bmakevisible)-->

 //in doccore.cpp
 bool cdocument::onopendocument(lpctstr lpszpathname)
 {      ...//
        cfileexception fe;
 cfile* pfile = getfile(lpszpathname,
  cfile::moderead|cfile::sharedenywrite, &fe);
 if (pfile == null)
 {
  reportsaveloadexception(lpszpathname, &fe,
   false, afx_idp_failed_to_open_doc);
  return false;
 }

 deletecontents();
 setmodifiedflag();  // dirty during de-serialize

 carchive loadarchive(pfile, carchive::load | carchive::bnoflushondelete);//***
 loadarchive.m_pdocument = this;
 loadarchive.m_bforceflat = false;
 try
 {
  cwaitcursor wait;
  if (pfile->getlength() != 0)
   serialize(loadarchive);     // load me***
  loadarchive.close();
  releasefile(pfile, false);
 }
 catch_all(e)
 {
  releasefile(pfile, true);
  deletecontents();   // remove failed contents

  try
  {
   reportsaveloadexception(lpszpathname, e,
    false, afx_idp_failed_to_open_doc);
  }
  end_try
  delete_exception(e);
  return false;
 }
 end_catch_all

 setmodifiedflag(false);     // start off with unmodified

 return true;
}

--->void cmydoc::serialize(carchive& ar)
   {
 if (ar.isstoring())
 {
  // todo:在此添加存储代码/写入
 }
 else
 {
  // todo:在此添加加载代码/读出
 }
       m_stroklist.serialize(ar);
   }
  //in list_o.cpp
-->void coblist::serialize(carchive& ar)
 {
 assert_valid(this);
        cobject::serialize(ar);
        if (ar.isstoring())
 {
  ...//
 }
 else
 {
  dword_ptr nnewcount = ar.readcount();//读入ctypedptrlist中的元素个数
  cobject* newdata;
  while (nnewcount--)
  {
   ar >> newdata;//***
   addtail(newdata);
  }
 }
 }
---〉

本文关键:文档序列化
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top