MFC - 5 文件操作、序列化机制、对话框
2022/8/4 23:23:09
本文主要是介绍MFC - 5 文件操作、序列化机制、对话框,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文件操作
序列化基本类型
以二进制流形式读写硬盘文件,但这种方式效率高。
- CFile 文件操作类,完成硬盘文件读写操作。
- CArchive 归档类,完成内存数据操作。
CFile:
- CFile::Open
- CFile::Write / Read
- CFile::Close
- CFile::SeekToBegin / SeekToEnd / Seek
void fun() { CFile file; file.Open("C:/path/to/file", CFile::modeReadWrite | CFile::modeCreate); char str[] = "hello file"; file.Write(str, strlen(str)); file.SeekToBegin(); char buf[256] = { 0 }; long nLen = file.Read(buf, 255); std::cout << buf << " : " << nLen << std::endl; }
序列化机制使用
在内存中使用 \0 标识字符串的结束;在序列化的文件中,在字符串的前面用一个字节加上长度
图中的特殊符号就保存了字符串的长度
void store() { CFile file; file.Open("C:/file", CFile::modeReadWrite); CArchive ar(&file, CArchive::store); ar << 1L << 88.5 << "string"; ar.Close(); file.Close(); } void load() { CFile file; file.Open("C:/file", CFile::modeReadWrite); CArchive ar(&file, CArchive::load); long a; float b; CString c; ar >> a >> b >> c; std::cout << a << b << c << std::endl; ar.Close(); file.Close(); }
序列化过程:
- ar 对象维护一个缓冲区
- 将各个数据依次序列化到ar维护的缓冲区中,并将 m_lpBufCur 指针移动响应字节
- 如果ar维护的缓冲区不足,则将ar维护的缓冲区的数据写入硬盘文件,并重置 m_lpBufCur 为开始指向
- 当关闭ar对象时,将ar对象维护的缓冲区数据写入硬盘文件,释放ar维护的缓冲区
反序列化过程:
- ar 对象维护一个缓冲区
- 当反序列化第一个数据时,将文件数据全部读取到ar维护的缓冲区中,并将第一个数据反序列化到第一个变量,并将 m_lpBufCur 移动相应字节数
- 依次反序列化每个数据到变量中
- 当关闭ar对象时,释放ar维护的缓冲区
序列化类对象
序列化对象就是将对象的各个成员变量序列化,但与直接序列化各个字段不同,还会保存类名、类大小、类版本,然后保存字段。
要求:
- 必须派生自
CObject
- 类内必须添加声明宏
DECLARE_SERIAL(theClass)
- 类外必须添加实现宏
IMPLEMENT_SERIAL(theClass, baseClass, 1)
- 类必须重写虚函数
Serialize
class CMyDoc : public CDocument { DECLARE_SERIAL(CMyDoc) // 包含了 DECLARE_DYNCREATE(CMyDoc) 用于反序列化时动态生成对象 public: CMyDoc(int age = 0, float score = 0.0, CString name = "") : m_age(age), m_score(score), m_name(name) {} int m_age; float m_score; CString m_name; virtual void Serialize(CArchive& ar); }; IMPLEMENT_SERIAL(CMyDoc, CDocument, 1) // 包含了 IMPLEMENT_DYNCREATE(CMyDoc, CDocument) void CMyDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar << m_age << m_score << m_name; } else { ar >> m_age >> m_score >> m_name; } } void store() { CFile file; file.Open("C:/file", CFile::modeReadWrite); CArchive ar(&file, CArchive::store); CMyDoc data(1, 5.5, "zhangsan"); ar << &data; // 序列化对象就是将对象的各个成员变量序列化 ar.Close(); file.Close(); } void load() { CFile file; file.Open("C:/file", CFile::modeReadWrite); CArchive ar(&file, CArchive::load); CMyDoc* pData = NULL; ar >> pData; ar.Close(); file.Close(); std::cout << pData->m_age << pData->m_score << pData->m_name << std::endl; }
对话框
- 模式对话框(假,使用 EnableWindow 伪造)
- 无模式对话框
无模式对话框架构使用 CDialog CWinApp
- 添加 Dialog 资源
- 定义一个自己的对话框类,管理对话框资源,派生自
CDialog
或CDialogEx
均可
// 这份代码将对话框做为主窗口,点击“确定”按钮后窗口消失但进程依然存在,因为父类中虚函数使用了 EndWindow 隐藏窗口 #include <afxwin.h> #include "resource1.h" class CMyDlg : public CDialog { DECLARE_MESSAGE_MAP() public: void OnCancel(); }; BEGIN_MESSAGE_MAP(CMyDlg, CDialog) ON_COMMAND(IDCANCEL, OnCancel) END_MESSAGE_MAP() void CMyDlg::OnCancel() { this->DestroyWindow(); } class CMyWinApp : public CWinApp { public: virtual BOOL InitInstance(); }; BOOL CMyWinApp::InitInstance() { CMyDlg* pdlg = new CMyDlg; pdlg->Create(IDD_DIALOG1); m_pMainWnd = pdlg; pdlg->ShowWindow(SW_SHOW); pdlg->UpdateWindow(); return TRUE; } CMyWinApp theApp;
执行过程:
- 获得应用程序类对象theApp的地址
- 利用theApp地址调用InitApplication,初始化当前应用程序的数据
- 利用theApp地址调用InitInstance函数,在函数中创建无模式对话框并显示
- 利用theApp地址调用CWinApp的Run函数进行消息循环
- 如果没有消息,利用theApp地址调用 OnIdle 虚函数实现空闲处理
当对话框销毁(必须利用DestroyWindow),消息循环才可退出。
推出前利用theApp地址调用 ExitInstance 虚函数实现退出前的善后处理工作。
模式对话框
#include <afxwin.h> #include "resource1.h" class CMyDlg : public CDialog { DECLARE_MESSAGE_MAP() public: CMyDlg() : CDialog(IDD_DIALOG1) {} void OnCancel(); }; BEGIN_MESSAGE_MAP(CMyDlg, CDialog) ON_COMMAND(IDCANCEL, OnCancel) END_MESSAGE_MAP() void CMyDlg::OnCancel() { this->DestroyWindow(); } class CMyWinApp : public CWinApp { public: virtual BOOL InitInstance(); }; BOOL CMyWinApp::InitInstance() { CMyDlg* pdlg = new CMyDlg; this->m_pMainWnd = pdlg; //pdlg->Create(IDD_DIALOG1); //pdlg->ShowWindow(SW_SHOW); //pdlg->UpdateWindow(); pdlg->DoModal(); return FALSE; // 不再执行MFC库中安排的Run函数 } CMyWinApp theApp;
- 启动后进入入口函数 WinMain
- 获取应用程序类对象theApp的地址
- 利用theApp地址调用InitApplication,初始化当前应用程序的数据
- 利用theApp地址调用InitInstance函数,在函数中调用DoModal,DoModal 内部
- 将父窗口设置为不可用
- 创建无模式对话框
- 进入消息循环(自带的)
- 退出消息循环(父类的OnOK/OnCancel导致循环退出)
- 将父窗口设置为可用状态
- 销毁无模式对话框
- 不再执行CWinApp的Run函数进行消息循环
- 程序结束
这篇关于MFC - 5 文件操作、序列化机制、对话框的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升