正文

第十五课:文档系列化2007-09-25 15:51:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lym51/29660.html

分享到:

第十五课:文档系列化

一、View中存取文件:

1.  Carchive写文件:

  CFileDialog dlg(false);

    if (IDOK==dlg.DoModal())

    {

        CFile f(dlg.GetPathName(),CFile::modeCreate|CFile::modeWrite );

        CArchive ar(&f,CArchive::store);

        CString str("abc");

        ar<<3<<'c'<<6.6f<<str;

    }

2.  Carchive读文件:

    CFileDialog dlg(true);

    if (IDOK==dlg.DoModal())

    {

        CFile f(dlg.GetPathName(),CFile::modeRead);

        CArchive ar(&f,CArchive::load);  

        int x;

        char c;

        float d;

        CString st;

        ar>>x>>c>>d>>st;

        CString str;

        str.Format("%d,%c,%f,%s",x,c,d,st);

        MessageBox(str);

    }

说明:

a.     在代码中一个小数被默认为double类型;

b.     Carchive Cfile的包装类,简化了存取文件的操作,但它只能存取有限种数据类型。

二、Docment类中存取文件:

Docment类的Serialize函数中加入:

    if (ar.IsStoring())

    {

    CString str("abc");

        ar<<3<<'c'<<6.6f<<str;

   

      else

    {

        int x;

        char c;

        float d;

        CString st;

        ar>>x>>c>>d>>st;

        CString str;

        str.Format("%d,%c,%f,%s",x,c,d,st);

        MessageBox(NULL,str,0,0);

}

说明:

1.          这段代码等效于“一”中的存取文件的代码。

2.          Serialize函数会在用户点击MFC提供的有关文件的菜单时自动被调用,在调用之前,MFC会首先生成一个标准文件对话框,再根据用户的选择生成一个Cfile,再生成一个Carchive,把它传入Serialize。这大大简化了程序员的工作。

三、画线并将数据保存成文件:

1、  定义一个可序列化的类Cline:

a.     新建一个类,从Cobject派生,(在Class type中要选Generic Class,否则基类选不了Cobject。在类名中输入Cline;

b.     Cline中覆盖Serialize成员函数。

c.     在类的声明中使用DECLARE_SERIAL宏:

         DECLARE_SERIAL( Cline)

d.     定义一个一不带参数的构造函函数。

e.     在类的实现文件中使用IMPLEMENT_SERIAL宏:

    IMPLEMENT_SERIAL( CMygraph, CObject, 1 )

f.加入两个成员变量,记录一条线的起点和终点:

      CPoint m_ptOrigin;

          CPoint m_ptEnd;

2、  Document类中定义一个成员变量,用于保存每一根线的数据: 

       CObArray m_lnArray;

3、  View类中加入WM_LBUTTONDOWNWM_LBUTTONUP的响应函数,并加入一个成员变量,用于记录一条线的起点:

CPoint m_ptOrigin;

4、  OnLButtonDown中:

       m_ptOrigin=point;

5、  OnLButtonUp中:

    Cline *pLine=new Cline();

    pline->m_ptOrigin=m_ptOrigin;

    pline->m_ptEnd=point;

    GetDocument()->m_lnArray.Add(pLine);

    Invalidate();

6、  View类的OnDraw函数中加入:

    int x=pDoc->m_graphArray.GetSize();

  for (int i=0;i<x;i++)

{    pDC->MoveTo(((Cline*)pDoc->m_lnArray.GetAt(i))->m_ptOrigin);

pDC->LineTo(((CLine*)pDoc->m_lnArray.GetAt(i))->m_ptEnd);

}

7、  Document类中的Serialize函数中:

         m_lnArray.Serialize(ar);

四、DeleteContent:

document类中加入DeleteContent虚函数,它会在用户点击“打开”和“新建”菜单时自动调用,这是删除文档数据的最好时机。删除时有两种常见的错误:

 1.错误方法一:

    for (int i=0;i<m_lnArray.GetSize();i++)

        delete (Cline*)m_lnArray.GetAt(i);

    m_lnArray.RemoveAll();

原因:每循环一次,m_lnArray.GetSize()返回的值都会减小,造成数据的漏删。

2.错误方法二:

 int index=lnArray.GetSize();

  for (int i=0;i<index;i++)

{

      delete (Cline*)m_graphArray.GetAt(i);

      m_lnArray.RemoveAt(i);

}

原因:每删除一个数组元素,数组都会重新排序,它的下标会变。

3.正确方法:

    int index=m_lnArray.GetSize();

    while(index--)

        delete (Cline*)m_lnArray.GetAt(index);

    m_lnArray.RemoveAll();


阅读(4414) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册