【MFC】文档操作——范例(12)

news2024/9/20 15:26:43

使用MFC框架文档操作范例:

 创建工程

创建工程,其中:

1、MFC单文档

2、自定义改应用程序数据文件扩展名:

 

3、 最后一步选择CListView(用报表显示数据)

 重点问题:数据文件的读写功能

添加数据类

学生类,如下:

#pragma once
class CStudent
{
public:
	CStudent(void);
	~CStudent(void);
	virtual void Serialize(CArchive& ar);
	CString name;
	CString department;
	CString major;
	CString grade;
	CString classname;
	CString cid;
};

#include "stdafx.h"
#include "Student.h"


CStudent::CStudent(void)
{
}


CStudent::~CStudent(void)
{
}
void CStudent::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{	// storing code
		ar<<name<<department<<major<<grade<<classname<<cid;
	}
	else
	{	// loading code
		ar>>name>>department>>major>>grade>>classname>>cid;
	}
}

文档类:


// MFC05Doc.h : CMFC05Doc 类的接口
//


#pragma once
#include "Student.h"
#include <vector>
using namespace std;

class CMFC05Doc : public CDocument
{
protected: // 仅从序列化创建
	CMFC05Doc();
	DECLARE_DYNCREATE(CMFC05Doc)

// 特性
public:	
	vector<CStudent> svect;
// 操作
public:

// 重写
public:
	virtual BOOL OnNewDocument();
	virtual void Serialize(CArchive& ar);
#ifdef SHARED_HANDLERS
	virtual void InitializeSearchContent();
	virtual void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds);
#endif // SHARED_HANDLERS

// 实现
public:
	virtual ~CMFC05Doc();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	DECLARE_MESSAGE_MAP()

#ifdef SHARED_HANDLERS
	// 用于为搜索处理程序设置搜索内容的 Helper 函数
	void SetSearchContent(const CString& value);
#endif // SHARED_HANDLERS
public:
	afx_msg void OnAddStu();
//	virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
};

其中 :  vector<CStudent> svect;   即保存多个学生信息的向量(STL)

资源视图中添加菜单命令:

添加对话框(用于添加学生)

 

文档类中响应菜单命令,并且打开对话框:

 代码如下:


// MFC05Doc.cpp : CMFC05Doc 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MFC05.h"
#endif

#include "MFC05Doc.h"

#include <propkey.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMFC05Doc

#include "AddStuDlg.h"
IMPLEMENT_DYNCREATE(CMFC05Doc, CDocument)

BEGIN_MESSAGE_MAP(CMFC05Doc, CDocument)
	ON_COMMAND(IDC_ADD_STU, &CMFC05Doc::OnAddStu)
END_MESSAGE_MAP()


// CMFC05Doc 构造/析构

CMFC05Doc::CMFC05Doc()
{
	// TODO: 在此添加一次性构造代码

}

CMFC05Doc::~CMFC05Doc()
{
}

BOOL CMFC05Doc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: 在此添加重新初始化代码
	// (SDI 文档将重用该文档)
	svect.clear();
	return TRUE;
}




// CMFC05Doc 序列化

void CMFC05Doc::Serialize(CArchive& ar)
{
	int size;
	if (ar.IsStoring())
	{
		// TODO: 在此添加存储代码
		size=svect.size();
		ar<<size;
		for(int i=0;i<size;i++)
			svect[i].Serialize(ar);
	}
	else
	{
		// TODO: 在此添加加载代码
		ar>>size;
		for(int i=0;i<size;i++)
		{
			CStudent s;
			s.Serialize(ar);
            svect.push_back(s);
		}
			
	}
}

#ifdef SHARED_HANDLERS

// 缩略图的支持
void CMFC05Doc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds)
{
	// 修改此代码以绘制文档数据
	dc.FillSolidRect(lprcBounds, RGB(255, 255, 255));

	CString strText = _T("TODO: implement thumbnail drawing here");
	LOGFONT lf;

	CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT));
	pDefaultGUIFont->GetLogFont(&lf);
	lf.lfHeight = 36;

	CFont fontDraw;
	fontDraw.CreateFontIndirect(&lf);

	CFont* pOldFont = dc.SelectObject(&fontDraw);
	dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK);
	dc.SelectObject(pOldFont);
}

// 搜索处理程序的支持
void CMFC05Doc::InitializeSearchContent()
{
	CString strSearchContent;
	// 从文档数据设置搜索内容。
	// 内容部分应由“;”分隔

	// 例如:  strSearchContent = _T("point;rectangle;circle;ole object;");
	SetSearchContent(strSearchContent);
}

void CMFC05Doc::SetSearchContent(const CString& value)
{
	if (value.IsEmpty())
	{
		RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid);
	}
	else
	{
		CMFCFilterChunkValueImpl *pChunk = NULL;
		ATLTRY(pChunk = new CMFCFilterChunkValueImpl);
		if (pChunk != NULL)
		{
			pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT);
			SetChunkValue(pChunk);
		}
	}
}

#endif // SHARED_HANDLERS

// CMFC05Doc 诊断

#ifdef _DEBUG
void CMFC05Doc::AssertValid() const
{
	CDocument::AssertValid();
}

void CMFC05Doc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG


// CMFC05Doc 命令


void CMFC05Doc::OnAddStu()
{
	// TODO: 在此添加命令处理程序代码
	CAddStuDlg dlg;
	if(dlg.DoModal()==IDOK)
	{
		CStudent stu;
		stu.cid=dlg.m_cid;
		stu.classname=dlg.m_classname;
		stu.department=dlg.m_department;
		stu.grade=dlg.m_grade;
		stu.major=dlg.m_major;
		stu.name=dlg.m_name;
		svect.push_back(stu);
		this->UpdateAllViews(NULL);
		this->SetModifiedFlag();
	}
}

核心代码:

1、序列化函数,Serialize

思路:保存的时候,先写入学生个数,然后一个个写,读取的时候正好相反.。CStudent的序列化函数需要好好了解一下;

2、菜单命令响应:

打开对话框,读取添加的数据,新生成一个CStudent,添加到Vector,并且更新视图和设置文档已经修改标记(提醒保存)。

视图类相对比较简单:


// MFC05View.h : CMFC05View 类的接口
//

#pragma once


class CMFC05View : public CListView
{
protected: // 仅从序列化创建
	CMFC05View();
	DECLARE_DYNCREATE(CMFC05View)

// 特性
public:
	CMFC05Doc* GetDocument() const;

// 操作
public:

// 重写
public:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	bool isInitView;
	void InitView();
	void InitData();
protected:
	virtual void OnInitialUpdate(); // 构造后第一次调用

// 实现
public:
	virtual ~CMFC05View();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	DECLARE_MESSAGE_MAP()
public:
//	afx_msg void OnPaint();
//	afx_msg void OnSize(UINT nType, int cx, int cy);
//	virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/);
//	virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/);
//	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	virtual void OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/);
};

#ifndef _DEBUG  // MFC05View.cpp 中的调试版本
inline CMFC05Doc* CMFC05View::GetDocument() const
   { return reinterpret_cast<CMFC05Doc*>(m_pDocument); }
#endif


// MFC05View.cpp : CMFC05View 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MFC05.h"
#endif

#include "MFC05Doc.h"
#include "MFC05View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMFC05View

IMPLEMENT_DYNCREATE(CMFC05View, CListView)

BEGIN_MESSAGE_MAP(CMFC05View, CListView)
//	ON_WM_SIZE()
END_MESSAGE_MAP()

// CMFC05View 构造/析构

CMFC05View::CMFC05View()
{
	// TODO: 在此处添加构造代码
	isInitView=false;

}

CMFC05View::~CMFC05View()
{
}

BOOL CMFC05View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CListView::PreCreateWindow(cs);
}

void CMFC05View::OnInitialUpdate()
{
	CListView::OnInitialUpdate();
	if(!isInitView)	InitView();
	InitData();
}
void CMFC05View::InitView()
{
	CListCtrl& m_list = GetListCtrl();//得到内置的listctrl引用
	LONG lStyle;
	lStyle = GetWindowLong(m_list.m_hWnd, GWL_STYLE);//获取当前窗口风格
	lStyle |= LVS_REPORT; //设置报表风格
	SetWindowLong(m_list.m_hWnd, GWL_STYLE, lStyle); //设置窗口风格
	CRect rect;
	m_list.GetClientRect(&rect);
	int cx =rect.Width()/8;
	m_list.InsertColumn( 0, " ", LVCFMT_CENTER, 50 );
	m_list.InsertColumn( 1, "姓名", LVCFMT_CENTER, cx );
	m_list.InsertColumn( 2, "学号", LVCFMT_CENTER, cx );
	m_list.InsertColumn( 3, "系部", LVCFMT_CENTER, cx );
	m_list.InsertColumn( 4, "专业", LVCFMT_CENTER, cx );
	m_list.InsertColumn( 5, "年级", LVCFMT_CENTER, cx );
	m_list.InsertColumn( 6, "班级", LVCFMT_CENTER, cx );
	m_list.InsertColumn( 7, "备注", LVCFMT_CENTER, 2*cx- 50);
	isInitView=true;
}
void CMFC05View::InitData()
{	
	CListCtrl& m_list = GetListCtrl();
	m_list.DeleteAllItems();
	vector<CStudent> svect=GetDocument()->svect;
	for(int i=0;i<svect.size();i++)
	{
		CString cs;
		cs.Format("%d",i+1);
		int row=m_list.InsertItem(i, "");
		m_list.SetItemText(row, 0, cs);
		m_list.SetItemText(row, 1, svect[i].name);
		m_list.SetItemText(row, 2, svect[i].cid);
		m_list.SetItemText(row, 3, svect[i].department);
		m_list.SetItemText(row, 4, svect[i].major);
		m_list.SetItemText(row, 5, svect[i].grade);
		m_list.SetItemText(row, 6, svect[i].classname);
		m_list.SetItemText(row, 7, "");
	}
}

// CMFC05View 诊断

#ifdef _DEBUG
void CMFC05View::AssertValid() const
{
	CListView::AssertValid();
}

void CMFC05View::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}

CMFC05Doc* CMFC05View::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFC05Doc)));
	return (CMFC05Doc*)m_pDocument;
}
#endif //_DEBUG




void CMFC05View::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/)
{
	// TODO: 在此添加专用代码和/或调用基类
	InitData();
}

总结:

1、MFC提供的文档操作框架简化了文件操作,核心是序列化处理数据,由文档类去调用用户自定义的序列化函数,实现特定数据的读写;

2、MFC屏蔽了文件的操作和消息响应,结论是读写文件都会自动调用文档类的Serialize函数,具体流程可以通过跟踪调试去了解(应用程序类首先响应打开、新建、保存文档的消息!)

3、重点掌握三口组(文档、视图、框架)以及应用程序类之间的相互调用:

获取应用程序对象指针:::AfxGetApp()   全局函数  可以强制转换

获取主框架指针:::AfxGetMainWnd()  或者 ::AfxGetApp()->m_pMainWnd;  可以强制转换

视图获取文档:GetDocument() (框架提供)

视图获取主框架还可以:GetParentFrame()  可以强制转换

文档类获取视图:多视图需要枚举(比如窗口分割后多块显示同一个文档)

​
 POSITION pos=CDocument::GetFirstViewPosition();
        while(pos != NULL)
        {
            CView *pView=CDocument::GetNextView(pos);
            if(pView->GetRuntimeClass()==RUNTIME_CLASS(C**View))
            {
                

            }
        }

​

单视图可以按框架方法来完成。

框架获取视图:

单文档单视图  GetActiveView()

多视图:先获取文档指针 GetActiveDocument() ,然后 枚举(见上)。

4、MFC文档操作相对比较简单安全,当然也可以自己通过CFile等相关类来实现数据文档的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑多个不同分辨率屏幕鼠标移动时出现偏移、错位情况的解决方法

本文介绍在使用不同尺寸、不同分辨率的两个或多个电脑屏幕时&#xff0c;鼠标在不同屏幕之间切换时&#xff0c;出现偏移、飘动、不规则运动等情况的解决方法。 对于使用两个或多个电脑屏幕的用户而言&#xff0c;鼠标在不同屏幕之间的切换有时候会出现偏移的问题。在同时使用多…

【My Electronic Notes系列——逻辑函数的化简】

目录 序言&#xff1a; &#x1f3c6;&#x1f3c6;人生在世&#xff0c;成功并非易事&#xff0c;他需要破茧而出的决心&#xff0c;他需要永不放弃的信念&#xff0c;他需要水滴石穿的坚持&#xff0c;他需要自强不息的勇气&#xff0c;他需要无畏无惧的凛然。要想成功&…

MySQL入门篇-MySQL字符集小结

备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊MySQL的字符集 前言: 字符集和排序规则 说实话我对这两个概念比较模糊&#xff0c;其实可以简单的理解: 字符集(character set)&#xff1a;定义了字符以及字符的编码。 排序规则(collation)&#xff1a;定义了字符的比…

【Django】ORM增删改查、F对象和Q对象、聚合操作和原生数据库操作

1、ORM的增删改查均需要通过管理器对象进行。 2、可使用python3 manage.py shell 进入脚本页方便操作。 3、可修改输出格式 一、ORM查询操作 1、查询方法 &#xff08;1&#xff09;all()方法 用法&#xff1a;MyModel.objects.all()作用&#xff1a;查询所有数据&#xff0c…

微信小程序——自定义组件(纯数据字段),组件的生命周期,组件所在页面的生命周期,插槽,父子组件之间的通信,事件绑定,属性绑定,behavior

一.纯数据字段1.什么是纯数据字段概念&#xff1a;纯数据字段指的是那些不用于界面渲染的data字段。应用场景&#xff1a;例如有些情况下&#xff0c;某些 data 中的字段既不会展示在界面上&#xff0c;也不会传递给其他组件&#xff0c;仅仅在当前组件内部使用。带有这种特性的…

《Keras深度学习:入门、实战与进阶》之回归问题实例:波士顿房价预测

本文摘自《Keras深度学习&#xff1a;入门、实战与进阶》。 本节将要预测20世纪70年代中期波士顿郊区房屋价格的中位数。这个数据是1978年统计收集的&#xff0c;数据集中的每一行数据都是对波士顿周边或城镇房价的描述&#xff0c;包含以下14个特征和506条数据。  CRIM&am…

verilog图像算法实现和仿真(代码与实践)

【声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 这里的代码指的是verilog代码,而不是之前的python代码。因为verilog处理的是数据,所以之前我们也谈到过,如果需要用verilog处理图像数据,需要先用python把图像变成文本文件,等到…

菜鸟的进阶--手写一个微型Spring

前言想干嘛深入了解spring原理&#xff0c;特别是IOC容器是如何实现的&#xff1f;AOP是如何实现的&#xff1f;手写一个spring迷你版框架&#xff0c;实现容器和AOP机制。我为什么想这么做spring是整个java体系中最重要的框架&#xff0c;它整合第三方技术&#xff0c;将所有的…

交联剂134272-64-3,Maleimide-NH2 HCl,2-马来酰亚胺乙胺盐酸盐

【中文名称】N-(2-氨乙基)马来酰亚胺盐酸盐&#xff0c;2-马来酰亚胺乙胺盐酸盐【英文名称】 MAL-NH2 HCl&#xff0c;Maleimide-NH2 HCl&#xff0c;MAL NH2 HCl&#xff0c;Maleimide-amine HCl&#xff0c;MAL-amine HCl&#xff0c;N-(2-AMinoethyl)MaleiMide Hydrochlorid…

5年老测试员,面试被刷,别人说他不懂自动化测试.....

圈内认识的朋友最近跳槽了&#xff0c;之前在一家小公司干了5年测试&#xff0c;本来以为很容易跳一个高待遇的工作&#xff0c;结果却比想象的难&#xff0c;因为他不会自动化测试… 最近也看了很多人的简历&#xff0c;写的都是3年工作经验&#xff0c;但面试中&#xff0c…

对数据库几个范式的理解

数据库关系理论 这部分主要是几个概念很抽象&#xff0c;大家开始学可能学不明白。最近在准备复试&#xff0c;复习了一下相关的内容&#xff0c;顺便做一下总结。 先说几个名词&#xff1a; 候选码&#xff1a;能够唯一确定一个元组的属性集合称为候选码。注意是集合&#…

每日学术速递2.3

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.Cv、cs.LG 1.Compositional Prompt Tuning with Motion Cues for Open-vocabulary Video Relation Detection(ICLR 2023) 标题&#xff1a;通过基于错误的隐性神经表征的上下文修剪实现高…

Java基础学习笔记(十五)—— 集合(3)

集合1 HashMap 类1.1 HashMap 类概述1.2 HashMap 案例2 TreeMap 类2.1 TreeMap 类概述2.2 TreeMap 案例3 Properties集合3.1 Properties集合概述3.2 Properties基本使用3.3 Properties特有方法3.4 Properties和IO流相结合的方法4 可变参数与不可变集合4.1 可变参数4.2 不可变集…

2023.1.26

0、任务 今明两天任务&#xff0c;回答以下问题&#xff1a; 1、网络传输延迟有哪些&#xff1f;如何区分传输延迟和排队延迟&#xff1f; 2、如何理解路由器存储转发的过程&#xff1f; 3、拥塞是什么&#xff0c;为什么会发生拥塞&#xff0c;发生拥塞的表现是什么&#xff…

网络资源下载方式:http/https、ftp/sftp、BT种子、磁力下载、ed2k下载等的区别

文章目录参考资料序言中心化下载http/https下载ftp/sftp下载http与ftp下载方式的不同中心化下载的缺点中心化下载BT种子下载磁力下载ed2k下载推荐的下载器IDM下载器安装步骤IDM如何下载种子文件参考资料 一文读懂Bt种子、磁力链接、直链、p2p这些下载的区别 常说的BT下载、磁力…

【数据结构基础】图 - 基础和Overview

图(Graph)是由顶点和连接顶点的边构成的离散结构。在计算机科学中&#xff0c;图是最灵活的数据结构之一&#xff0c;很多问题都可以使用图模型进行建模求解。例如: 生态环境中不同物种的相互竞争、人与人之间的社交与关系网络、化学上用图区分结构不同但分子式相同的同分异构体…

情人节该送女友什么?分享四款适合送女生的数码好物

情人节快到了&#xff0c;对于有伴侣的人来说&#xff0c;这是一个浪漫的日子。在这个浪漫的日子&#xff0c;一些生活仪式感是必不可少的。最近看到不少人问&#xff0c;适合女生的数码好物有哪些&#xff1f;下面&#xff0c;我来给大家推荐几款适合送女生的数码好物&#xf…

动态规划DP与记忆化搜索DFS 题单刷题(c++实现+AC代码)

文章目录数字三角形滑雪挖地雷最大食物链计数采药疯狂的采药5倍经验值过河卒洛谷动态规划入门题单&#xff1a; 提单传送门 数字三角形 观察下面的数字金字塔。写一个程序来查找从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大。每一步可以走到左下方的点也…

“深度学习”学习日记。卷积神经网络--卷积层

2023.2.3 CNN中出现一些新的概念&#xff1a;填充、步幅 等&#xff0c;此外各层中传递的数据是有形状的&#xff0c;与之前的全连接层神经网络完全不同&#xff1b; 一、全连接层存在的问题&#xff1a; 全连接层神经网络使用了Affine层&#xff0c;在相邻的神经元全部连接…

php7.3.4 pdo方式连接sqlserver 设置方法

我这边用的php是7.3.4版本的&#xff0c;大家设置的时候看一下。一、首先要开启php的sqlsrv扩展1.下载SQLSRV58.EXE,我的php版本是7.3.4https://docs.microsoft.com/en-us/sql/connect/php/release-notes-php-sql-driver?viewsql-server-2017#previous-releases拷贝到浏览器打…