MFC之文档视图案例30

1 文档视图案例的初始化

1)创建基于单文档的MFC程序,但是到下图步骤时,需要换一下视图的继承基类为CFormView。。

在这里插入图片描述

这样下面我们就多出了FORM这个对话框,以前单文档继承于CView时是没有对话框的,所以无法操作控件。
在这里插入图片描述

2)然后按如下所示添加控件。其中模式为GroupBox容器,需要注意Group里面的ID顺序。
在这里插入图片描述

3)将Group第一个控件即编辑单选框的Group属性置为true。

4)然后将上一个下一个这两个按钮添加变量。

5)这里将编辑模式时,上一个,下一个这两个按钮为灰色,预览模式时为高亮。所以分别双击编辑和预览按钮,去到响应函数。

void CanliView::OnBnClickedRadio1()
{
	// TODO: 在此添加控件通知处理程序代码
	m_buttonPre.EnableWindow(FALSE);
	m_buttonNext.EnableWindow(FALSE);
}


void CanliView::OnBnClickedRadio2()
{
	// TODO: 在此添加控件通知处理程序代码
	m_buttonPre.EnableWindow(TRUE);
	m_buttonNext.EnableWindow(TRUE);
}

6)由于我们设定默认是编辑模式,所以当我们没有按下单选框也要为灰色,所以需要在视图的初始化函数OnInitialUpdate初始化上一个下一个按钮为灰色。

void CanliView::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();

	CheckRadioButton(IDC_RADIO1, IDC_RADIO2, IDC_RADIO1);//设置编辑区默认显示
	m_buttonPre.EnableWindow(FALSE);
	m_buttonNext.EnableWindow(FALSE);

}

初始化后的结果:
在这里插入图片描述
在这里插入图片描述

2 文档视图案例的实现

先了解相关函数。
在这里插入图片描述

1)新建一个学生类。

#pragma once
class Student
{
public:
	Student(int id, CString name, int age, int score);
	virtual ~Student();

public:
	int m_id;
	CString m_name;
	int m_age;
	int m_score;
};
Student::Student(int id, CString name, int age, int score)
{
	m_id = id;
	m_name = name;
	m_age = age;
	m_score = score;
}

Student::~Student()
{
}

2)在文档类Doc添加链表成员,用于保存数据。因为MFC的链表需要保存当前节点位置,所以也要添加一个保存当前节点位置的变量。

CList<Student*> m_list;
POSITION m_pos;

3)为四个编辑区关联Value类型的变量。

4)双击添加按钮,去到响应函数处理。

//添加按钮
void CanliView::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	//1 更新内容到变量
	UpdateData(TRUE);

	//2 创建学生信息
	Student *stu = new Student(m_uiId, m_uiName, m_uiAge, m_uiScore);

	//3 保存到链表
	CanliDoc *pDoc = GetDocument();
	pDoc->m_list.AddTail(stu);

	//4 更新当前节点为新添加的节点
	pDoc->m_pos = pDoc->m_list.GetTailPosition();
}

5)双击上一个按钮,去到响应函数处理。

/上一个按钮
void CanliView::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码

	//1 获取上一节点下标
	CanliDoc *pDoc = GetDocument();
	if (pDoc->m_list.GetSize() <= 0) {
		return;
	}
	pDoc->m_list.GetPrev(pDoc->m_pos);//自动将m_pos指向上一节点
	if (pDoc->m_pos == NULL) {
		pDoc->m_pos = pDoc->m_list.GetTailPosition();//如果指向头结点前面的NULL,就重新指向末尾
	}

	//2 通过上一节点下标获取上一节点元素
	Student *tmp = pDoc->m_list.GetAt(pDoc->m_pos);

	//3 更新值到编辑区
	m_uiId = tmp->m_id;
	m_uiName = tmp->m_name;
	m_uiAge = tmp->m_age;
	m_uiScore = tmp->m_score;
	UpdateData(FALSE);
}

6)双击下一个按钮,去到响应函数处理。

//下一个按钮
void CanliView::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码

	//1 获取下一节点下标
	CanliDoc *pDoc = GetDocument();
	if (pDoc->m_list.GetSize() <= 0) {
		return;
	}
	pDoc->m_list.GetNext(pDoc->m_pos);
	if (pDoc->m_pos == NULL) {
		pDoc->m_pos = pDoc->m_list.GetHeadPosition();
	}

	//2 通过下一节点下标获取下一节点元素
	Student *tmp = pDoc->m_list.GetAt(pDoc->m_pos);

	//3 更新值到编辑区
	m_uiId = tmp->m_id;
	m_uiName = tmp->m_name;
	m_uiAge = tmp->m_age;
	m_uiScore = tmp->m_score;
	UpdateData(FALSE);
}

7)由于每次新建文档都需要释放上一次的内容,所以我们需要重写文档类的DeleteContents函数。
在这里插入图片描述

void CanliDoc::DeleteContents()
{
	// TODO: 在此添加专用代码和/或调用基类

	while (m_list.GetHeadPosition() != NULL) {
		Student *tmp = m_list.RemoveHead();//只剔除出链表,并不会释放空间
		delete tmp;
		tmp = NULL;
	}

	m_pos = NULL;

	CDocument::DeleteContents();
}

至此本案例结束,但是该案例可能会存在部分bug,自己维护一下即可。下图几个键额度功能都实现了。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值