文号
t71866
阅读
2622
回复
1
收藏
2
不使用MFC序列化的方法(XML分析器v0.2)
2015/05/30
IP:四川
对于文档,MFC默认做法是二进制序列化(即重写文档类的Serialize()函数,用ar.IsStoring()判断是打开还是保存),大部分教材上也是这么教的。

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

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

比如我的XML Tree分析器的打开和保存代码,可以这样写——
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;
}

原来的不科学代码——
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);
    }
}

attachment icon XmlTree01-改进版.rar 407.81KB RAR 20次下载
来自:
软件综合
1
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的