文档与串行化

新建一个MFC的单文档应用程序,工程名字叫Graphic

1.利用CArchive完成文件读写操作

在菜单资源中新建一个文件菜单,并分别添加两个菜单项,id:IDM_FILE_WRITE(写文件)id:IDM_FILE_READ(读文件),并分别对这两个菜单项添加命令响应,编辑:

void CGriphic3View::OnFileWrite()  

CFile file("1.txt",CFile::modeCreate|CFile::modeWrite); 
    CArchive ar(&file,CArchive::store); 
    int i=4
    char ch='a'
    float f=1.3f;//
加一个f表明这是一个浮点数 
    CString str("http://www.luowei.org"); 
    ar<<i<<ch<<f<<str;//
将数据插入到CArchive对象当中 

 void CGriphic3View::OnFileRead()  

CFile file("1.txt",CFile::modeRead); 
    CArchive ar(&file,CArchive::load); 
    int i; 
    char ch; 
    float f; 
    CString str; 
    CString strResult; 
    ar>>i>>ch>>f>>str; 
    strResult.Format("%d,%c,%f,%s",i,ch,f,str); 
    MessageBox(strResult);
 
}

2.设置文档的标题

方式一、在CGriphic3Doc::OnNewDocument()函数中编辑:

BOOL CGriphic3Doc::OnNewDocument() 

    if (!CDocument::OnNewDocument()) 
        return FALSE; 
    // TODO: add reinitialization code here 
    // (SDI documents will reuse this document) 
    SetTitle("http://www.luowei.org");//
设置文档标题 
    return TRUE; 

方式二、打开字符串表

IDR_MAINFRAME中添加:

Griphic3\nGraphic\nGriphi\n\n\nGriphic3.Document\nGriphi Document

IDR_MAINFRAME中字串的代表意义:

CDocTemplate::GetDocString

This method retrieves a specific substring that describes the document type. The document template stores the string containing these substrings and derives from a string in the resource file for the application. The framework calls this method to get the strings needed for the user interface in the application. If you specify a filename extension for documents in an application, the framework calls this method when adding an entry to the Windows CE registration database; this allows documents to be opened from the Windows CE File Manager.

Call this method only if you are deriving your own class from CDocTemplate.

virtual BOOL GetDocString(

CString& rString,

enum DocStringIndex index )

const;

Parameters

rString

A reference to a CString object that will contain the string when the function returns.

index

An index of the substring retrieved from the string that describes the document type. This parameter can have one of the following values:

  • CDocTemplate::windowTitle   Name that appears in the title bar of the application window like, Microsoft Excel. Present only in the document template for SDI applications.
  • CDocTemplate::docName   Root for the default document name (for example, Sheet). This root, plus a number, is used for the default name of a new document of this type whenever the user chooses the New command from the File menu (for example, Sheet1 or Sheet2). If not specified, the name Untitled is used as the default.
  • CDocTemplate::fileNewName   Name of this document type. If the application supports more than one type of document, this string is displayed in the File New dialog box (for example, Worksheet). If not specified, the document type is inaccessible using the File New command.
  • CDocTemplate::filterName   Description of the document type and a wildcard filter matching documents of this type. This string is displayed in the List Files Of Type drop-down list in the File Open dialog box (for example, Worksheets (*.xls) ). If not specified, the document type is inaccessible using the File Open command.
  • CDocTemplate::filterExt   Extension for documents of this type (for example, .xls). If not specified, the document type is inaccessible using the File Open command.
  • CDocTemplate::regFileTypeId   Identifier for the document type to be stored in the registration database maintained by Windows CE. This string is for internal use only (for example, ExcelWorksheet). If not specified, the document type cannot be registered with the Windows File Manager.
  • CDocTemplate::regFileTypeName   Name of the document type to be stored in the registration database. This string may be displayed in dialog boxes of applications that access the registration database (for example, Microsoft Excel Worksheet).

Return Value

Nonzero if the specified substring was found; otherwise, it is zero.

3.利用CArchive保存对象

CGriphic3Doc::Serialize(CArchive& ar)中编辑:

void CGriphic3Doc::Serialize(CArchive& ar) 

    if (ar.IsStoring()) 
    { 
        int i=5
        char ch='b'
        float f=1.2f; 
        CString str("http://www.baidu.com"); 
        ar.<<i<<ch<<f<<str;
 
    } 
    else 
    { 

        CString str; 
        CString strResult; 
        ar>>i>>ch>>f>>str; 
        strResult.Format("%d,%c,%f,%s",i,ch,f,str); 
        AfxMessagBox(strResult);
 
    } 
}

4.创建图形元素

先生成一个可串行化的类

    1.把第11课中的CGriph3工程的Griph.h,Griph.cpp添加到工程,并将Griph.cpp中的头文件//#include "Graphic2.h" 注释起来,再修改:

class CGraph :public CObject 

    DECLARE_SERIAL(CGraph) //
要求调用这个宏 
public
    void Draw(CDC* pDC ); 
    CPoint m_ptOrigin; 
    CPoint m_ptEnd; 
    UINT m_nDrawType; 
    CGraph(); 
    CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd); 
    void Serialize(CArchive &ar);//
声明Serialize函数 
    virtual ~CGraph(); 
}; 

并在Graph.cpp中编辑:

CGraph::CGraph()前面添加:

IMPLEMENT_SERIAL(CGraph,CObject,1)//加这样一个宏,为使CGraph支持串行化

void CGraph::Serialize(CArchive &ar) 

    if(ar.IsStoring()) 
    { 
        ar<<m_nDrawType<<m_ptOrigin<<m_ptEnd; 
    } 
    else 
    { 
        ar>>m_nDrawType>>m_ptOrigin>>m_ptEnd; 
    } 
}

然后再给CGraph添加一个CGraph::Draw成员函数,并将第11课的菜单资源的绘图菜单,拷贝到这个工程中菜单中,修改ID号,并分别添加命令响应函数,再在CGriphic3View添加两个成员变量:

private:  //添加两成员变量 
    UINT m_nDrawType; 
    CPoint m_ptOrigin;

并在构造函数中初始化:

CGriphic3View::CGriphic3View() 

    // TODO: add construction code here 
    m_nDrawType=0;  //
初始化成员变量 
    m_ptOrigin=0;
 

编辑:

void CGriphic3View::OnPoint()  

    m_nDrawType=1; 

 void CGriphic3View::OnLine()  

    m_nDrawType=2; 


void CGriphic3View::OnRectangle()  

    m_nDrawType=3; 

 void CGriphic3View::OnEllipse()  

    m_nDrawType=4; 
}

并在CGriphic3View类上添加成员变量:

public
    CObArray m_obArray;

接着在CGriphic3View类上添加OnLButtonDownOnLButtonUp消息响应函数,编辑:

void CGriphic3View::OnLButtonDown(UINT nFlags, CPoint point)  

m_ptOrigin=point; 
    CView::OnLButtonDown(nFlags, point); 

 
void CGriphic3View::OnLButtonUp(UINT nFlags, CPoint point)  

CClientDC dc(this); 
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
    //
创建透明画刷 
    dc.SelectObject(pBrush); 
     
    switch(m_nDrawType) 
    { 
    case 1
        dc.SetPixel(point,RGB(0,0,0)); 
        break
    case 2
        dc.MoveTo(m_ptOrigin); 
        dc.LineTo(point); 
        break
    case 3
        dc.Rectangle(CRect(m_ptOrigin,point)); 
        break
    case 4
        dc.Ellipse(CRect(m_ptOrigin,point)); 
        break
    } 
    CGraph *pGraph=new CGraph(m_nDrawType,m_ptOrigin,point); 
    m_obArray.Add(pGraph);//
使用集合类的对象 
    CView::OnLButtonUp(nFlags, point); 
}

5. 利用Serialize将图形元素保存到文件当中

先在Griphic3Doc.cpp文件中包含头文件:

#include "Griphic3View.h"//包含视类的头文件 
#include "Graph.h"
 

并在CGriphic3Doc::Serialize中编辑:

void CGriphic3Doc::Serialize(CArchive& ar) 

    POSITION pos=GetFirstViewPosition();//
获取第一个视类对象指针 
    CGriphic3View * pView=(CGriphic3View*)GetNextView(pos); 
    //
传递视类对象的地址值 
     if (ar.IsStoring()) 
    { 
        //
利用视类对象指针去访问它的成员变量 
        int nCount=pView->m_obArray.GetSize(); 
        ar<<nCount; 
        for(int i=0;i<nCount;i++) 
        { 
            ar<<pView->m_obArray.GetAt(i); 
        }
 
    } 
    else 
    { 
        int nCount; 
        ar>>nCount; 
        CGraph *pGraph; 
        for(int i=0;i<nCount;i++) 
        { 
            ar>>pGraph; 
            pView->m_obArray.Add(pGraph); 
        }
 
    } 
}

并在CGriphic3View::OnDraw中编辑:

void CGriphic3View::OnDraw(CDC* pDC) 

    CGriphic3Doc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
    // TODO: add draw code for native data here 
    int nCount; 
    nCount=m_obArray.GetSize(); 
    for(int i=0;i<nCount;i++) 
    { 
        ((CGraph*)m_obArray.GetAt(i))->Draw(pDC);//
依次画出集合对象中的图形 
    }
 
}

6.利用CObArray支持串行化

方式一:

利用CObArray支持串行化这一特性,来保存CObArray数组当中的所有元素,CGriphic3Doc::Serialize修改:

void CGriphic3Doc::Serialize(CArchive& ar) 

    POSITION pos=GetFirstViewPosition();//
获取第一个视类对象指针 
    CGriphic3View * pView=(CGriphic3View*)GetNextView(pos); 
    //
传递视类对象的地址值 
    if (ar.IsStoring()) 
    { 
    } 
    else 
    { 
    } 
    pView->m_obArray.Serialize(ar); 
}

方式二:

Doc文档类是来保存数据的,将CGriphic3View类中的成员变量CObArray m_obArray;放到CGriphic3Doc中去定义。在CGriphic3View::OnDraw编辑:

void CGriphic3View::OnDraw(CDC* pDC) 

    CGriphic3Doc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
    // TODO: add draw code for native data here 
    int nCount; 
    //nCount=m_obArray.GetSize(); 
    nCount=pDoc->m_obArray.GetSize(); 
    for(int i=0;i<nCount;i++) 
    { 
        //((CGraph*)m_obArray.GetAt(i))->Draw(pDC);//
依次画出集合对象中的图形 
        ((CGraph*)pDoc->m_obArray.GetAt(i))->Draw(pDC);//
依次画出集合对象中的图形 
    } 
}

CGriphic3View::OnLButtonUp修改:

void CGriphic3View::OnLButtonUp(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    ........ 
    ........ 
    //m_obArray.Add(pGraph);//
使用集合类的对象 
    CGriphic3Doc *pDoc=GetDocument(); 
    pDoc->m_obArray.Add(pGraph);
 
 
    CView::OnLButtonUp(nFlags, point); 
}

并在CGriphic3Doc::Serialize中修改:

void CGriphic3Doc::Serialize(CArchive& ar) 

    POSITION pos=GetFirstViewPosition();//
获取第一个视类对象指针 
    CGriphic3View * pView=(CGriphic3View*)GetNextView(pos); 
    //
传递视类对象的地址值 
 
    if (ar.IsStoring()) 
    { 
    } 
    else 
    { 
    } 
    //pView->m_obArray.Serialize(ar); 
    m_obArray.Serialize(ar);
 
}

7.Document/View结构:

CGriphic3Doc添加虚函数DeleteContents,编辑:

方式一

void CGriphic3Doc::DeleteContents()  

    // TODO: Add your specialized code here and/or call the base class 
    int nCount; 
    //nCount=m_obArray.GetSize(); 
    for(int i=0;i< m_obArray.GetSize();i++) 
    { 
        delete m_obArray.GetAt(i); 
        //
删除这个指针所指向的堆内存 
        m_obArray.RemoveAt(1);//
将这个索引位置的元素删除掉
 
    } 
    CDocument::DeleteContents(); 
}

方式二

void CGriphic3Doc::DeleteContents()  

    // TODO: Add your specialized code here and/or call the base class 
    int nCount; 
    nCount=m_obArray.GetSize(); 
    for(int i=0;i<nCount;i++) 
    { 
        delete m_obArray.GetAt(i); 
        //
删除这个指针所指向的堆内存 
        //m_obArray.RemoveAt(1);//
将这个索引位置的元素删除掉 
    } 
    m_obArray.RemoveAll();
 
    CDocument::DeleteContents(); 
}

方式三

void CGriphic3Doc::DeleteContents()  

    int nCount; 
    nCount=m_obArray.GetSize(); 
    while(nCount--) 
    { 
        delete m_obArray.GetAt(nCount); 
        m_obArray.RemoveAt(nCount); 
    } 
    CDocument::DeleteContents();
 

OK , ^_^

原文地址:https://www.cnblogs.com/luowei010101/p/2030818.html