青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

yehao's Blog

使用 MFC 串行化數據和 C++ 對象

轉自http://www.vckbase.com/document/viewdoc/?id=1871

源代碼下載


串行化數據
串行化C++對象
定制串行化

串行化數據

——
例子程序:Memo

  創建一個新的單文檔 SDI 應用,視圖類選擇 CFormView,以便用戶可以在窗口中輸入。 在界面中創建三個編輯框,然后再添加三個相應的編輯框變量。這三個變量是視圖類的成員變量,為了交互數據,文檔類中也要創建三個對應的變量。然后,文檔類和視圖類都要對數據成員進行初始化操作,在文檔類中這個工作通常都在 OnNewDocument() 函數中進行。因為下面任何一個操作發生時都觸發文檔類 OnNewDocument()函數執行:

  • 當用戶啟動應用程序;
  • 當用戶在“File”菜單中選擇“New”選項;

視圖類的初始化通常由 OnInitialUpdate() 負責,下面的任何一個操作發生時,代碼都會觸發視圖類 OnInitialUpdate()函數執行 :

  • 當用戶啟動應用程序;
  • 當用戶在“File”菜單中選擇“New”選項;
  • 當用戶從“File”菜單中選擇 “Open”選項;

在視圖類中獲得文檔類指針的方法是:CFooDoc* pDoc = GerDocument();
用此文檔指針便可以操作文檔類數據:m_ViewData = pDoc->m_DocData;

串行化的代碼很簡單,ar 是一個與用戶選擇的文件相對應的文檔對象(CArchive 對象):

// CFooDoc 序列化
void CFooDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// 將數據寫入文件
ar << m_DocData;
}
else
{
// 從文件中讀取數據
ar >> m_DocData;
}
}

  這樣就將數據寫入了文件,選擇“File”菜單中的“Save”或者“Save as”即可完成數據的串行化。 如果沒有保存數據,退出程序是會提示用戶是否保存修改過的數據。具體細節請參考源代碼。

串行化C++對象

——例子程序:PHN

創建一個新的單文檔 SDI 應用,視圖類選擇 CFormView,以便可以有窗口中用戶可以輸入。

聲明一個要串行化的 C++ 類。如 CPhone;

文檔類的處理:
  在文檔類中聲明一個 MFC CObList 類對象,這個類很有用,功能也很強,用它可以很輕松地維護 C++ 對象列表,例如 添加、刪除列表元素等。在文檔類的頭文件中作如下聲明:

CObList m_PhoneList;

  上面的聲明可以是 public 類型,這樣其它類可以直接訪問它。也可以是 private 類型,這樣就必須聲明一個公共的訪問函數,比如:GetPhoneList(),這個函數能返回 m_PhoneList 的地址。

通常可以在文檔類的 OnNewDocument()函數中進行數據初始化;

	// Create a CPhone Object
CPhone* pPhone = new CPhone();
pPhone->m_Name = "";
pPhone->m_Phone = "";
// Add new object to the m_PhoneList list
m_PhoneList.AddHead(pPhone);		
  在此 CPhone 類的成員變量的初始化不是必須的,因為 CPhone 的構造函數已經完成了這個工作。AddHead()函數向 m_PhoneList 列表添加剛創建的 CPhone 對象。所以,無論什么時候創建新文檔(如啟動應用程序)都會向 m_PhoneList 列表中添加一個空的 CPhone 對象。注意類 CObList 的成員函數 AddHead() 是向列表的“頭部”添加對象(列表的開始),所以參數是想要添加的對象的地址。

刪除 m_PhoneList 列表中的內容

  因為 m_PhoneList 是在內存中維護的,所以要隨時維護,只要下面三個事件中的任何一個事件發生,都需要從內存中刪除 m_PhoneList 列表中的對象:

  • 用戶退出應用程序;
  • 用戶開始一個新的文檔,如從“File”菜單中選擇“New”選項;
  • 用戶打開一個已存在的文檔,如從“File”菜單中選擇“Open”選項;

在文檔類的頭文件中聲明刪除操作的函數:

virtual void DeleteContents();

其實現如下:

// 刪除列表中的所有項目并釋放列表對象占用的內存
while ( ! m_PhoneList.IsEmpty() )
{
delete m_PhoneList.RemoveHead();
}

視圖類處理:

聲明視圖類的數據成員:

POSITION m_position; // 在文檔類列表中的當前位置
CObList* m_pList; // 指向文檔類的列表

在 OnInitialUpdate()函數中初始化視圖類的數據成員

	POSITION m_position;
CObList* m_pList;
// 獲取文檔類指針
CFooDoc* pDoc = (CFooDoc*) GetDocument();
// 獲得文檔類 m_PhoneList 的地址
m_pList = &(pDoc->m_PhoneList);
// 獲得列表頭位置
m_position = m_pList->GetHeadPosition();
// 用文檔類數據更新視圖類數據成員
CPhone* pPhone = (CPhone*)m_pList->GetAt(m_position);
m_Name = pPhone->m_Name;
m_Phone = pPhone->m_Phone;
// 用新的數據成員變量值更新屏幕顯示
UpdateData(FALSE);
// 控制輸入焦點
((CDialog*) this)->GotoDlgCtrl(GetDlgItem(IDC_NAME));

更新文檔數據

當用戶修改了視圖類的數據成員,即修改了窗體編輯框中的內容時,執行這些代碼后也會修改文檔類的數據成員。

void CFooView::OnEnChangeName()
{
// 用屏幕輸入更新控件變量
UpdateData(TRUE);
// 獲得文檔指針
CFooDoc* pDoc =(CFooDoc*)GetDocument();
// 更新文檔
CPhone* pPhone = (CPhone*)m_pList->GetAt(m_position);
pPhone->m_Name = m_Name;
// 置修改標志為 TRUE
pDoc->SetModifiedFlag();
}

在列表中移動記錄,修改視圖類中相應的函數。

	// 聲明一個臨時的位置變量
POSITION temp_pos;
// 用當前的列表位置更新 temp_pos
temp_pos = m_position;
// 用前一個/或后一個位置更新 temp_pos
m_pList->GetPrev(temp_pos);
if ( temp_pos == NULL)
{
// no previous element
MessageBox(_T("Bottom of file encountered!"),_T("Phone for Windows"));
}else
{
// 用列表前一個記錄內容更新視圖成員數據
m_position = temp_pos;
CPhone* pPhone = (CPhone*)m_pList->GetAt(m_position);
m_Name = pPhone->m_Name;
m_Phone = pPhone->m_Phone;
UpdateData(FALSE);
}
// 控制輸入焦點
((CDialog*) this)->GotoDlgCtrl(GetDlgItem(IDC_NAME));

添加和刪除列表記錄:

//添加記錄
// 清空屏幕輸入控制
m_Name = "";
m_Phone = "";
UpdateData(FALSE);
// 創建一個新的  CPhone 對象
CPhone* pPhone = new CPhone();
pPhone->m_Name = m_Name;
pPhone->m_Phone = m_Phone;
// 添加新的對象到列表尾部,并用新的位置更新 m_position
m_position = m_pList->AddTail(pPhone);
// 獲得文檔指針
CFooDoc* pDoc = (CFooDoc*) GetDocument();
// 置修改標志為 TRUE
pDoc->SetModifiedFlag();
// 控制輸入焦點
((CDialog*) this)->GotoDlgCtrl(this->GetDlgItem(IDC_NAME));
//刪除記錄
// 刪除前先保存舊的指針
CObject* pOld;
pOld = m_pList->GetAt(m_position);
// 從列表中刪除元素
m_pList->RemoveAt(m_position);
// 從內存中刪除對象
delete pOld;
// 如果列表已經清空則添加一個空記錄
if ( m_pList->IsEmpty())
{
OnBnClickedAddButton();
}
// 獲取文檔指針
CPHNDoc* pDoc = (CPHNDoc*) GetDocument();
// 置修改標志為 TRUE
pDoc->SetModifiedFlag();
// 顯示列表的第一條記錄
OnInitialUpdate();

串行化處理

  我們要串行化 CPhone 對象,把C++對象寫入文件,所以需要在 CPhone 類的定義和實現文件中加入相應的串行化代碼,首先要在 CPhone 頭文件中加入一個 MFC 宏,這是串行化需要的宏,必須為它提供一個參數,也就是類的名字。

// 串行化宏定義
DECLARE_SERIAL(CPhone)
  其次是聲明串行化函數,這個原型是必須的,因為要串行化類 CPhone 對象列表,所以 CPhone 類必須有一個屬于自己的 Serialize()函數:
// 串行化函數 Serialize()
virtual void Serialize(CArchive& ar);

  在 CPhone 實現文件中也要加入對應的代碼,這個宏也是串行化需要的另一個宏,它有三個參數,第一個是類名,第二個是基類名,第三個是應用程序的版本號,可以將版本號定義為任何值,當串行化數據到文件時,此版本號也要寫入文件。

// 串行化宏實現
IMPLEMENT_SERIAL(CPhone,CObject,0);
串行化函數 Serialize() 實現
if (ar.IsStoring())
{
ar << m_Name << m_Phone;
}
else
{
ar >> m_Name >> m_Phone;
}

這里要注意的是為了使用 CObList 類的成員函數 Serialize(),有幾個前提條件需要滿足:

  • 列表類對象必須是 MFC CObject 類的派生類對象,也就是說 CPhone 類必須是 CObject 的派生類;
  • 在列表中的對象類必須具備一個不帶參數的構造函數。如果需要,也可以有其它帶參數的構造函數;
  • 必須聲明和實現列表類的串行化函數 Serialize(),即 CPhone::Serialize();
  • 實現列表對象的串行化必須使用 DECLARE_SERIAL/IMPLEMENT_SERIAL 宏;

調用列表 Serialize()函數

  這一步是串行化列表 m_PhoneList,也就是調用 m_PhoneList 的成員函數 Serialize()。在什么地方調用呢?記住,無論用戶什么時候從“File”菜單中選擇“Save”或者“Save as”或“Open”選項,都將執行文檔類的 Serialize()函數,所以必須在文檔類的 Serialize()函數中調用 m_PhoneList 的 Serialize()函數。
  這樣一來,無論用戶什么時候從 File 菜單中選擇 Save/Save as 時,都將把 m_PhoneList 保存在用戶選擇的文件中,同樣地,無論用戶什么時候從選擇 Open 時,都將把文件中保存的列表信息加載到 m_PhoneList 中來。m_PhoneList 的串行化調用如下:

m_PhoneList.Serialize(ar);

  只要在文檔類的 Serialize() 函數中調用上面這條語句時,必須把 ar 作為參數傳入,它將完成需要串行化 m_PhoneList 列表數據的所有工作。不必在if語句中再做其它處理。

定制串行化

——例子程序:ARCH

  串行化處理有時并不需要用戶選擇文件,此時仍要從或向一個特定文件串行化數據,本部分將描述怎樣創建并定制一個 CArchive 對象。創建一個新的單文檔 SDI 應用, 工程名為 ARCH。視圖類仍然選擇 CFormView。視圖中兩個編輯框和兩個按鈕,編輯框用于輸入數據,“Save to File”按鈕用于將輸入的數據串行化到文件,“Load from File”按鈕用于從文件中抽取數據。為簡單起見,文件使用的硬編碼。
下面是 “Save to File”的操作代碼:

	// 用屏幕輸入內容更新 m_Var1 和 m_Var2
UpdateData(TRUE);
// 創建文件 C:\ARC.ARC
CFile f;
f.Open("c:\\arc.arc",CFile::modeCreate|CFile::modeWrite);
// 創建一個 CArchive 對象,并將文件與對象關聯
CArchive ar(&f,CArchive::store);
// 串行化 m_Var1 和 m_Var2 到文檔
ar<<m_Var1<<m_Var2;
// 關閉文檔
ar.Close();
// 關閉文件
f.Close();

下面是 “Load from File”的操作代碼:

	// 打開文件 C:\ARC.ARC
CFile f;
if ( f.Open("c:\\arc.arc",CFile::modeRead ) == FALSE )
return;
// 創建一個 CArchive 對象,并將文件與對象關聯
CArchive ar(&f,CArchive::load);
// 從對象中抽取數據并賦值給成員變量
ar>>m_Var1>>m_Var2;
// 關閉文檔
ar.Close();
// 關閉文件
f.Close();
// 更新屏幕顯示
UpdateData(FALSE);

  以上是三個 MFC 串行化數據的例子,Memo 程序的功能是串行化數據到文件,Phn 程序是串行化 C++ 對象列表到文件,而 ARCH 則是定制串行化。詳細實現細節請下載源代碼。

posted on 2011-05-15 17:28 厚積薄發 閱讀(358) 評論(0)  編輯 收藏 引用 所屬分類: Windows編程

導航

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

統計

常用鏈接

留言簿

隨筆分類

文章分類

文章檔案

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲永久免费av| 欧美国产第一页| 国产精品五月天| 亚洲欧洲99久久| 亚洲欧美视频一区二区三区| 国产精品一区二区三区观看 | 国产酒店精品激情| 久久精品91久久香蕉加勒比| 欧美在线亚洲一区| 亚洲丶国产丶欧美一区二区三区| 欧美1区3d| 欧美日韩高清在线| 久久www成人_看片免费不卡| 久久久久九九视频| 一二三区精品福利视频| 亚洲欧美精品中文字幕在线| 韩国av一区二区三区四区| 欧美激情一区二区三级高清视频 | 久久久久久亚洲精品中文字幕| 在线成人欧美| 亚洲精选久久| 狠狠色丁香婷综合久久| 亚洲国产精品久久久久| 欧美日韩在线亚洲一区蜜芽| 久久国产综合精品| 欧美激情免费在线| 欧美一区三区二区在线观看| 美女啪啪无遮挡免费久久网站| 亚洲视频你懂的| 久久精品99国产精品日本| 亚洲精品午夜精品| 午夜在线精品| 日韩一区二区高清| 久久精彩免费视频| 亚洲一区视频在线| 欧美99在线视频观看| 久久成人综合视频| 欧美日韩大片一区二区三区| 久久久综合香蕉尹人综合网| 欧美日韩免费| 欧美夫妇交换俱乐部在线观看| 国产精品va| 亚洲欧洲在线播放| 在线免费日韩片| 亚洲影视中文字幕| 亚洲视频 欧洲视频| 快播亚洲色图| 久久尤物电影视频在线观看| 国产精品久久二区| 日韩亚洲国产欧美| 亚洲精选一区| 美国十次了思思久久精品导航| 欧美在线免费视屏| 国产精品久久久久久av下载红粉 | 欧美不卡视频| 国产亚洲欧美一区二区三区| 中日韩美女免费视频网址在线观看 | 99视频有精品| 日韩视频在线免费观看| 毛片一区二区| 欧美成人精品h版在线观看| 国产在线日韩| 久久国产色av| 久久久女女女女999久久| 国产视频一区在线| 午夜欧美精品| 久久精品视频导航| 国产自产高清不卡| 久久精品国产91精品亚洲| 久久久久99| 在线观看欧美亚洲| 久久一区精品| 欧美激情在线观看| 日韩视频在线观看| 欧美性淫爽ww久久久久无| 中文精品视频| 欧美在线免费一级片| 国产综合色精品一区二区三区| 欧美一区二区三区的| 久久久久久夜| 亚洲国产精品日韩| 欧美精品一区二区三| 99国产麻豆精品| 欧美一区二区三区四区在线观看地址| 国产精品私房写真福利视频| 性色av香蕉一区二区| 久热精品视频在线| 日韩一级免费观看| 国产精品亚洲第一区在线暖暖韩国| 午夜精品久久久久久久蜜桃app | 亚洲精品中文字幕女同| 欧美日韩精品免费观看视频完整 | 亚洲美女视频在线观看| 亚洲欧美日韩国产中文| 国产日韩欧美日韩| 美女视频黄 久久| 日韩五码在线| 久久婷婷丁香| 在线一区二区三区四区| 国产日韩精品入口| 欧美成年视频| 先锋影音国产一区| 亚洲黄色一区| 久久国产乱子精品免费女| 亚洲韩国一区二区三区| 国产精品久久久久久久一区探花| 久久精品人人做人人爽电影蜜月 | 亚洲综合精品四区| 伊人婷婷欧美激情| 国产精品久久久久毛片软件| 久久久人成影片一区二区三区| 亚洲美女淫视频| 麻豆成人av| 午夜一区不卡| 日韩视频一区二区在线观看| 国产欧美在线| 欧美日韩亚洲免费| 久久久久久欧美| 亚洲专区欧美专区| 亚洲精品在线免费观看视频| 噜噜噜躁狠狠躁狠狠精品视频 | 欧美一区免费视频| 在线一区日本视频| 亚洲黄一区二区| 极品少妇一区二区| 国产欧美精品一区| 欧美视频中文一区二区三区在线观看| 久久九九免费| 欧美夜福利tv在线| 亚洲一二三区在线| 99v久久综合狠狠综合久久| 你懂的成人av| 久久综合久久美利坚合众国| 午夜国产欧美理论在线播放| 中文在线一区| 一区二区不卡在线视频 午夜欧美不卡'| 国内外成人在线视频| 国产精品一区在线观看| 国产精品久久久久久久久久ktv| 欧美极品影院| 欧美巨乳在线观看| 欧美黄色免费网站| 欧美激情亚洲视频| 欧美精品一区二区高清在线观看| 久久综合一区二区三区| 久久中文在线| 老司机午夜精品视频在线观看| 久久久久久久一区二区三区| 久久精品成人一区二区三区蜜臀| 欧美一区激情| 久久久久久久999精品视频| 久久久99久久精品女同性| 久久久国产精品亚洲一区| 久久男人资源视频| 美日韩精品免费观看视频| 欧美大片一区二区三区| 欧美精品一区视频| 欧美午夜电影在线| 国产日韩欧美电影在线观看| 国产日韩亚洲欧美精品| 黑人操亚洲美女惩罚| 亚洲国产精品专区久久| 亚洲精品乱码久久久久| 这里只有精品视频在线| 欧美在线一二三四区| 老司机免费视频一区二区| 亚洲高清久久| 一区二区三区黄色| 欧美一区二区在线免费播放| 久久人人爽人人爽| 欧美日韩国内自拍| 国产亚洲精品自拍| 亚洲人成啪啪网站| 亚洲欧美日本国产专区一区| 久久久久久精| 亚洲国产一区二区三区a毛片 | 性色一区二区三区| 欧美+亚洲+精品+三区| 亚洲精品影视在线观看| 香港久久久电影| 米奇777超碰欧美日韩亚洲| 欧美日韩一区综合| 一区二区三区在线看| 亚洲愉拍自拍另类高清精品| 免费成人激情视频| 亚洲一区亚洲| 欧美韩日一区二区三区| 国产午夜精品视频| 日韩视频在线一区二区| 久久久久久久97| 一区二区欧美日韩视频| 久久综合狠狠| 国产欧美一区二区精品秋霞影院 | 亚洲最新合集| 久久这里有精品视频| 亚洲夜间福利| 欧美日韩另类一区| 亚洲国产一区二区三区在线播 | 亚洲精品免费网站| 久久久国产91|