新建一个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(
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类上添加OnLButtonDown和OnLButtonUp消息响应函数,编辑:
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 , ^_^