【问题标题】:Rename MFC CArchive Serialized class重命名 MFC CArchive 序列化类
【发布时间】:2010-11-05 14:56:16
【问题描述】:

我正在使用 MFC 的 CArhive 类为我的应用程序保存项目文件。其中一个类名非常不准确,我想更改它,但只是在任何地方更改名称都会使以前的存档文件无用并出现存档错误。有没有办法在不使之前保存的所有文件失效的情况下更改归档类的名称?

这当然是不使用 typedef 来访问具有新名称的现有类或保留具有旧名称的类的版本来读取存档文件并将读取的对象复制到具有新名称的同一个类.

【问题讨论】:

    标签: c++ mfc


    【解决方案1】:

    关键点是当您使用DECLARE_SERIALIMPLEMENT_SERIAL 时,一个CRuntimeClass 成员将添加到您的类中,该成员在其m_lpszClassName 字段中包含名称。 这个CRuntimeClass 对象也被添加到由框架维护的列表中,在动态创建类时搜索该列表。 您需要确保CRuntimeClass 对象在m_lpszClassName 中包含您的类的旧名称。

    您有两个选择:

    1. 覆盖 CRuntimeClass对象设置名称

    2. 更改存储在其 m_lpszClassName 字段后 已创建

    重写 CRuntimeClass 对象的构造

    为此,您需要制作自己的 DECLARE_DYMAMICDECLARE_DYNCREATEDECLARE_SERIALIMPLEMENT_DYMAMICIMPLEMENT_DYNCREATEIMPLEMENT_SERIAL 版本。 您可以复制并重命名现有的实现。 在您的IMPLEMENT_DYNAMIC 版本中,您需要更改构造CRuntimeClass 的代码,以便使用旧类的名称对其进行初始化。

    在创建 CRuntimeClass 对象后更改存储在 m_lpszClassName 字段中的类名

    由于CRuntimeClass 是由静态初始化程序创建的,我认为您不能在您的类中执行此操作。 我认为最好的方法是在您的应用程序的InitInstance 中。 将static char* 变量添加到包含旧类名的应用程序类。 然后,在InitInstance 中,在您班级的CRuntimeClass 中设置m_lpszClassName 字段。

    • 第一种方法的优点是 保持类内的变化 本身。
    • 第二个使应用程序 以某种方式了解班级 可能不应该。

    无论哪种方式,首先要做的就是完全熟悉动态创建和序列化的工作方式。

    【讨论】:

    • 可能更快地编写一个实用程序来转换保存文件的内容,以便他们使用新名称...+1 以获得彻底的答案,清楚地了解所涉及的内容。
    • @Kate Gregory,谢谢,我也会转换文件,可能会覆盖 OpenDocumentFile 而不是单独的程序,因为如果文档文件是他们的。
    • 感谢您的回答,我决定继续前进,不理会班级名称。似乎不值得付出那么多努力。
    【解决方案2】:

    我选择了第三个选项。我最初将我的一个可序列化类命名为CEvent,这在VC6.0 上似乎不是问题;但在 VS2010 上有一个名为 CEvent 的 MFC 内置类,所以我不得不更改它。

    所以,我在调用COleServerDoc::OnOpenDocument之前通过修改旧格式文件来修复它

    我只是简单地打开,读取内存,找到CEvent并将其替换为任何其他6个字符(必须相同大小)的类名,写入并保存为新文件名,然后打开并读取新文件,没问题。

    无论如何,我正在更改新版本的文件扩展名,所以一切正常。

    【讨论】:

    • 感谢您提供另一种选择。我从未在文本编辑器中查看过存档文件,但您不会遇到元数据或已序列化的字符串因执行此类操作而被更改的任何潜在问题吗?
    猜你喜欢
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 2011-01-25
    • 2017-05-21
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    相关资源
    最近更新 更多