学习笔记MFC文件 MFC对话框1.docx
《学习笔记MFC文件 MFC对话框1.docx》由会员分享,可在线阅读,更多相关《学习笔记MFC文件 MFC对话框1.docx(18页珍藏版)》请在冰豆网上搜索。
学习笔记MFC文件MFC对话框1
MFC文件
1MFC文件相关
CFile-父类是CObject,封装了文件操作的API,提供了创建,数据读写等操作。
CFileFind-文件查找
2CFile的使用
2.1打开或者创建文件的时候,注意设置打开模式。
(CFile:
:
Open)【1】
virtualBOOLOpen(LPCTSTRlpszFileName,//文件的路径
UINTnOpenFlags,//打开模式
CFileException*pError=NULL);//指向一个存在的文件异
常对象,获取失败操作的状态。
返回值:
成功打开,则返回非零值,否则为0。
pError参数仅在返回0时才有意义。
2.2数据读写,注意读写才做的异常捕获。
【2】
virtualvoidWrite(constvoid*lpBuf//写入的数据或者缓冲区地址
UINTnCount//写入的数据字节数);
virtualUINTRead(void*lpBuf,//接受文件中数据的缓冲区地址
UINTnCount);//读取的字节。
返回值:
传输到缓冲区的字节数
2.3文件的关闭【3】CFile:
:
Close
2.4文件指针操作SeekToBegin/SeekToEnd【4】
2.5Flush-强制缓冲区的数据写入硬盘
读写的时候,不会直接写到目的地,为了提高效率,引入缓冲区,缓冲区满了,再写入目的低。
当缓冲区还没有写满就结束时,调用Flush使缓冲区的数据刷新到目的地。
2.6LockRange/UnLockRange
当多个程序同时操作一个文件时,可以锁定指定位置和字节数量的文件区域,这个区域的数据其他程序是不能修改的,直到解锁解锁后才能区修改
2.7GetStatus/SetStatus【5】设置或获取文件状态信息
//获取文件的状态信息(文件路径,放入的状态结构)
staticBOOLPASCALGetStatus(LPCSTRlpszFileName,CFileStatus&rStatus);
3CFileFind
文件查找
3.1FindFile开始查找
3.2FindNextFile查找下一个,依次遍历查找结果
3.3Close关闭查找请求
例:
voidMyFile()
{
CFilefile;【1】
BOOLbRet=file.Open("E:
\\huai.txt",CFile:
:
modeCreate|CFile:
:
modeReadWrite);
if(!
bRet)
{
return;
}
//项目时应在异常处理中执行操作【2】
try
{
file.Write("helloworld",10);
file.SeekToBegin();【4】
CHARszText[256]={0};
file.Read(szText,256);
printf("%s\n",szText);
}
catch(CException*)
{
//异常处理
}
file.Close();【3】
}
//获得或者设置文件的信息【5】
voidMyFileStatus()
{
CFileStatusstatus;
CFile:
:
GetStatus("E:
\\huai.txt",status);
//定义一个时间段
CTimeSpanspan(365,0,0,0);★
status.m_mtime+=span;
CFile:
:
GetStatus("E:
\\huai.txt",status);
}
voidMyFileFind(CStringstrPath)
{
CFileFindfind;
//判断当前文件下是否有文件
BOOLbRet=find.FindFile(strPath+"*.*");
while(bRet)
{
//只有调用FindNextFile才能获取文件信息(执行它下面的才起作用)★
bRet=find.FindNextFile();
CStringstrName=find.GetFileName();
strPath=find.GetFilePath();
if(find.IsDirectory()&&!
find.IsDots())
{
printf("目录:
%s\n",strName);
//接着再查找
MyFileFind(strPath+"\\*.*");
}
else
{
printf("文件:
%s\n",strName);
}
}
find.Close();
}
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[])
{
//MyFile();
//MyFileStatus();
MyFileFind("C:
\\");
return0;
}
文件序列化
1序列化
采用数据流的方式,将数据依次写入或者读取文件,是二进制的存储方式(.dat)。
2序列化相关
CFile文件类
CArchive归档类,封装了序列化的具体操作
CObject
//完成数据读写
virtualvoidSerialize(CArchive&ar);
//判断某个对象是否支持序列化
BOOLIsSerializable()const;
3序列化的使用
3.1新建或者打开文件
CFile:
:
Open(文件的路径,文件的打开方式)
3.2定义CArchive对象
3.3使用CArchive对象存储或者加载数据-----(注意存储和加载的数据的顺序要一致)
CArchivear(&file,CArchive:
:
store);
存储"<<"
CArchivear(&file,CArchive:
:
load);
读取">>"
3.4关闭CArchive对象CArchive:
:
Close()
3.5关闭文件
CFile:
:
Close()
CArchive:
:
Close()
4CArchive类
4.1数据结构
CArchive定义缓存,缓存的长度由m_nBufSize,减少读写硬盘的次数
classCArchive
{
..........
BOOLm_nMode;
BOOLm_bUserBuf;//
intm_nBufSize;//缓存的长度
CFile*m_pFile;//关联文件的地址
BYTE*m_lpBufCur;//当前指针位置
BYTE*m_lpBufMax;//终止指针位置
BYTE*m_lpBufStart;//起始指针位置
...........
};
★4.2执行过程数据存储、写入(内存-缓冲区-文件)
4.2.1判断在Buffer当中是否有足够的空间存储数据
4.2.2如果空间不够,将Buffer中已有的数据写入文件,重置m_lpBufCur为Buffer的起始位置
4.2.3将内存数据拷贝到m_lpBufCur的地址
4.2.4将m_lpBufCur向后偏移写入的字节数
写到最后ar.Close(),自动调用Flush(),把缓冲区中剩余的数据写入文件
★4.3数据的读出(加载),(文件-缓冲区-内存)
4.3.1首先判断剩余的Buffer是否满足读取数据的大小
4.3.2如果不满足,调用FillBuffer()函数,并将需要的字节数传入
Cur+4>max
|
|----------------------------AAA|
4.3.2.1将Buffer中没有使用的字节数拷贝到Buffer的起始位置
Cur
|
|AAA---------------------------|
4.3.2.2从文件中读取Buffer剩余空间长度的数据,这样前面的半个数据变完整了,再次循环
Cur
|
|AAAABBCDDDD-------------------|
4.3.2.3数据块读完了,不到Max的值,根据实际读出文件的数据长度设置Max的地址
4.3.3将数据从m_lpBufCur位置的Buffer中取出放到变量中
4.3.4将m_lpBufferCur向后偏移读出的字节数
例:
CWinApptheApp;
usingnamespacestd;
//数据的写入
voidMyStore()
{
CFilefile;
BOOLbRet=file.Open("C:
\\huai.dat",CFile:
:
modeReadWrite|CFile:
:
modeCreate);
if(!
bRet)
{
return;
}
CArchivear(&file,CArchive:
:
store);//写入文件(2进制保存)★
ar<<100;
doubled=12.25;
ar<ar.Close();
file.Close();
}
//数据的读取
voidMyLoad()
{
CFilefile;
BOOLbRet=file.Open("C:
\\huai.dat",CFile:
:
modeReadWrite);
if(!
bRet)
{
return;
}
CArchivear(&file,CArchive:
:
load);//从文件到内存★
inta=0;
ar>>a;
printf("%d\n",a);
doubled1=0.0;
ar>>d1;
printf("%f\n",d1);
ar.Close();
file.Close();
}
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[])
{
MyStore();
MyLoad();
return0;
}
5对象的序列化
序列化的基本思想是:
一个类应该能够对自己的成员变量的数据进行读写操作,对象可以通过读操作而重新创建。
即对象可以将其当前状态(由其成员变量的值表示)写入永久性存储体(通常指磁盘)中,以后可以从永久性存储体中读取(载入)对象的状态,从而重建对象。
类的对象自己应该具备将状态值写入磁盘或从磁盘中读出的方法(即成员函数),这种对象的保存和恢复过程称为序列化。
★序列化对象-将对象的类的信息,对象中的数据保存到文件
★反序列化对象-根据读取的类的信息,创建对象,然后将对象中的数据读入
好处是,类对象可以改变改变(增加成员变量,成员函数),但是序列化的两个函数不用重写,只需把前面重载的函数重写
5.1使用
5.1.1定义支持序列化的类
1CObject类的子类
2重写CObject类的Serialize函数
3在类定义中添加宏,DECLARE_SERIAL(类名称)
4在类的实现中增加宏,IMPLEMENT_SERIAL(类名称,父类名称,)
5.1.2打开或者新建文件
5.1.3定义CArchive对象
5.1.4将类的对象保存或者读取
5.1.5关闭CArchive对象
5.1.6关闭文件
5.2代码
5.3operator>>创建对象并读取数据
_init_Student将类的运行时类信息保存到模块中的m_classList的链表中
5.4对象序列化(存入文件)
5.4.1获取对象的运行时类信息
5.4.2将类的版本和名称写入到CArchive对象(写入到该类CRuntimeClass结构中)
5.4.3调用对象的Serialize函数
5.4.4在函数中保存该对象自己的数据
5.5对象的反序列化(从文件读取,动态创建对象)
5.5.1从文件中读取类的名称
5.5.2根据类的名称,从m_classList链表中查询该类对应的运行时类信息地址
5.5.3使用查询到的运行时类信息创建对象
5.5.4调用对象的Serialize函数
例:
CWinApptheApp;
usingnamespacestd;
//自定义类(序列化保存他)
classStudent:
publicCObject
{
public:
//★DECLARE_SERIAL(Student)//序列化基于动态创建★
//宏展开
_DECLARE_DYNCREATE(Student)
AFX_APIfriendCArchive&AFXAPIoperator>>(CArchive&ar,Student*&pOb);
virtualvoidSerialize(CArchive&ar);
CStringm_strName;
intm_nAge;
Student(CStringname="",intage=20):
m_strName(name),m_nAge(age){};
voidShow();
};
//IMPLEMENT_SERIAL(Student,CObject,1)
//宏展开
CObject*PASCALStudent:
:
CreateObject()
{returnnewStudent;}
//运行时类信息
_IMPLEMENT_RUNTIMECLASS(Student,CObject,1,
Student:
:
CreateObject)
AFX_CLASSINIT_init_Student(RUNTIME_CLASS(Student));
CArchive&AFXAPIoperator>>(CArchive&ar,Student*&pOb)
{pOb=(Student*)ar.ReadObject(RUNTIME_CLASS(Student));
returnar;}
voidStudent:
:
Show()
{
printf("学生信息:
name:
%sage:
%d\n",m_strName,m_nAge);
}
//重写CObject类的Serialize函数(相当于运算符重载)★
voidStudent:
:
Serialize(CArchive&ar)
{
if(ar.IsStoring())//确定是否正在存储归档文件。
这个函数由归档文件类的Serialize函数调用
{
ar<}
else
{
ar>>m_strName>>m_nAge;
}
}
//将类对象保存进文件
voidMyobjStore(Student&stu)
{
CFilefile;
file.Open("C:
\\huaishuo.dat",CFile:
:
modeCreate|CFile:
:
modeWrite);
CArchivear(&file,CArchive:
:
store);
ar<<&stu;
ar.Close();
file.Close();
}
//从文件到内存,动态创建出对象
voidMyObjLoad()
{
CFilefile;
file.Open("C:
\\huaishuo.dat",CFile:
:
modeRead);
CArchivear(&file,CArchive:
:
load);
Student*pStu=NULL;
ar>>pStu;
pStu->Show();
ar.Close();
file.Close();
}
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[])
{
Studentstu("张三",18);
MyobjStore(stu);
MyObjLoad();
return0;
}
MFC对话框
1对话框的分类
模式无模式
2对话框相关的类
CDialog类-父类CWnd
CCommonDialog类-通用对话框类,父类是CDialog
CPropertyPage---属性页,父类是CDialog
结合CPropertySheet(属性表单)类使用
3在Win32应用程序中使用MFC类构建基于对话框的应用程序
3.1资源模板和类定义
通过构造函数将资源模板的ID赋值给父类CDialog【1】
3.2调用CDialog的DoModal函数,显示对话框【2】
3.3调用CDialog的OnOk或者OnCancel关闭对话框【3】
3.4重写OnInitDialog函数完成对话框的初始化相关操作【4】
例:
#include"stdafx.h"
#include"resource.h"
//应用程序类
classCDialogApp:
publicCWinApp{
public:
virtualBOOLInitInstance();
};
//对话框类
classCMyDialog:
publicCDialog
{
DECLARE_MESSAGE_MAP()
public:
CMyDialog();
//对话框创建后默认调用
virtualBOOLOnInitDialog();
afx_msgvoidOnMyOK();
afx_msgvoidOnMyCancel();
};
BEGIN_MESSAGE_MAP(CMyDialog,CDialog)
ON_COMMAND(IDOK,OnMyOK)
ON_COMMAND(IDCANCEL,OnMyCancel)
END_MESSAGE_MAP()
//OK消息处理函数【3】
voidCMyDialog:
:
OnMyOK()
{
MessageBox("点击了OK");
OnOK();//对话框自带的OK处理函数,在此调用它
}
//Cancel消息处理函数【3】
voidCMyDialog:
:
OnMyCancel()
{
MessageBox("点击了Cancel");
OnCancel();
}
//构造函数【1】
CMyDialog:
:
CMyDialog():
CDialog(IDD_DIALOG1){};
BOOLCMyDialog:
:
OnInitDialog()
{
MessageBox("对话框的初始化!
");
returnTRUE;
}
CDialogApptheApp;
BOOLCDialogApp:
:
InitInstance(){【4】
CMyDialog*Frame=newCMyDialog;
m_pMainWnd=Frame;
Frame->DoModal();//对话框的创建和显示【2】
returnTRUE;
}
4MFC向导创建模式对话框:
4.1在菜单中添加选项
4.2在资源中添加对话框资源
4.3双击对话框,调出添加类菜单,添加对话框类
4.4Ctrl+W在主框架中添加菜单消息处理函数,在函数中创建对话框
CMyDialogdlg;
dlg.DoModal();
4.5创建和显示模式对话框DoModal()函数
4.5.2.1查找对话框资源
4.5.2.2将主窗体设置为非激活窗口
4.5.2.3创建对话框
4.5.2.4执行对话框的消息循环
4.5.2.5退出后隐藏对话框窗口
4.5.2.6将主窗口设置为活动窗口
4.5.2.7销毁对话框窗口
4.5.2.8返回DoModal函数的执行结果
5Wnd32下创建非模式对话框
5.1资源模板和类定义
通过构造函数将资源模板的ID赋值给CDialog【1】
5.2创建和显示对话框
5.2.1查找对话框资源
5.2.2创建对话框(CDialog:
:
Create)【2】
5.3关闭--(EndDialog并不能真正的关闭对话框,只是隐藏)【3】
解决方法:
重写OnOk或者OnCancel加入DistoryWindow()销毁对话框
例:
//对话框类
classCMyDlg:
publicCDialog
{
public:
CMyDlg();
virtualBOOLOnMyOk();
};
//对话框构造函数
CMyDlg:
:
CMyDlg():
CDialog(IDD_DIALOG1)【1】
{
}
//重写OK按钮函数,使可以被真正销毁【3】
BOOlCMyDlg:
:
OnMyOk()
{
OnOk();//不能真正被销毁,只是隐藏
DestroyWindow();
}
//应用程序类
classCDlgApp:
publicCWinApp
{
public:
virtualBOOLInitInstance();
protected:
private:
};
CDlgApptheApp;
BOOLCDlgApp:
:
InitInstance()
{