设为首页 加入收藏

TOP

使用 MFC 串行化数据和 C++ 对象(一)
2011-04-28 12:40:16 来源: 作者: 【 】 浏览:2731
Tags:使用 MFC 串行 数据 对象

串行化数据 

——
例子程序: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++(www.cppentry.com)对象

——例子程序:PHN

创建一个新的单文档 SDI 应用,视图类选择 CFormView,以便可以有窗口中用户可以输入。

声明一个要串行化的 C++(www.cppentry.com) 类。如 CPhone;

文档类的处理:
  在文档类中声明一个 MFC CObList 类对象,这个类很有用,功能也很强,用它可以很轻松地维护 C++(www.cppentry.com) 对象列表,例如 添加、删除列表元素等。在文档类的头文件中作如下声明:

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 fo
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇深入C++的new 下一篇C++编程对缓冲区的理解

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: