Reputation: 1304
I'm using MFC's CArhive class to save off a project file for my app. One of the class names is wildly inaccurate and I'd like to change it, but simply changing the name everywhere renders previous archive files useless with an archive error. Is there a way to change the name of the archived class without rendering all previously saved files useless?
That is of course without using a typedef to access the existing class with a new name or keeping around a version of the class with the old name to read archived files and copying the read in objects to the same class with a new name.
Upvotes: 6
Views: 1263
Reputation: 1
There is a 3rd option which I took. I originally named one of my serializable classes CEvent
which didn't seem to be a problem on VC6.0; but on VS2010 there is a MFC built-in class called CEvent
so I had to change it.
So, I fixed it by modifying old format files before calling COleServerDoc::OnOpenDocument
I simply, open, read to memory, find and replace CEvent
with any other 6 character (has to be same size) class name, write and save as new filename, then open and read new file, no problem.
I'm changing file extension for the new version anyway, so it all works out.
Upvotes: 0
Reputation:
The crucial point is that when you use DECLARE_SERIAL
and IMPLEMENT_SERIAL
, a CRuntimeClass
member is added to your class containing the name in its m_lpszClassName
field.
This CRuntimeClass
object is also added to a list maintained by the framework that is searched when classes are dynamically created.
You need to make sure that the CRuntimeClass
object contains the old name of your class in m_lpszClassName
.
The two options you have are:
Override the construction of the
CRuntimeClass
object to set the name
Change the class name stored in its
m_lpszClassName
field after it has
been created
To do this, you will need to make your own versions of DECLARE_DYMAMIC
, DECLARE_DYNCREATE
, DECLARE_SERIAL
, IMPLEMENT_DYMAMIC
, IMPLEMENT_DYNCREATE
, and IMPLEMENT_SERIAL
.
You can just copy and rename the existing implementations.
In your version of IMPLEMENT_DYNAMIC
, you need to change the code that constructs the CRuntimeClass
so that it is initialised with the old class's name.
As the CRuntimeClass
is created by a static initializer, I don't think that you can do this from within your class.
I think that the best place to do it is in your application's InitInstance
.
Add a static char*
variable to your application's class containing the old class name.
Then, in InitInstance
, set the m_lpszClassName
field in your class's CRuntimeClass
.
Either way, the first thing to do is to completely familiarise yourself with the way dynamic creation and serialization work.
Upvotes: 8