Переименовать MFC CArchive Сериализованный класс - PullRequest
6 голосов
/ 05 ноября 2010

Я использую класс CArhive MFC, чтобы сохранить файл проекта для моего приложения. Одно из названий классов крайне неточно, и я хотел бы изменить его, но простое изменение имени везде делает предыдущие архивные файлы бесполезными с ошибкой архива. Есть ли способ изменить имя заархивированного класса, не делая все ранее сохраненные файлы бесполезными?

Это, конечно, без использования typedef для доступа к существующему классу с новым именем или хранения версии класса со старым именем для чтения архивных файлов и копирования объектов чтения в тот же класс с новым именем .

Ответы [ 2 ]

8 голосов
/ 05 ноября 2010

Важным моментом является то, что при использовании DECLARE_SERIAL и IMPLEMENT_SERIAL в ваш класс добавляется член CRuntimeClass, содержащий имя в поле m_lpszClassName. Этот CRuntimeClass объект также добавляется в список, поддерживаемый платформой, в которой производится поиск при динамическом создании классов. Вы должны убедиться, что объект CRuntimeClass содержит старое имя вашего класса в m_lpszClassName.

У вас есть два варианта:

  1. Переопределить конструкцию CRuntimeClass объект для установки имени

  2. Изменить имя класса, хранящееся в его m_lpszClassName поле после того, как оно имеет создано

Переопределение конструкции объекта CRuntimeClass

Для этого вам необходимо создать собственные версии DECLARE_DYMAMIC, DECLARE_DYNCREATE, DECLARE_SERIAL, IMPLEMENT_DYMAMIC, IMPLEMENT_DYNCREATE и IMPLEMENT_SERIAL. Вы можете просто скопировать и переименовать существующие реализации. В вашей версии IMPLEMENT_DYNAMIC вам нужно изменить код, который создает CRuntimeClass, чтобы он инициализировался с именем старого класса.

Изменение имени класса, хранящегося в поле m_lpszClassName после создания объекта CRuntimeClass

Поскольку CRuntimeClass создается статическим инициализатором, я не думаю, что вы можете сделать это из своего класса. Я думаю, что лучшее место для этого - приложение InitInstance. Добавьте переменную static char* в класс вашего приложения, содержащий старое имя класса. Затем в InitInstance установите поле m_lpszClassName в CRuntimeClass.

вашего класса.
  • Первый метод имеет преимущество держать изменения в классе сам по себе.
  • Второй делает заявку знать о классе таким образом, чтобы он возможно, не должно быть.

В любом случае, первое, что нужно сделать, это полностью ознакомиться с тем, как работают динамическое создание и сериализация.

0 голосов
/ 08 июня 2011

Есть третий вариант, который я выбрал.Первоначально я назвал один из моих сериализуемых классов CEvent, который, по-видимому, не был проблемой в VC6.0;но на VS2010 есть встроенный класс MFC с именем CEvent, поэтому мне пришлось его изменить.

Итак, я исправил его, изменив файлы старого формата перед вызовом COleServerDoc::OnOpenDocument

Iпросто откройте, прочитайте в память, найдите и замените CEvent на любое другое имя класса из 6 символов (должно быть такого же размера), запишите и сохраните как новое имя файла, затем откройте и прочитайте новый файл, без проблем.

В любом случае я изменяю расширение файла для новой версии, так что все работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...