首页 > 代码库 > MFC 之支持串行化的类

MFC 之支持串行化的类

MFC中可以串行化的类必须满足以下条件
1 从CObject派生,或者间接派生
2 重写Serialize函数
3 使用DECLARE_SERIAL宏
4 定义不带参数的构造函数
5 在类的实现文件中用IMPLENT_SERIAL宏


在绘图保存的程序中,类CPaints作为保存的基本单元,它里面存储了绘图类型,起始点,终止点三个成员变量。
然后在绘图中每当绘制一幅图都会将CPaints作为保存对象,保存在View类的CObArray类型的变量中。


在文件保存中需要在Document类中保存View类中的m_obArray,加载的时候反之。
主要代码如下所示:


//Paints.h
#pragma once


// CPaints 命令目标


class CPaints : public CObject
{
public:
	CPaints();
	virtual ~CPaints();
	CPaints(UINT type,CPoint start,CPoint end);
	void Serialize(CArchive& ar);
	void Draw(CDC* pDC);
private:
	UINT m_nDrawType;
	CPoint m_ptOrigin;
	CPoint m_ptEnd;


	DECLARE_SERIAL(CPaints)
};


.............................................................................................................
//Paints.cpp
// Paints.cpp : 实现文件
//


#include "stdafx.h"
#include "mfcArchive.h"
#include "Paints.h"


IMPLEMENT_SERIAL(CPaints,CObject,1)
// CPaints


CPaints::CPaints()
{
	m_nDrawType = 0;
}


CPaints::~CPaints()
{
}




// CPaints 成员函数
CPaints::CPaints(UINT type,CPoint start,CPoint end)
{
	m_nDrawType = type;
	m_ptOrigin = start;
	m_ptEnd = end;
}


void CPaints::Serialize(CArchive& ar)
{
	if(ar.IsStoring() )
	{
		ar<<m_nDrawType<<m_ptOrigin<<m_ptEnd;
	}
	else
	{
		ar>>m_nDrawType>>m_ptOrigin>>m_ptEnd;
	}
}


void CPaints::Draw(CDC* pDC)
{
	CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
	CBrush *pOldBrush = pDC->SelectObject(pBrush);
	switch(m_nDrawType)
	{
	case 1:
		pDC->SetPixel(m_ptEnd,RGB(0,0,0));
		break;
	case 2:
		pDC->MoveTo(m_ptOrigin);
		pDC->LineTo(m_ptEnd);
		break;
	case 3:
		pDC->Rectangle(CRect(m_ptOrigin,m_ptEnd));
		break;
	case 4:
		pDC->Ellipse(CRect(m_ptOrigin,m_ptEnd));
		break;
	}
	pDC->SelectObject(pOldBrush);
}


......................................................................................................
void CmfcArchiveDoc::Serialize(CArchive& ar)
{
	POSITION ps = GetFirstViewPosition();
	CmfcArchiveView* pView = (CmfcArchiveView*)GetNextView(ps);
	if (ar.IsStoring())
	{
		// TODO: 在此添加存储代码
		int a = 5;
		char b = 'c';
		CString str("load test");
		ar<<a<<b<<str;


		//
		int nCount = pView->m_obArray.GetSize();
		ar<<nCount;
		for(int i=0;i<nCount;i++)
		{
			ar<<pView->m_obArray.GetAt(i);
		}
	}
	else
	{
		// TODO: 在此添加加载代码
		int a;
		char b;
		CString str,strResult;
		ar>>a>>b>>str;
		strResult.Format("%d,%c,%s",a,b,str);
		//AfxMessageBox(strResult);
		int nCount;
		CPaints *ps;
		ar>>nCount;
		for(int i=0;i<nCount;i++)
		{
			ar>>ps;
			pView->m_obArray.Add(ps);
		}
	}
}
............................................................................

void CmfcArchiveView::OnDraw(CDC* pDC)
{
	CmfcArchiveDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;


	// TODO: 在此处为本机数据添加绘制代码
	int nCount;
	nCount = m_obArray.GetSize();
	for(int i=0;i<nCount;i++)
	{
		( (CPaints*)m_obArray.GetAt(i) )->Draw(pDC);
	}
}