我在一个多文档框架下通过void CMyDoc::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
    }
    else
    {
    }
}来保存和打开一个自己的文档,完全正常。可是我现在需要在一个dll中去解析这个文档,要怎么样做呢,能否贴点代码看看啊?

解决方案 »

  1.   

    创建了,
    我现在在dll中有一个函数:ParseFile(const CString& strFile)
    后面代码大概怎么样啊?
      

  2.   

    封装读取/存储操作到dll,然后在void CMyDoc::Serialize(CArchive& ar)
    中调用不就行了?
      

  3.   

     我这个dll是给其他应用来调用的,那么在其他软件中如何构造这个CArchive参数呢?这个能解决,也就可以了。
      

  4.   

    给ParseFile再加个参数 CArchive& ar
      

  5.   


    可以的啊,可是其他应用程序怎么构造这个CArchive& ar参数,该应用程序不是一个Document,没有Serialize的。
      

  6.   

    先根据文件路径及名称构造一个CFile对象,再用这个CFile对象构造一个CArchive对象。
      

  7.   

    用CFile关联一个CArchive,打开这个文档,然后调用operator >>和operator <<。只要你知道文档的格式,应该不是问题吧?
      

  8.   


    CFileException ex;
    CFile file; if (!file.Open(strFile, CFile::modeRead|CFile::shareExclusive, &ex))
    return FALSE;
    CArchive ar(&file, CArchive::load);
    我这样先构造出来的ar,解析出的内容是不对的。
      

  9.   

    一致的,原文档程序中的load和store都正常,在dll中load出来的却是乱码
      

  10.   

    跟踪了下mfc的doc代码,发现下面构建的ar在dll中解析正常。
    // 打开文件
    LPCOLESTR lpsz = strFile.GetString();
    LPSTORAGE lpStorage = NULL;
    SCODE sc = StgOpenStorage(lpsz, NULL, STGM_READ | STGM_TRANSACTED, 0, 0, &lpStorage);
    if (FAILED(sc))
    return FALSE; CFileException ex;
    COleStreamFile file; if (!file.OpenStream(lpStorage, _T("Contents"), CFile::modeRead|CFile::shareExclusive, &ex))
    return FALSE;
    CArchive ar(&file, CArchive::load);
    平白无故用到了LPSTORAGE这么个类型,还有个常量_T("Contents"), 万一哪天mfc把这个换了,我不是玩完了。
      

  11.   

    我就是用的如下的代码,也是在DLL中做的,是正常的。 CString path=Browse.GetFileName();
    CFile fileLoad(path, CFile::modeRead);
    CArchive arLoad(&fileLoad, CArchive::load);
    Serialize(arLoad);
    arLoad.Close();
    fileLoad.Close();
      

  12.   

    我的是vs2005。我也是在DLL中保存和打开一个文档。我写的时候就是这么简单,没出现问题。
      

  13.   

    晕倒。
    明白了,
    我的文档是从COleDocument继承的,可能是这个引起的。不知道前人为什么要从这个来继承呢
      

  14.   

    呵呵,有可能,我的就是CDocument,没有用COleDocument。COleDocument包含容器,可能你需要实现的功能要复杂吧。
      

  15.   

    MFC序列化的数据不是标准的复合文档,但是原理大致相同,每段从CObject派生的类保存的数据前都有一个前缀数据,用来指明数据类型,在符合文档中这个前缀是一个CLSID,在MFC中它是类名,通过类名能用CRuntimeClass把序列化数据初始化成类实例。如果仅仅封装成一个DLL来读取序列化文件可能存在潜在的风险,就是找不到登记的运行时类,从而无法创建出类实例,体现为反序列化失败。举个例子:
    假设你的文件是由某个应用程序生成的,该文件中保存了一个CMyClass实例的数据,如果新做的DLL中没有使用CMyClass类,那么它反序列化就会失败,因为它根本不知道如何创建这个类的实例。所以序列化和反序列化必须由同一个模块来完成,不可能分离到一个通用的DLL中。
    复合文档的读取也是一样的,但是它不存在把数据恢复成对象的问题,因为CLSID前缀将保证合适的组件被找到并加载,然后把有效数据交给这个组件来初始化。
      

  16.   

    谢谢谢谢,是你的代码给了我信心啊,这样我可以相信我的代码必须用到LPSTORAGE了,应该没什么别的办法了,呵呵。
      

  17.   


    是有风险的,不过我在dll中不需要创建出类实例,而只需要这个类数据,提取出数据交给其他应用程序使用。
    而且最大的麻烦是我的文档序列化有改变时,这个dll也要同步的改变。
      

  18.   

    问题在于每个类需要的数据大小DLL是不知道的,甚至同一个类的不同实例序列化的长度可能也不同,后面怎么区分下一个类的开始?要不派生一个CArchive类,在文件里加上内容长度信息。