文檔與串行化

新建一個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<//
將數據插入到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.< 
    } 
    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<    } 
    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<        for(int i=0;i        { 
            ar<m_obArray.GetAt(i); 
        }
 
    } 
    else 
    { 
        int nCount; 
        ar>>nCount; 
        CGraph *pGraph; 
        for(int i=0;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    { 
        ((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    { 
        //((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    { 
        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 , ^_^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章