一 文件操作
1CFile类,--完成文件的找开和读写操作
2.CFileFind类--提供了文件查找功能。
这两个类,父类都是CObject.
3.CFile类的使用
2.1找开或者创建文件
CFile::Open
2.2数据读写
CFile::Read/Write注意读写操作的异常捕获
2.3文件的关闭
CFile::Close
2.4文件指针位置
CFile:Seek/SeekToEnd/SeekToBegin
Flush--强制将缓冲区数据写入到硬盘
2.6 LockRange/UnLockRange当多个程序同时操作同一文件时使用
2.7文件状态信息
GetStatus/SetStatus
3.CFileFind类
3.1 FindFile--开始查找
3.2 FindNextFile--查找下一个文件(得到第一个文件信息,返回下一个文件是否存在)
3.3 调用一系列的GetXXX和IsXXX函数获取和判断文件的信息
3.4 Close结束查找
//////////////////////////////
控制台程序《支持MFC》
CWinApp theApp;
void CFileExample(){
CFile file;
//打开或者新建文件
BOOL bRet=file.Open("c:\\mfcfile.txt",CFile::modeCreate|CFile::modeReadWrite);
if(!bRet) return;
//文件的读写操作
try{
file.Write("Hello CFile",11);
//移动文件指针到文件的开始位置
file.SeekToBegin();
char szText[100]={0};
file.Read(szText,100);
printf("%s\n",szText);
}
catch(CFileException* e){
//具体的异常处理
}
//文件关闭
file.Close();
}
////////////修改文件状态信息
CFileStatus status;
CFile::GetStatus("c:\\mfcfile.txt",status);
CTimeSpan span(366,0,0,0);
status.m_ctime-=span;
CFile::SetStatus("c:\\mfcfile.txt",status);
//////////////////////////////
二 MFC序列化
1.序列化概念
采用数据流的方式,将数据依次写入/读取文件,是二进制的存储方式。
2.序列化相关类
2.1CFile--文件类
2.2CArchive--归档类,封装了序列化的操作(完成数据的具体读写操作)
2.3CObject类(与对象的序列化相关的)
3.序列化的使用
3.1 打开或者创建文件
3.2 定义CArchive对象
3.3 进行具体的数据读写
写,存储, <<
读,加载, >>
3.4关闭CArchive对象
3.5关闭文件
//数据存储
void Store(){
CFile file;
BOOL bRet=file.Open("c:\\serial.dat",CFile::modeCreate|cfile::modeWrite);
if(!bRet){return;}
CArchive ar(&file,CArchive::store);//与modeWrite保持一致
ar<<100;
float fValue=12.25;
ar<<fValue;
CString strValue="Hello CArchive";
ar<<strValue;
ar.Close();
file.Close();
}
//数据读出
void Load(){
CFile file;
file.Open("c:\\serial.dat",CFile::modeRead);
CArchive ar(&file,CArchive::load);
int nNum=0;
ar>>nNum;
float fNum=0.0;
ar>>fNum;
CString strValue;
ar>>strValue;
ar.Close();
file.Close();
//输入读到的数据
printf("%d\n",nNum);
printf("%.xf\n",fNum);
printf("%s\n",strValue);
}
4.CArchive类
CArchive中定义了缓存,目的减少硬盘的读写次数
class CArchive{
CFile* m_pFile;//关联的文件对象
int m_nBufSize;//缓存的大小
BYTE* m_lpBufCur;//当前指针位置
BYTE* m_lpBufMax;//终止指针位置
BYTE* m_lpBufStart;//起始指针位置
};
4.1 数据写入的执行过程(存储)
4.1.1 判断在Buff中,是否有足够的空间存储数据
m_lpBufCur+sizeof(数据)>m_lpBufMax
4.1.2 如果空间不够,首先将Buff中已有的数据写入文件(Flush)
重置m_lpBufCur到Buff的起始位置
4.1.3如果空间足够,将数据写入m_lpBufCur执行的地址
4.1.4将m_lpBufCur向后偏移写入的字节数
写入到最后,ar.Close()调用Flush
4.2数据读取的执行过程(加载)
4.2.1 判断在Buff中剩余的空间是否满足读取数据的大小。
5.对象的序列化
序列化对象--将对象的类的信息和对象的数据保存到文件
反序列化对象--根据读取的类的信息,创建对象,并将对象的数据读取。
条件:至少是具有运行类信息功能。还具有动态创建对象。
class CStudent
{
CString strName;
UINT m_nAge;
}
CStudent sta1("张三",18);
5.1 定义一个支持序列化的类
5.1.1必须是CObject类的子类
5.1.2添加序列化的声明宏和实现宏
5.1.3要重写CObject类函数Serialize
//////////////////////////////
//定义支持序列化的类
class CStudent:public CObject
{
public:
CStudent();
CStudent(CString name,UINT age);
void Show();
//声明宏
DECLARE_SERIAL(CStudent)
virtual void Serialize(CArchive& ar);
public:
CString m_strName;
UINT m_nAge;
}
//实现宏
IMPLEMENT_SERIAL(CStudent,CObject,1);
CStudent::CStudent(){};
CStudent::CStudent(CString name,UINT age){
m_strName=name;
m_nAge=age;
}
void CStudent::Show(){
printf("姓名:%s\n",m_strName);
printf("年龄:%d\n",m_nAge);
}
//重写Serialize函数
void CStudent::Serialize(CArchive& ar){
if(ar.IsStoring()){
ar<<m_strName<<m_nAge;
}
else
{
arr>>m_strName>>m_nAge;
}
}
//实验存储
void ObjStore(CStudent & stu)
{
CFile file;
file.Open("c:\\stu.dat",CFile::modeCreate|CFile::modeWrite);
CArchive ar(&file,CArchive::store);
ar<<&stu;
ar.Close();
file.Close();
}
//实验加载
void ObjLoad()
{
CFile file;
file.Open("c:\\stu.dat",CFile::modeRead);
CArchive ar(&file,CArchive::load);
CStudent *pStu=NULL;
ar>>pStu;
ar.Close();
file.Close();
if(pStu){
pStu->Show();
}
}
/////////////////////////////
5.2宏替换后的代码
init_CStudent--将CStudent类的运行时类信息的地址保存到应用程序的m_classList链表中
mperator>>--创建类的对象并读取对象的成员变量数据
5.3序列化对象的过程
获取对象的运行时类信息
将类的名称,版本等信息写入到文件
调用对象Serialize函数
在函数中,保存对象的成员变量的数据
WriteObject->WriteClaps->Store->Serialize
5.4反序列化对象的过程
从文件中读取类的名称和版本号等信息
根据读取到的类名称,在m_classList链表中查找该类所对应的运行时类信息
使用查询到的运行时类信息创建对象
调用对象的Serialize函数
在函数中,读取变量的数据
ReadObject->ReadClass->Load->CreateObject->Serialize
1 对象的序列化(反序列化)
1.1 对象的序列化的使用
1.1.1 定义支持序列化的类
1)是CObject的子孙类
2)添加支持序列化的宏
DECLARE_SERIAL
IMPLEMENT_SERIAL
3)要重写函数Serialize
virtual void Serialize( CArchive& ar );
1.1.2 创建文件
1.1.3 定义CArchive
1.1.4 存储对象
1.1.5 关闭CArchive
1.1.6 关闭文件
1.2 序列化的实现
1.2.1 宏代码
class CAnimal : public CObject
{
_DECLARE_DYNCREATE( CAnimal )
AFX_API friend CArchive& AFXAPI
operator>>(CArchive& ar, CAnimal * &pOb);
}
CObject* PASCAL CAnimal::CreateObject()
{
return new CAnimal;
}
_IMPLEMENT_RUNTIMECLASS( CAnimal, CObject, 0,
CAnimal::CreateObject )
AFX_CLASSINIT _init_CAnimal( RUNTIME_CLASS(CAnimal) );
CArchive& AFXAPI operator>>(CArchive& ar, CAnimal* &pOb)
{
pOb = (CAnimal*)
ar.ReadObject(RUNTIME_CLASS(CAnimal));
return ar;
}
1.2.2 说明
1)_DECLARE_DYNCREATE 动态创建类
2)operator>> 读入操作符,读取对象
数据。不是CAnimal类的成员函数,
是一个CAnimal类的友员全局函数。
3) AFX_CLASSINIT _init_CAnimal
全局变量,在程序启动的时候被创建。
将CAnimal类RUNTIMECLASS信息
注册到程序中(保存到数据链表).
1.2.3 执行过程
初始化:
1) _init_CAnimal变量初始化,在构造
函数中,将类的CRuntimeClass地址
保存到程序AFX_MODULE_STATE的
全局变量中,使用m_classList保存
这个地址.
写入数据:
2) 使用"<<"写入对象数据,内部调用
CArchive的WriteObject函数.
3) 在WriteObject函数,将该对象的
CRuntimeClass信息中的版本号/
类名称写入到文件.
4) 调用对象的Serialize,保存对象
内的相关数据.
读取数据:
5) 使用">>"读取对象数据,实际调用
的是该类的友员函数
(即在序列化宏中定义操作符).
6) 在">>"操作符中调用CArchive的
ReadObject函数读取对象.
7) 在ReadObject中从文件中读取
版本号和类名称
8) 根据读取的类名称,从m_classList
中,查找相应的CRuntimeClass的地址
9) 获取到CRuntimeClass地址,使用
CRuntimeClass的CreateObject函数
创建该类的对象.
10) 调用对象的Serialize函数,从
CArchive中读取对象内的数据.
1.3 类的Schema(版本)
1.3.1 通过IMPLEMENT_SERIAL宏
的第3个参数Schema来控制类的版本
1.3.2 定义版本时,需要增加
VERSIONABLE_SCHEMA
例如:
IMPLEMENT_SERIAL( CAnimal, CObject, VERSIONABLE_SCHEMA|1 )
1.3.3 读取数据时,要增加版本
判断处理
CArachive::GetObjectSchema获取
当前对象的版本号.
二 MFC对话框
1 MFC对话框
1.1 有模式对话框
1.2 无模式对话框
2 MFC APP对话框的使用
2.1 对话框窗口
2.2 应用程序主窗口
3 有模式对话框的使用
3.1 使用
3.1.1 定义对话框资源
3.1.2 定义对话框类
基于CDialog父类生成子类,将对话框
的资源ID通过构造函数传递给CDialog
3.1.3 显示对话框
int CDialog::DoModal()
3.1.4 WM_INITDIALOG映射为OnInitDialog
在这个函数中完成对话框数据的初始化
3.1.5 消息映射
使用消息映射宏完成消息处理
3.1.6 对话框的关闭
CDialog::OnOK - 确定的方式关闭,
DoModal函数返回IDOK
CDialog::OnCancel - 取消的方式关闭,
DoModal函数返回IDCANCEL
CDialog::EndDialog - 关闭并指定
返回值
3.2 DoModal执行
3.2.1 查找对话框资源
3.2.2 将父窗口设置成禁止输入状态
3.2.3 创建对话框窗口
3.2.4 调用消息循环,等候对话框关闭
执行3.2.5
3.2.5 将自己的窗口隐藏
3.2.6 将父窗口设置激活窗口
3.2.7 删除对话框窗口
3.2.8 返回对话框结束参数
4 无模式对话框
4.1 使用
4.1.1 定义对话框资源
4.1.2 定义对话框类
基于CDialog父类生成子类
4.1.3 创建对话框
CDialog::Create创建对话框
4.1.4 显示对话框
CDialog::ShowWindow显示
4.1.5 对话框的关闭
需要手动添加DestoryWindow函数
可以在OnOK/OnCancel当中
4.2 执行
4.2.1 查找资源
4.2.2 创建窗口
1CFile类,--完成文件的找开和读写操作
2.CFileFind类--提供了文件查找功能。
这两个类,父类都是CObject.
3.CFile类的使用
2.1找开或者创建文件
CFile::Open
2.2数据读写
CFile::Read/Write注意读写操作的异常捕获
2.3文件的关闭
CFile::Close
2.4文件指针位置
CFile:Seek/SeekToEnd/SeekToBegin
Flush--强制将缓冲区数据写入到硬盘
2.6 LockRange/UnLockRange当多个程序同时操作同一文件时使用
2.7文件状态信息
GetStatus/SetStatus
3.CFileFind类
3.1 FindFile--开始查找
3.2 FindNextFile--查找下一个文件(得到第一个文件信息,返回下一个文件是否存在)
3.3 调用一系列的GetXXX和IsXXX函数获取和判断文件的信息
3.4 Close结束查找
//////////////////////////////
控制台程序《支持MFC》
CWinApp theApp;
void CFileExample(){
CFile file;
//打开或者新建文件
BOOL bRet=file.Open("c:\\mfcfile.txt",CFile::modeCreate|CFile::modeReadWrite);
if(!bRet) return;
//文件的读写操作
try{
file.Write("Hello CFile",11);
//移动文件指针到文件的开始位置
file.SeekToBegin();
char szText[100]={0};
file.Read(szText,100);
printf("%s\n",szText);
}
catch(CFileException* e){
//具体的异常处理
}
//文件关闭
file.Close();
}
////////////修改文件状态信息
CFileStatus status;
CFile::GetStatus("c:\\mfcfile.txt",status);
CTimeSpan span(366,0,0,0);
status.m_ctime-=span;
CFile::SetStatus("c:\\mfcfile.txt",status);
//////////////////////////////
二 MFC序列化
1.序列化概念
采用数据流的方式,将数据依次写入/读取文件,是二进制的存储方式。
2.序列化相关类
2.1CFile--文件类
2.2CArchive--归档类,封装了序列化的操作(完成数据的具体读写操作)
2.3CObject类(与对象的序列化相关的)
3.序列化的使用
3.1 打开或者创建文件
3.2 定义CArchive对象
3.3 进行具体的数据读写
写,存储, <<
读,加载, >>
3.4关闭CArchive对象
3.5关闭文件
//数据存储
void Store(){
CFile file;
BOOL bRet=file.Open("c:\\serial.dat",CFile::modeCreate|cfile::modeWrite);
if(!bRet){return;}
CArchive ar(&file,CArchive::store);//与modeWrite保持一致
ar<<100;
float fValue=12.25;
ar<<fValue;
CString strValue="Hello CArchive";
ar<<strValue;
ar.Close();
file.Close();
}
//数据读出
void Load(){
CFile file;
file.Open("c:\\serial.dat",CFile::modeRead);
CArchive ar(&file,CArchive::load);
int nNum=0;
ar>>nNum;
float fNum=0.0;
ar>>fNum;
CString strValue;
ar>>strValue;
ar.Close();
file.Close();
//输入读到的数据
printf("%d\n",nNum);
printf("%.xf\n",fNum);
printf("%s\n",strValue);
}
4.CArchive类
CArchive中定义了缓存,目的减少硬盘的读写次数
class CArchive{
CFile* m_pFile;//关联的文件对象
int m_nBufSize;//缓存的大小
BYTE* m_lpBufCur;//当前指针位置
BYTE* m_lpBufMax;//终止指针位置
BYTE* m_lpBufStart;//起始指针位置
};
4.1 数据写入的执行过程(存储)
4.1.1 判断在Buff中,是否有足够的空间存储数据
m_lpBufCur+sizeof(数据)>m_lpBufMax
4.1.2 如果空间不够,首先将Buff中已有的数据写入文件(Flush)
重置m_lpBufCur到Buff的起始位置
4.1.3如果空间足够,将数据写入m_lpBufCur执行的地址
4.1.4将m_lpBufCur向后偏移写入的字节数
写入到最后,ar.Close()调用Flush
4.2数据读取的执行过程(加载)
4.2.1 判断在Buff中剩余的空间是否满足读取数据的大小。
5.对象的序列化
序列化对象--将对象的类的信息和对象的数据保存到文件
反序列化对象--根据读取的类的信息,创建对象,并将对象的数据读取。
条件:至少是具有运行类信息功能。还具有动态创建对象。
class CStudent
{
CString strName;
UINT m_nAge;
}
CStudent sta1("张三",18);
5.1 定义一个支持序列化的类
5.1.1必须是CObject类的子类
5.1.2添加序列化的声明宏和实现宏
5.1.3要重写CObject类函数Serialize
//////////////////////////////
//定义支持序列化的类
class CStudent:public CObject
{
public:
CStudent();
CStudent(CString name,UINT age);
void Show();
//声明宏
DECLARE_SERIAL(CStudent)
virtual void Serialize(CArchive& ar);
public:
CString m_strName;
UINT m_nAge;
}
//实现宏
IMPLEMENT_SERIAL(CStudent,CObject,1);
CStudent::CStudent(){};
CStudent::CStudent(CString name,UINT age){
m_strName=name;
m_nAge=age;
}
void CStudent::Show(){
printf("姓名:%s\n",m_strName);
printf("年龄:%d\n",m_nAge);
}
//重写Serialize函数
void CStudent::Serialize(CArchive& ar){
if(ar.IsStoring()){
ar<<m_strName<<m_nAge;
}
else
{
arr>>m_strName>>m_nAge;
}
}
//实验存储
void ObjStore(CStudent & stu)
{
CFile file;
file.Open("c:\\stu.dat",CFile::modeCreate|CFile::modeWrite);
CArchive ar(&file,CArchive::store);
ar<<&stu;
ar.Close();
file.Close();
}
//实验加载
void ObjLoad()
{
CFile file;
file.Open("c:\\stu.dat",CFile::modeRead);
CArchive ar(&file,CArchive::load);
CStudent *pStu=NULL;
ar>>pStu;
ar.Close();
file.Close();
if(pStu){
pStu->Show();
}
}
/////////////////////////////
5.2宏替换后的代码
init_CStudent--将CStudent类的运行时类信息的地址保存到应用程序的m_classList链表中
mperator>>--创建类的对象并读取对象的成员变量数据
5.3序列化对象的过程
获取对象的运行时类信息
将类的名称,版本等信息写入到文件
调用对象Serialize函数
在函数中,保存对象的成员变量的数据
WriteObject->WriteClaps->Store->Serialize
5.4反序列化对象的过程
从文件中读取类的名称和版本号等信息
根据读取到的类名称,在m_classList链表中查找该类所对应的运行时类信息
使用查询到的运行时类信息创建对象
调用对象的Serialize函数
在函数中,读取变量的数据
ReadObject->ReadClass->Load->CreateObject->Serialize
1 对象的序列化(反序列化)
1.1 对象的序列化的使用
1.1.1 定义支持序列化的类
1)是CObject的子孙类
2)添加支持序列化的宏
DECLARE_SERIAL
IMPLEMENT_SERIAL
3)要重写函数Serialize
virtual void Serialize( CArchive& ar );
1.1.2 创建文件
1.1.3 定义CArchive
1.1.4 存储对象
1.1.5 关闭CArchive
1.1.6 关闭文件
1.2 序列化的实现
1.2.1 宏代码
class CAnimal : public CObject
{
_DECLARE_DYNCREATE( CAnimal )
AFX_API friend CArchive& AFXAPI
operator>>(CArchive& ar, CAnimal * &pOb);
}
CObject* PASCAL CAnimal::CreateObject()
{
return new CAnimal;
}
_IMPLEMENT_RUNTIMECLASS( CAnimal, CObject, 0,
CAnimal::CreateObject )
AFX_CLASSINIT _init_CAnimal( RUNTIME_CLASS(CAnimal) );
CArchive& AFXAPI operator>>(CArchive& ar, CAnimal* &pOb)
{
pOb = (CAnimal*)
ar.ReadObject(RUNTIME_CLASS(CAnimal));
return ar;
}
1.2.2 说明
1)_DECLARE_DYNCREATE 动态创建类
2)operator>> 读入操作符,读取对象
数据。不是CAnimal类的成员函数,
是一个CAnimal类的友员全局函数。
3) AFX_CLASSINIT _init_CAnimal
全局变量,在程序启动的时候被创建。
将CAnimal类RUNTIMECLASS信息
注册到程序中(保存到数据链表).
1.2.3 执行过程
初始化:
1) _init_CAnimal变量初始化,在构造
函数中,将类的CRuntimeClass地址
保存到程序AFX_MODULE_STATE的
全局变量中,使用m_classList保存
这个地址.
写入数据:
2) 使用"<<"写入对象数据,内部调用
CArchive的WriteObject函数.
3) 在WriteObject函数,将该对象的
CRuntimeClass信息中的版本号/
类名称写入到文件.
4) 调用对象的Serialize,保存对象
内的相关数据.
读取数据:
5) 使用">>"读取对象数据,实际调用
的是该类的友员函数
(即在序列化宏中定义操作符).
6) 在">>"操作符中调用CArchive的
ReadObject函数读取对象.
7) 在ReadObject中从文件中读取
版本号和类名称
8) 根据读取的类名称,从m_classList
中,查找相应的CRuntimeClass的地址
9) 获取到CRuntimeClass地址,使用
CRuntimeClass的CreateObject函数
创建该类的对象.
10) 调用对象的Serialize函数,从
CArchive中读取对象内的数据.
1.3 类的Schema(版本)
1.3.1 通过IMPLEMENT_SERIAL宏
的第3个参数Schema来控制类的版本
1.3.2 定义版本时,需要增加
VERSIONABLE_SCHEMA
例如:
IMPLEMENT_SERIAL( CAnimal, CObject, VERSIONABLE_SCHEMA|1 )
1.3.3 读取数据时,要增加版本
判断处理
CArachive::GetObjectSchema获取
当前对象的版本号.
二 MFC对话框
1 MFC对话框
1.1 有模式对话框
1.2 无模式对话框
2 MFC APP对话框的使用
2.1 对话框窗口
2.2 应用程序主窗口
3 有模式对话框的使用
3.1 使用
3.1.1 定义对话框资源
3.1.2 定义对话框类
基于CDialog父类生成子类,将对话框
的资源ID通过构造函数传递给CDialog
3.1.3 显示对话框
int CDialog::DoModal()
3.1.4 WM_INITDIALOG映射为OnInitDialog
在这个函数中完成对话框数据的初始化
3.1.5 消息映射
使用消息映射宏完成消息处理
3.1.6 对话框的关闭
CDialog::OnOK - 确定的方式关闭,
DoModal函数返回IDOK
CDialog::OnCancel - 取消的方式关闭,
DoModal函数返回IDCANCEL
CDialog::EndDialog - 关闭并指定
返回值
3.2 DoModal执行
3.2.1 查找对话框资源
3.2.2 将父窗口设置成禁止输入状态
3.2.3 创建对话框窗口
3.2.4 调用消息循环,等候对话框关闭
执行3.2.5
3.2.5 将自己的窗口隐藏
3.2.6 将父窗口设置激活窗口
3.2.7 删除对话框窗口
3.2.8 返回对话框结束参数
4 无模式对话框
4.1 使用
4.1.1 定义对话框资源
4.1.2 定义对话框类
基于CDialog父类生成子类
4.1.3 创建对话框
CDialog::Create创建对话框
4.1.4 显示对话框
CDialog::ShowWindow显示
4.1.5 对话框的关闭
需要手动添加DestoryWindow函数
可以在OnOK/OnCancel当中
4.2 执行
4.2.1 查找资源
4.2.2 创建窗口