Reputation: 15
I have a program,draws shapes: Lozenge, square, rectangle, line, circle... it's same Paint in Microsoft. My problems are save and load file with Serialize(CArchive &), but i cannot save and load file when use CArray. How i can do that:
class BaseShape : public CObject
{
DECLARE_SERIAL(BaseShape)
public:
CPoint topLeft, bottomRight;
COLORREF m_clrBack;
EShapeType m_ShapeType; //enum type of shape
public:
BaseShape(void); //empty method
BaseShape (CPoint , CPoint, COLORREF, EShapeType);
~BaseShape(void);
virtual void DrawShape (CDC*); //empty method
void Serialize(CArchive& ar);
};
Implement Serialize(CArchive& ar) of BaseShape class:
IMPLEMENT_SERIAL(BaseShape, CObject, 1)
void BaseShape::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
ar << topLeft << bottomRight << m_clrBack << m_ShapeType;
}
else
{
int temp_shape;
ar >> topLeft >> bottomRight >> m_clrBack >> temp_shape;
m_ShapeType = (EShapeType)temp_shape;
}
}
Square class and Lozenge class are derived by BaseShape:
class CSquare : public BaseShape
{
public:
CSquare(void);
CSquare (CPoint , CPoint, COLORREF, EShapeType);
~CSquare(void);
void DrawShape(CDC*);
};
In MFC Document class, i have:
//declare properties
CArray<BaseShape*, BaseShape*> m_arrShape;
COLORREF m_clrBack;
EShapeType m_ShapeType;
//implement method
void CdemoDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
int i;
ar << m_arrShape.GetSize();
for (i = 0; i <m_arrShape.GetSize(); i++)
ar << m_arrShape[i];
}
else
{
int ncount, i;
ar >> ncount;
m_arrShape.RemoveAll();
for (i = 0; i < ncount; i++)
{
BaseShape* pShape = new BaseShape();
ar >> pShape;
m_arrShape.Add(pShape);
}
above my code, When i click open file, the shapes is not showed, which was drew before, although my code are not error, I save data file uncertain successfuly. I dont understand how the code lines of "isloading()" function working. Is there another way to do it ? This is my source code for all my project: http://www.mediafire.com/download/jy23ct28bgqybdc/demo.rar
Upvotes: 0
Views: 2259
Reputation: 15365
The reason is simple: You can not create a BaseShape object and expect that it get specialized when it is loaded.
The trick is that ar << saves the complete object type and saves the Name of the class in the stream to. All you need is to load the stream into an object pointer again. The CArchive code will try to find a matching object class creates it and loads it.
Please read the MSDN about CObject serializing... se also the Scribble samples and others.
if (ar.IsStoring())
{
int i;
ar << m_arrShape.GetSize();
for (i = 0; i <m_arrShape.GetSize(); i++)
ar << m_arrShape[i];
}
else
{
int ncount, i;
ar >> ncount;
m_arrShape.RemoveAll();
for (i = 0; i < ncount; i++)
{
BaseShape *pNewShape;
ar >> pNewShape;
m_arrShape.Add(pNewShape);
}
}
PS: If you provide sample code, it should match the code in your question.
Upvotes: 1