天天看點

MFC CArchive類的使用和資料序列化以及doc、view、frame指針的互相擷取

一、Document/View結構

       在MFC中,文檔類負責管理資料,提供儲存和加載資料的功能。視類負責資料的顯示,以及給使用者提供對資料的編輯和修改功能。

MFC給我們提供Document/View結構,将一個應用程式所需要的“資料處理與顯示”的函數空殼都設計好了,這些函數都是虛函數,我們可以在派生類中重寫這些函數。有關檔案讀寫的操作在CDocument的Serialize函數中進行,有關資料和圖形顯示的操作在CView的OnDraw函數中進行。我們在其派生類中,隻需要去關注Serialize和OnDraw函數就可以了,其它的細節我們不需要去理會,程式就可以良好地運作。

       當我們按下“File/Open”,Application Framework會激活檔案打開對話框,讓你指定檔案名,然後自動調用CGraphicDoc::Serialize讀取檔案。Application Framework還會調用CGraphicView::OnDraw,傳遞一個顯示DC,讓你重新繪制視窗内容。

       MFC給我們提供Document/View結構,是希望我們将精力放在資料結構的設計和資料顯示的操作上,而不要把時間和精力花費在對象與對象之間、子產品與子產品之間的通信上。

一個文檔對象可以和多個視類對象相關聯,而一個視類對象隻能和一個文檔對象相關聯。

1、doc類擷取view類的指針 GetFirstViewPosition GetNextView

2、view類或frame擷取doc類的指針 getDocument

3、view類擷取frame類的指針 Getparent

類能實作資料序列化的條件:

A serializable class usually has a Serialize member function, and it usually uses the DECLARE_SERIAL and IMPLEMENT_SERIAL macros, as described under class CObject.

Five main steps are required to make a class serializable. They are listed below and explained in the following sections:

  1. Deriving your class from CObject (or from some class derived fromCObject).
  2. Overriding the Serialize member function.
  3. Using the DECLARE_SERIAL macro in the class declaration. 
  4. Defining a constructor that takes no arguments.
  5. Using the IMPLEMENT_SERIAL macro in the implementation file for your class. 
IMPLEMENT_SERIAL( CGraph, CObject, 1 )

CGraph::CGraph()
{

}

CGraph::CGraph(UINT m_nDrawType,CPoint m_startPoint,CPoint m_endPoint)
{
	this->m_nDrawType=m_nDrawType;
	this->m_startPoint=m_startPoint;
	this->m_endPoint=m_endPoint;
}

CGraph::~CGraph()
{

}
void CGraph::Serialize( CArchive& archive)
{
	if (archive.IsStoring())
	{
		archive<<m_nDrawType<<m_startPoint<<m_endPoint;
	}else{	
		archive>>m_nDrawType>>m_startPoint>>m_endPoint;
	}
}


//文檔類
void CGraphicDoc::Serialize(CArchive& ar)
{
	POSITION pos=GetFirstViewPosition();
	CGraphicView *pView=(CGraphicView *)GetNextView(pos);
	if (ar.IsStoring())
	{
		// TODO: add storing code here
		int nCount=pView->m_ptrArray.GetSize();
		ar<<nCount;
		for (int i=0;i<nCount;i++)
		{
			ar<<(CGraph *)pView->m_ptrArray.GetAt(i);
		}	
	}
	else
	{
		// TODO: add loading code here
		int nCount;
		ar>>nCount;
		CGraph *pGraph;
		for (int i=0;i<nCount;i++)
		{
			ar>>pGraph;
			pView->m_ptrArray.Add(pGraph);
		}
	}
}