MFC的Serialize机制及其使用(转)
1. OnNewDocument()調(diào)用過(guò)程:
? 程序啟動(dòng)->CWinApp:;OnFileNew(m_pDocManager->OnFileNew()) ->CDocManager::OnFileNew(pTemplate->OpenDocumentFile(NULL)) ->CSingleDocTemplate::OpenDocumentFile(CreateNewDocument->CreateNewFrame?? ? pDocument->OnNewDocument) -> CGraphicDoc::OnNewDocument
2.Serialize()調(diào)用過(guò)程
文件打開菜單命令->CWinApp::OnFileOpen(m_pDocManager->OnFileOpen()) ->CDocManager::OnFileOpen(調(diào)用DoPromptFileName函數(shù)顯示文件打開對(duì)話框->AfxGetApp()->OpenDocumentFile) ->CWinApp::OpenDocumentFile(m_pDocManager->OpenDocumentFile) ->CDocManager::OpenDocumentFile ->CSingleDocTemplate::OpenDocumentFile(pDocument->OnOpenDocument) ->CDocument::OpenDocument(構(gòu)造一個(gè)CFile::modeRead模式的Cfile對(duì)象-》構(gòu)造一個(gè)CArchive::load模式的CArchive對(duì)象-》Serialize(loadArchive))->CGraphicDoc::Serialize
?
?[文件\新建]和【文件\打開】菜單項(xiàng)的命令響應(yīng)函數(shù)都是在CWinApp類中提供的。CWinApp類有一個(gè)成員變量:m_pDocManager,是指向CDocManager對(duì)象的指針,也就是說(shuō),CWinApp負(fù)責(zé)管理文檔管理器,而后者有一個(gè)文檔模板指針鏈表:m_templateList,用來(lái)保存文檔模板的指針,即文檔管器負(fù)責(zé)管理文檔模板,而后者又是用來(lái)管理文檔類、框架類和視類的,始終讓這三個(gè)對(duì)象三位一體,一起為文檔服務(wù)。
MFC提供了非常方便的串行化函數(shù)Serialize()。利用這個(gè)機(jī)制可以很方便的對(duì)文檔進(jìn)行存取和讀取。
Serialization就是面向?qū)ο笫澜缋锩娴挠谰蒙鏅C(jī)制,對(duì)象必須能夠永久生存,也就是他們必須能夠在程序結(jié)束時(shí)存儲(chǔ)到文件當(dāng)中,并且能夠在程序重新激活時(shí)在恢復(fù)過(guò)來(lái),存儲(chǔ)和恢復(fù)對(duì)象的過(guò)程在MFC稱之為Serialization,負(fù)責(zé)這項(xiàng)重要任務(wù)的是MFC Object類中的一個(gè)名為Serialize()的虛函數(shù),文件的讀寫操作均通過(guò)它來(lái)方便的完成。
一個(gè)類要支持Serializable,必須遵循以下步驟:
該類必須要繼承自CObject
在該類的頭文件中添加DECLARE_SERIAL宏
在該類的實(shí)現(xiàn)文件中添加 IMPLEMENT SERIAL宏
為該類添加一個(gè)缺省構(gòu)造函數(shù)
在該類中重寫Serialize( CArchive& ar )函數(shù)
之后,該類就可以被Serializable。
如何使用:
譬如我們新建一個(gè)MFC應(yīng)用程序,為了方便處理數(shù)據(jù),我們?cè)诔绦蛑袉为?dú)創(chuàng)建自己的類MyClass:
MyClass:public CObject
{
DECLARE_SERIAL(MyClass) ????//很重要一定要加上
?
public:
???virtual void Serialize(CArchive& ar);
public:
???int m_iVal;
???float m_fVal;
};
在實(shí)現(xiàn)文件中:
IMPLEMENT_SERIAL(MyClass,CObject,1)
?
void MyClass::Serialize(CArchive& ar)
{
???if(ar.IsLoading())
???{
??????//從文件中讀取數(shù)據(jù)到內(nèi)存中
??????ar >> m_iVal;
??????ar >> m_fVal;
???}
???else if(ar.IsStoring())
???{
??????ar << m_iVal;
??????ar << m_fVal;
???}
}
然后在MFC程序的C**Doc類中添加一個(gè)MyClass類型的對(duì)象myclass:
class C***Doc : public CDocument
{
public:
??C***Doc();
??DECLARE_DYNCREATE(C***Doc)
?
public:
??MyClass myclass;
?
public:
??virtual void Serialize(CArchive& ar);
?
*******
?
}
并且在C***Doc類的Serialize()函數(shù)中調(diào)用我們的myclass對(duì)象的Serialize函數(shù)就可以永久保存myclass對(duì)象了:
IMPLEMENT_DYNCREATE(C***Doc, CDocument)
?
BEGIN_MESSAGE_MAP(C***Doc, CDocument)
END_MESSAGE_MAP()
?
IMPLEMENT_SERIAL(MyClass,CObject,1);
?
void C***Doc::Serialize(CArchive& ar)
{
?if (ar.IsStoring())
?{
???myclass.Serialize(ar);
?}
?else
?{
???myclass.Serialize(ar);
?}
}
如何觸發(fā)Serialize
當(dāng)我們新建一個(gè)基于文檔的MFC程序時(shí),向?qū)?huì)自動(dòng)為我們創(chuàng)建一些菜單,點(diǎn)擊菜單的保存或者打開文件按鈕時(shí),內(nèi)部機(jī)制自動(dòng)觸發(fā)Serialize函數(shù)調(diào)用,那么怎樣在程序中自己觸發(fā)Serialize呢?
剖開文件保存和打開內(nèi)部機(jī)制(詳見深入淺出MFC),對(duì)于讀取文件,會(huì)得到類似這樣的調(diào)用來(lái)觸發(fā)Serialize加載機(jī)制:
CFileException fe;
CFile *pFile=GetFile("d://file.txt",
??????????????CFile::modeRead | CFile::shareDenyWrite,
??????????????&fe);
DeleteContents();
SetModifiedFlag();
CArchive loadArchive(pFile,CArchive::load );
loadArchive.m_pDocument=this;
loadArchive.m_bForceFlat=FALSE;
CWaitCursor wait;
if(pFile->GetLength()!=0)
???Serialize(loadArchive);
loadArchive.Close();
ReleaseFile(pFile,FALSE);
類似的,可以使用下面的操作來(lái)觸發(fā)Serialize保存機(jī)制:
CFileException fe;
CFile *pFile=GetFile("d://file.txt",CFile::modeCreate|
?????????CFile::modeWrite | CFile::shareDenyWrite,
?????????&fe);
DeleteContents();
SetModifiedFlag();
CArchive saveArchive(pFile,CArchive::store );
saveArchive.m_pDocument=this;
saveArchive.m_bForceFlat=FALSE;
CWaitCursor wait;
if(pFile->GetLength()!=0)
Serialize(saveArchive);
saveArchive.Close();
ReleaseFile(pFile,FALSE);
轉(zhuǎn):http://blog.sina.com.cn/s/blog_914851f70102v2i2.html
總結(jié)
以上是生活随笔為你收集整理的MFC的Serialize机制及其使用(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 项目经理沟通的四个好习惯
- 下一篇: 在MFC里面实现线程的实例