MFC实验—学生成绩管理系统

大一下学期最后一个c++程序实验,选择了做一个学生成绩的管理系统。系统的界面如下:(红字为对应的控件对象的命名)
在这里插入图片描述

  • 初始化List Control 控件
//在BOOL CMFCApplication6Dlg::OnInitDialog()函数里加入以下代码。
	//初始化CListCtrl控件。插入一些标头,设置宽度和序列号。
	list1.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT);
	CString col[8] = { _T("姓名"),_T("学号"),_T("性别"),_T("语文"),_T("数学"),_T("英语"),_T("总分"),_T("平均分")};
	RECT r;
	list1.GetClientRect(&r);
	for (int i = 0; i < 8; i++)
	{ list1.InsertColumn(i, col[i], LVCFMT_CENTER, r.right / 8); }
  • 添加学生信息功能(添加按钮)
void CMFCApplication6Dlg::OnBnClickedButton1()//“添加”按钮代码
{
	//列表插入一行。创建Enroll对话框对象,并DoModal。
	
	Enroll enroll;
	enroll.DoModal();
}

Enroll是一个对话框类,界面如下图所示。
在这里插入图片描述

  • 先编写一个student类保存数据
class CMFCApplication6Dlg;

class student
{
public:
    //CString n[8]用于保存学生各项信息。
	CString n[8];
	CMFCApplication6Dlg*Dlg1 = NULL;
	student(CMFCApplication6Dlg*dlg);
	void set();
};
student::student(CMFCApplication6Dlg*dlg)
{
	Dlg1 = dlg;
}

void student::set()
{
	for (int b = 0; b < 8; b++)
	{
		Dlg1->list1.SetItemText(Dlg1->list1.GetItemCount()-1, b, n[b]);
	}
}
  • 录入按钮响应代码
//创建student类对象,用Enroll::Dlg初始化student::Dlg1。
//换取Enroll对话框的数据插入CMFCApplication6Dlg对话框的CListCtrl控件。
//如果输入信息不完整、学号重复,都会报错并退出子级对话框。
//录入成功则提示并退出子级对话框。
void Enroll::OnBnClickedButton1()//“录入”按钮代码。
{
    //建立stu对象,传入Dlg指针,Dlg指针为父级对话框指针。
	student stu(Dlg);
	//获取输入信息
	Name.GetWindowTextW(stu.n[0]); Number.GetWindowTextW(stu.n[1]);
	YW.GetWindowTextW(stu.n[3]); SX.GetWindowTextW(stu.n[4]); YY.GetWindowTextW(stu.n[5]);
	UINT nID = GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO2);
	//判断是否选择性别
	if (!nID)
	{
		MessageBox(L"请输入完整信息!", L"Error!"); Enroll::OnOK(); return;
	}
	GetDlgItemText(nID, stu.n[2]);
	//判断是否有未输入信息
	for (int g = 0; g < 6; g++)
	{
		if (stu.n[g].IsEmpty())
		{
			MessageBox(L"请输入完整信息!", L"Error!");
			Enroll::OnOK();
			return;
		}
	}
	//判断学号是否重复
	for (int i = 0; i < Dlg->list1.GetItemCount(); i++)
	{
		if (Dlg->list1.GetItemText(i, 1) == stu.n[1])
		{
			CString str("学号为");
			str += stu.n[1]; str += "的学生信息已录入!";
			MessageBox(str, L"Error!");
			Enroll::OnOK();
			return;
		}
	}
	//在列表上显示录入的信息
	Dlg->list1.InsertItem(Dlg->list1.GetItemCount(), L"");
	double x = _ttof(stu.n[3]) + _ttof(stu.n[4]) + _ttof(stu.n[5]);
	double y = x / 3;
	stu.n[6].Format(L"%f", x); stu.n[7].Format(L"%f", y);
	//set()是student类成员函数
	stu.set();
	MessageBox(L"录入成功", L"Finish!");
	//save是主对话框的bool类型成员数据,记录录入的信息是否保存
	Dlg->save = false;
	Enroll::OnOK();
}
  • 删除按钮功能
    (将list1对象已选择行的信息删除,可多选)
void CMFCApplication6Dlg::OnBnClickedButton3()//“删除”按钮代码。
{
	//将已被选择的信息全部删除。if没有选择信息,弹出窗口显示错误信息。
	int count = list1.GetSelectedCount(); int *a = new int[count];
	POSITION pos = list1.GetFirstSelectedItemPosition();
	if (pos)
	{
		for (int i = 0; i < count; i++)
		{
			a[i] = list1.GetNextSelectedItem(pos);
		}
		int p = 0;
		for (int i = 0; i < count; i++)
		{
			list1.DeleteItem(a[i] - p++);
		}
		save = false;
	}
	else
		MessageBox(L"请选择需要删除的信息!", L"Error!");
}
  • 查找按钮功能
void CMFCApplication6Dlg::OnBnClickedButton2()//“查找”按钮代码。
{
	CString fname, fnumber;int index = list1.GetItemCount();
	int q = 0;
	for (int i = 0; i < index; i++)//初始化各行信息的选择状态,设置为未选择。
		list1.SetItemState(i, 0, LVIS_SELECTED | LVIS_FOCUSED);
	Fname.GetWindowTextW(fname); Fnumber.GetWindowTextW(fnumber);
//获取需要搜索的姓名和学号,传入fname和fnumber。
	
	//判断fname和fnumber是否为空,并做出对应操作。用int q的值判断是否找到符合信息的学生。
	if (fname!=""&&fnumber!="")
	{
		for (int i = 0; i < index; i++)
		{
			if (list1.GetItemText(i, 0) == fname && list1.GetItemText(i, 1) == fnumber)
			{
				list1.SetFocus();
				list1.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
				list1.EnsureVisible(i, true); q = 1;
			}

		}
	}
	else if (fname!="" && fnumber=="")
	{
		for (int i = 0; i < index; i++)
		{
			if (list1.GetItemText(i, 0) == fname)
			{
				list1.SetFocus();
				list1.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
				list1.EnsureVisible(i, true); q = 1;
			}
		}
	}
	else if (fname==""&&fnumber!="")
	{
		for (int i = 0; i < index; i++)
		{
			if (list1.GetItemText(i, 1) == fnumber)
			{
				list1.SetFocus();
				list1.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
				list1.EnsureVisible(i, true); q = 1;
			}
		}
	}
	else if (fname == "" && fnumber == "")
	{
		MessageBox(L"请输入查找信息!",L"Error!");
		return;
	}
	if (q == 0)
		MessageBox(L"没有找到该学生!",L"Error!");
}
  • 排序功能
    在这里插入图片描述
    由于之前还不会用std::sort,所以自己写了一个排序的函数。

在 CMFCApplication6Dlg 类里加入void sort(int col)代码并定义,用于排序数据。

参数col为需要排序的数据对应的列的索引号。采用冒泡法排序。(list1控件上的8列数据分别对应的参数int col为0-7)

定义如下:

void CMFCApplication6Dlg::sort(int col)
{
	int k = list1.GetItemCount();
	for (int i = k - 1; i >= 0; i--)
		for (int j = 0; j < i; j++)
		{
			CString a, b;
			a = list1.GetItemText(j, col); b = list1.GetItemText(j + 1, col);
			if (_ttof(a) < _ttof(b))
			{
				CString s[8];
				for (int o = 0; o < 8; o++)
					s[o] = list1.GetItemText(j, o);
				for (int o = 0; o < 8; o++)
					list1.SetItemText(j, o, list1.GetItemText(j + 1, o));
				for (int o = 0; o < 8; o++)
					list1.SetItemText(j + 1, o, s[o]);
			}
		}
}

在类向导中添加以下函数(box控件收起时响应)
void CMFCApplication6Dlg::OnCloseupCombo1()

void CMFCApplication6Dlg::OnCloseupCombo1()//“排序”选择列表代码
{
	//判断需要排序的数据,调用sort(int col)函数,将该数据的列的索引号传入参数col。
	CString a; box.GetWindowTextW(a);
	if (a == _T("语文"))
		sort(3);
	else if (a == _T("数学"))
		sort(4);
	else if (a == _T("英语"))
		sort(5);
	else if (a == _T("平均分"))
		sort(7);
	list1.UpdateData();
}
  • 全选和取消全选
void CMFCApplication6Dlg::OnBnClickedButton4()
{
	int index = list1.GetItemCount();
		list1.SetFocus();
		for (int i = 0; i < index; i++)
		{
			list1.SetItemState(i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
		}
}
//全不选按钮代码
void CMFCApplication6Dlg::OnBnClickedButton5()
{
	int index = list1.GetItemCount();
	list1.SetFocus();
	for (int i = 0; i < index; i++)
	{
		list1.SetItemState(i, 0, LVIS_SELECTED | LVIS_FOCUSED);
	}
}
  • 数据保存和提取
    保存按钮代码
//将数据全部写入文件。
void CMFCApplication6Dlg::OnBnClickedButton7()
{
	CFile s(L"E://学生成绩记录.txt", CFile::modeCreate | CFile::modeReadWrite);
	int index = list1.GetItemCount();
	for (int i = 0; i < index; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			CString a;
			a = list1.GetItemText(i, j) + '\t';
			s.Write(a, a.GetLength() * 2);
		}
	}
	save = true;
}

打开按钮代码

//将文件数据读出。
void CMFCApplication6Dlg::OnBnClickedButton8()
{
	CFile in(L"E://学生成绩记录.txt", CFile::modeRead);
	list1.DeleteAllItems();
	TCHAR*a = new TCHAR; CString z;
	int i = 0, j = 0;
	list1.InsertItem(i, L"");
	while (in.Read(a, 2))
	{
		if (*a != '\t')
			z += *a;
		else
			list1.SetItemText(i, j++, z), z = L"";
		if(j==8)
		{
			list1.InsertItem(list1.GetItemCount(), L"");
			i++; j = 0;
		}
	}
	list1.DeleteItem(list1.GetItemCount()-1);
}
  • 程序退出提示
//判断退出程序前 数据是否保存并提示。
void CMFCApplication6Dlg::OnClose()
{
	if (!save)
	{
		if (MessageBox(L"信息还未保存!是否退出?", L"Error!", MB_YESNO)==IDNO)
		{
			return;
		}	
	}
	CDialogEx::OnClose();
}

总结:
问:如何实现两个对话框之间的数据交互。

答:可以在一个对话框说明并保存另一个对话框的指针实现。

PS:新人第一次写博客,肯定还有很多漏洞,大家看看就好,写的不好的地方各位大佬们不要见笑。

评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值