不使用MFC序列化的方法(XML分析器v0.2)
acmilan2015/05/30软件综合 IP:四川
对于文档,MFC默认做法是二进制序列化(即重写文档类的Serialize()函数,用XXXXXStoring()判断是打开还是保存),大部分教材上也是这么教的。

但是我们常常需要使用其它格式保存文档(比如XML格式、BMP格式等),而这时文档已被打开,序列化时常会破坏原来的数据格式,导致文件损坏。所以大部分情况下,序列化并没有什么用处,反而会有坏处,我们通常不需要使用序列化。

不使用序列化的方法很简单,重写OnOpenDocument()和OnSaveDocument函数(它们默认打开文件,构建CArchive并调用Serialize函数),用自己的打开、保存代码重写之后,就不会自动打开文件并序列化了,可以安全地使用其它格式。

比如我的XML Tree分析器的打开和保存代码,可以这样写——
<code class="lang-cpp">void CXmlTree01Doc::Serialize(CArchive& ar)
{
    // 不使用序列化 —— 打开和保存代码见OnOpenDocument和OnSaveDocument
    if (ar.IsStoring())
    {
    }
    else
    {
    }
}
             
BOOL CXmlTree01Doc::OnSaveDocument(LPCTSTR lpszPathName)
{
    return FALSE; // 保存失败!
}
             
BOOL CXmlTree01Doc::OnOpenDocument(LPCTSTR lpszPathName)
{
    if (!CDocument::OnOpenDocument(lpszPathName))
        return FALSE;
             
    MSXML2::IXMLDOMDocumentPtr pDoc; // 文档对象
    MSXML2::IXMLDOMElementPtr xmlRoot; // 根元素
             
    HRESULT hr = pDoc.CreateInstance(_uuidof(MSXML2::DOMDocument30)); // 使用的msxml版本和新建对象的版本必须一致
    if (FAILED(hr))
    {
        AfxMessageBox("无法创建DOM文件对象,检查是否安装MS XML Parser运行库!");
        return FALSE;
    }
             
    pDoc->load(lpszPathName);
                 
    MSXML2::IXMLDOMElementPtr pElement;
    pElement = pDoc->GetdocumentElement();
             
    m_rootnode.name = (char *)pElement->GettagName();
    m_rootnode.child = NULL;
    m_rootnode.sibling = NULL;
    m_rootnode.text = (char*)pElement->Gettext();
    ReadAttribute(pElement, &m_rootnode);
             
    ReadElements(pElement->GetfirstChild(), &m_rootnode);
             
    this->SetModifiedFlag(false);
             
    return TRUE;
}</code>

原来的不科学代码——
<code class="lang-cpp">void CXmlTree01Doc::Serialize(CArchive& ar)
{
    MSXML2::IXMLDOMDocumentPtr pDoc; // 文档对象
    MSXML2::IXMLDOMElementPtr xmlRoot; // 根元素
         
    HRESULT hr = pDoc.CreateInstance(_uuidof(MSXML2::DOMDocument30)); // 使用的msxml版本和新建对象的版本必须一致
    if (FAILED(hr))
    {
        AfxMessageBox("无法创建DOM文件对象,检查是否安装MS XML Parser运行库!");
        return;
    }
         
    if (ar.IsStoring())
    {
        // TODO: 在此添加存储代码
        ASSERT(!"不支持程序保存!");
    }
    else
    {
        // TODO: 在此添加加载代码
        CFile *f = ar.GetFile();
        if (f == NULL) return;
        pDoc->load((const char*)f->GetFilePath());
                 
        MSXML2::IXMLDOMElementPtr pElement;
        pElement = pDoc->GetdocumentElement();
         
        m_rootnode.name = (char *)pElement->GettagName();
        m_rootnode.child = NULL;
        m_rootnode.sibling = NULL;
        m_rootnode.text = (char*)pElement->Gettext();
        ReadAttribute(pElement, &m_rootnode);
         
        ReadElements(pElement->GetfirstChild(), &m_rootnode);
         
        this->SetModifiedFlag(false);
    }
}</code>

attachment icon XmlTree01-改进版.rar 407.81KB RAR 17次下载
来自:计算机科学 / 软件综合
1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,5年3个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}