基于面向对象的软件开发技术
课程设计报告
学院 | 计算机学院 |
---|---|
班级 | |
姓名 | |
学号 |
计算机学院制
1 摘要
1.1 设计题目
基于MFC的多功能低调奢华学生信息管理系统
1.2 设计内容
传统的大量数据处理方式过于繁琐且界面不够友好。通过对所学知识的总结,将完成一个比较完整的应用程序的设计,将学过的知识连贯起来,掌握开发一个实际应用程序的步骤,同时学会使用开发工具实现界面友好的应用程序。运用面向对象技术对具体的应用系统进行分析和设计。完成一个界面友好、功能齐全、便于操作的基于MFC的学生管理系统。
1.3 开发工具
Visual Studio 2017,Visual Studio 2019,Win32
2 详细设计
2.1 程序结构
/*请在这里详细描述你的程序的整体结构,包括程序的流程,各函数的功能关系、参数传递等。*/
程序流程图
函数功能关系图:
2.2 主要功能
/*请在这里说明你的课程设计程序功能,并详细描述它们实现的原理和方法(包含算法、数据结构)。*/
该课程设计为学生成绩管理系统,由一个主对话框及若干的子对话框组成。主要运用面向对象技术及数据库相关原理,并利用MFC进行界面设计来完成课程设计。
该系统拥有较为强大的信息管理功能,详见以下
以下功能实现,皆用代码及注释展示
①登录操作:
void CglxtDlg::OnBnClickedOk() //按下确定键对账号密码进行判断
{
UpdateData(TRUE);
CString zhang = zhanghao;
CString mi = mima;
if (zhang == "xsglxt" && mi == "123")
{
AfxGetMainWnd()->SendMessage(WM_CLOSE);
management dlgs;
dlgs.DoModal();
}
else if (zhang == "" || mi == "")
{
MessageBox("账号或密码不能为空", "提醒");
return;
}
else
{
MessageBox("账号或密码错误","提醒");
return;
}
UpdateData(FALSE);
CDialogEx::OnOK();
}
BOOL CglxtDlg::PreTranslateMessage(MSG* pMsg) //重载它来处理键盘和鼠标消息,这段代码主要用于当点击编辑框,
{ //会把默认文本清除,比较巧妙,用了特殊的设置密码
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
CEdit* pEdit2 = (CEdit*)GetDlgItem(IDC_EDIT2);
CString s = (CString)"";
if (pMsg->message == WM_LBUTTONDOWN)
{
UpdateData(TRUE);
if (pMsg->hwnd == pEdit->GetSafeHwnd())
{
CEdit * kd = (CEdit*)GetDlgItem(IDC_EDIT1);
kd->SetPasswordChar('*');
pEdit->SetWindowText(_T(""));
if (zhanghao== s) //处理细节
{
pEdit2->SetWindowText("学号");
}
}
else if(pMsg->hwnd == pEdit2->GetSafeHwnd())
{
pEdit2->SetWindowText("");
if (mima == s)
{
CEdit * kd = (CEdit*)GetDlgItem(IDC_EDIT1);
kd->SetPasswordChar(NULL);
pEdit->SetWindowText("输入密码");
}
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}
②主界面各功能:
BOOL management::nodata()//判断列表中是否有数据 该功能多处用到
{
if (m_list.GetItemText(0, 0) != "")
{
return TRUE;
}
return FALSE;
}
程序还附带多处检查信息填写是否完整函数,基本原理相同,详见源代码
删除功能:
void management::deletenull()//删除列表框的所有数据
{
m_list.DeleteAllItems();
m_line = 0;
m_stusum = m_line;
UpdateData(FALSE);
}
void management::delete_q()//删除单个数据+调用上面函数删除所有数据
{
if (deletes.a == 0 && deletes.b != "")
{
for (UINT i = 0; i < m_line; i++)
{
CString s = m_list.GetItemText(i, 1);
if (deletes.b == s)
{
m_list.DeleteItem(i);
m_line--;
deletes.b = "";
judge = TRUE;
m_stusum = m_line;
UpdateData(FALSE);
MessageBox("删除成功");
break;
}
}
if (judge == FALSE)
MessageBox("没有此名字的学生");
}
else if (deletes.a == 1 && deletes.b != "")
{
for (UINT i = 0; i < m_line; i++)
{
CString s = m_list.GetItemText(i, 0);
if (deletes.b == s)
{
m_list.DeleteItem(i);
m_line--;
deletes.b = "";
judge = TRUE;
m_stusum = m_line;
UpdateData(FALSE);
MessageBox("删除成功");
break;
}
}
if (judge == FALSE)
MessageBox("没有此学号的学生");
}
else if (deletes.a == 2)
{
deletenull();
}
else
{
MessageBox("请输入一项数据删除");
}
}
保存功能:
void management::OnBnClickedButton3()//保存按钮响应函数
{
BOOL jdg = FALSE;
glsave saves;
CFileDialog filesaves(FALSE);
filesaves.m_ofn.lpstrTitle = "选择文件并保存";
filesaves.m_ofn.lpstrFilter = "所有文件(*.*)\0*.*\0\0";
if (filesaves.DoModal() == IDOK)
{
filename = filesaves.GetPathName();
finds.filenaem = filename;
}
if (saves.DoModal() == IDOK && nodata())
{
if (filename == "")MessageBox("请选择保存的文件名");
else {
CFile file;
file.Open(filename, file.modeWrite | file.modeCreate);
for (UINT i = 0; i < m_line; i++)
{
for (UINT j = 0; j < 8; j++)
{
CString s = m_list.GetItemText(i, j);
int strLength2 = s.GetLength() + 1;
char chArray[20];
memset(chArray, 0, sizeof(chArray) ); //将数组的垃圾内容清空.
strncpy_s(chArray, s, strLength2);
file.Write(chArray, sizeof(chArray));
}
}
MessageBox("数据存储成功");
file.Close();
}
}
if (!nodata())
{
MessageBox("列表中没有数据,请先添加");
}
check = TRUE;
}
查找功能:
void management::find_q()//查找某学号或某名字的学生的信息
{
if (finds.a == 0 && finds.b != "")
{
for (UINT i = 0; i < m_line; i++)
{
CString s = m_list.GetItemText(i, 1);
if (finds.b == s)
{
reset(i);
finds.b = "";
judge = TRUE;
MessageBox("查找成功");
break;
}
}
if (judge == FALSE)
MessageBox("没有此名字的学生");
}
else if (finds.a == 1 && finds.b != "")
{
for (UINT i = 0; i < m_line; i++)
{
CString s = m_list.GetItemText(i, 0);
if (finds.b == s)
{
reset(i);
finds.b = "";
judge = TRUE;
MessageBox("查找成功");
break;
}
}
if (judge == FALSE)
MessageBox("没有此学号的学生");
}
else
{
MessageBox("请输入一项数据删除");
}
}
导入功能:
UINT management::importt()//导入函数主体,管理系统主菜单初始化时就调用了该函数,使得一开始就有若干学生信息
{
CFile file;
file.Open(finds.filenaem, file.modeReadWrite);
Student u;
UINT X = sizeof(u);
while (file.Read(&u, sizeof(u)))
{
m_list.InsertItem(m_line, u.ID);
m_list.SetItemText(m_line, 1, u.name);
m_list.SetItemText(m_line, 2, u.xing);
m_list.SetItemText(m_line, 3, u.grade);
m_list.SetItemText(m_line, 4, u.classs);
m_list.SetItemText(m_line, 5, u.program);
m_list.SetItemText(m_line, 6, u.math);
m_list.SetItemText(m_line, 7, u.lisan);
m_line++;
}
m_stusum = m_line;
UpdateData(FALSE);
file.Close();
return 0;
}
修改功能:
void management::findcheck()//个人信息修改函数
{
BOOL f = FALSE;
if (changes.name != "")
{
for (UINT i = 0; i < m_line; i++)
{
if (changes.name == m_list.GetItemText(i, 1))
{
settext(i);
f = TRUE;
}
if (f)
{
MessageBox("成功修改");
break;
}
}
if (!f)
{
MessageBox("查找的人名字可能不符,请检查");
}
}
else {
MessageBox("请输入修改同学的新旧姓名");
}
}
排序功能:
void management::resort(UINT x) //排序函数
{
point *gl = new point[m_line]; //建立动态数组
for (UINT i = 0; i < m_line; i++)
{
CString a = m_list.GetItemText(i, x);
UINT AA = _ttoi(a);
gl[i].x = i;
gl[i].y = AA;
}
if(x==0)
sort(gl, gl + m_line, cmp); //快排
else
sort(gl, gl + m_line, ccmp);
for (int i = 0; i < m_line; i++)
{
CString a = m_list.GetItemText(gl[i].x, 0);
m_list.InsertItem(i+m_line, a);
for (UINT j = 1; j < 8; j++)
{
CString a = m_list.GetItemText(gl[i].x, j);
m_list.SetItemText(i + m_line, j, a);
}
}
for (int i = 0; i <m_line; i++)
{
m_list.DeleteItem(0);
}
delete []gl; //防止内存泄露
}
直接在list上操作的功能实现:
void management::OnDblclkList2(NMHDR *pNMHDR, LRESULT *pResult) //双击响应
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CRect rc; //矩形
m_Row = pNMListView->iItem;
m_Col = pNMListView->iSubItem;
if (pNMListView->iSubItem != -1) //在listcontrol和edit上操作
{
m_list.GetSubItemRect(m_Row, m_Col, LVIR_LABEL, rc); //获取控件矩形区域
m_edit.SetParent(&m_list); //SetParent 就是把编辑框转到列表框里面
m_edit.MoveWindow(rc);
m_edit.SetWindowText(m_list.GetItemText(m_Row, m_Col));
m_edit.ShowWindow(SW_SHOW);
m_edit.SetFocus();
m_edit.ShowCaret(); //使插入标记在屏幕的当前位置上可见
}
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
}
以上仅为部分功能实现展示
2.3 函数实现
/*请在这里简要描述你的程序中各个函数程序代码的实现(包含算法、数据结构)*/
BOOL CwujiekdDlg::PreTranslateMessage(MSG* pMsg);
重载函数,以处理鼠标及键盘信息
BOOL nodata(); //添加函数
BOOL empty();
BOOL checkgrade();
BOOL checknumber(char(&c)[15]);
BOOL checkxingbie();
该部分主要实现检查及添加功能
①检查是否为空:主要对编辑框内信息进行判断是否为空,然后进行提示
②检查是否重复:在输入信息后,对数据进行检索,判断是否重复,若重复,基于提示
void deletenull(); //删除函数
void delete_q();
输入需删除的学生信息后,检索数据库,找到对应学生信息,调用DeleteItems()或DeleteAllItems()进行删除
void find_q(); //查找函数
void reset(UINT a);
在GetItemText()获得需要查找的学生后,检索数据库并将查找学生reset()放入list第一行
void importtt(); //导入函数
UINT importt();
调用importtt()打开文件并GetPathName()获取所需导入数据的文件的地址
在调用importtt()后调用importt(),主要利用file.Open(finds.filenaem, file.modeReadWrite)进信息导入管理系统
void findcheck(); //修改函数
void settext(int line);
BOOL checknum();
void changename();
该部分在获取所需修改的学生信息后,输入新信息并check后调用SetItemText()将信息放入管理系统
void resort(UINT x); //排序函数
主要利用algorithm头文件中sort实现功能
3 程序调试及运行
3.1 程序运行结果
/*请将程序运行的结果屏幕(可以使用ALT+PrintScreen截取屏幕)放在这里,并配上说明*/
①登录界面:输入学号及密码(为方便演示,默认密码为123)
②程序主界面:可显示学生信息及总人数,并拥有一系列按钮可实现不同功能
③以下为部分功能界面展示:
3.2 程序使用说明
/*请在这里详细描述如何使用你的程序,就好比是一个小型说明书*/
①启动程序
②输入学号(xsglxt)及密码(123)进行登录系统//初始默认账户
③成功进入系统后,将自动导入默认数据库
④通过下方按钮可对学生信息进行一定规则的管理,具体功能如下:
- 添加:单击后可输入欲添加的学生信息
- 删除:单击后可进行选择以删除无用学生信息
- 查找:单击后输入学生部分信息(如姓名、学号)后,可在界面迅速锁定所查学生信息。在数据过多的情况下,可利用该功能迅速完成查找的目的
- 修改:当输入信息有误时,可使用该功能根据提示修改学生信息/除使用该功能,还可直接在list列表中双击所需修改的信息,进行直接修改
- 导入:单击后,可在系统文件管理器中找到所需的新数据库进行导入,以便在系统中操作及显示
- 保存:将添加/删除/修改后的数据保存并导出,以便下次使用
- 排序:单击后系统将为学生按照一定规则进行排序
- 退出管理系统:正常退出程序
3.3 程序开发总结
/*请在这里简要描述你对课程设计的收获与思考*/
起初仅仅是抱着兴趣参加这个课程的学习,获得了远超预期的收获。尝试过诸多课程设计,最终选择了能很好地整合该课程所学知识的学生管理系统,通关该系统的设计,我更好的巩固了面向对象以及MFC的知识。在制作中,对曾经学过的知识有所遗忘,都通过笔记和课件的再学习拾了起来。除此之外,在制作中还遇到了许多小问题,例如一些函数的使用,在困难中,我选择利用网络解决问题。在浏览CSDN并查询了诸多资料后,解决了遇到的所有问题。
除了以上遇到的问题,该设计还有许多值得优化的地方,如增加统计方法处理数据功能。
通过整个设计的过程,我巩固了所学知识,同时开阔了眼界,强化了自学能力。最值得可幸的是,通过这个作业,我解决了许多疑惑,也为我学习目标提供了一个小小的方向。也许,完成课程设计是一个结束,但同时,它也是我走向面向对象编程的开始。
4 附件(源程序)
/*请在附上你的程序主要模块的源代码,如果是多个请标出文件名称以及工程管理名称及设置*/
management.cpp:
// management.cpp: 实现文件
//
#include "stdafx.h"
#include "glxt.h"
#include "management.h"
#include "afxdialogex.h"
#include "glxtdlg.h"
#include<algorithm> //引入快排
using namespace std;
// management 对话框
IMPLEMENT_DYNAMIC(management, CDialogEx)
management::management(CWnd* pParent /*=nullptr*/)
: CDialogEx(menu, pParent)
, m_stusum(0)
{
m_index = 0;
m_line = 0;
m_indexmax = 8;
judge = FALSE;
check = TRUE;
filename = "";
}
management::~management()
{
}
void management::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST2, m_list);
DDX_Text(pDX, IDC_EDIT1, m_stusum);
DDX_Control(pDX, IDC_EDIT2, m_edit);
}
BEGIN_MESSAGE_MAP(management, CDialogEx)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, &management::OnLvnItemchangedList2)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_BUTTON1, &management::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &management::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &management::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &management::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &management::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON6, &management::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON7, &management::OnBnClickedButton7)
ON_BN_CLICKED(IDC_BUTTON8, &management::OnBnClickedButton8)
ON_WM_PAINT()
ON_NOTIFY(NM_DBLCLK, IDC_LIST2, &management::OnDblclkList2)
ON_EN_KILLFOCUS(IDC_EDIT2, &management::OnKillfocusEdit2)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST2, &management::OnCustomdrawList2)
ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST2, &management::OnColumnclickList2)
END_MESSAGE_MAP()
// management 消息处理程序
void management::OnLvnItemchangedList2(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
}
BOOL management::OnInitDialog()
{
CDialogEx::OnInitDialog();
ModifyStyleEx(0, WS_EX_APPWINDOW);
CString str = "学生信息管理系统";
SetWindowText(str);
CRect rect;
CListCtrl* pmyListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST2); //设置风格
LONG dwStyle = GetWindowLong(pmyListCtrl->m_hWnd, GWL_STYLE);
SetWindowLong(pmyListCtrl->m_hWnd, GWL_STYLE, dwStyle | LVS_REPORT);
LONG styles = pmyListCtrl->GetExtendedStyle();
pmyListCtrl->SetExtendedStyle(styles | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_NOSCROLL);
pmyListCtrl->GetWindowRect(&rect);
m_list.InsertColumn(0, "学号", LVCFMT_CENTER, 100); //list control第一列会不在中间,但通过此方法可以很好的达到中间的目的
m_list.InsertColumn(1, "学号", LVCFMT_CENTER, 100);
m_list.InsertColumn(2, "姓名", LVCFMT_CENTER, 70);
m_list.InsertColumn(3, "性别", LVCFMT_CENTER, 70);
m_list.InsertColumn(4, "年级", LVCFMT_CENTER, 70);
m_list.InsertColumn(5, "班别", LVCFMT_CENTER, 70);
m_list.InsertColumn(6, "面向对象", LVCFMT_CENTER, 90);
m_list.InsertColumn(7, "高等数学", LVCFMT_CENTER, 90);
m_list.InsertColumn(8, "离散数学", LVCFMT_CENTER, 90);
m_list.DeleteColumn(0); //删除第一列
importt();
m_stusum=m_line;
UpdateData(FALSE);
GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);
m_edit.ShowWindow(SW_HIDE);
// TODO: 在此添加额外的初始化
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
//————————————————————————————————关键,多个操作功能会用到它!———————————————————————————————
BOOL management::nodata()//判断列表中是否有数据
{
if (m_list.GetItemText(0, 0) != "")
{
return TRUE;
}
return FALSE;
}
//——————————————————————————————————————添加————————————————————————————————————
BOOL management::empty()//判定数据是否存在没填的
{
if (adds.name == "" || adds.grade == "" || adds.classs == "" || adds.number == 0)
{
MessageBox("数据框有空,请填写");
return FALSE;
}
return true;
}
BOOL management::checkgrade() //检查分数是否在规定范围以内
{
if (adds.program > 100 || adds.math > 100 || adds.lisan > 100)
{
MessageBox("分数大于指定最大分数");
return FALSE;
}
return TRUE;
}
BOOL management::checknumber(char(&c)[20])//检测学号是否相等
{
_itoa_s(adds.number, c, 10);
for (UINT i = 0; i < m_line; i++)
{
CString ID;
ID += c;
if (ID == m_list.GetItemText(i, 0))
{
char cid[100];
_itoa_s(i + 1, cid, 10);
CString s = "学号与第";
s += cid;
s += "个同学相同,请重新输入";
MessageBox(s);
return FALSE;
}
}
return TRUE;
}
BOOL management::checkxingbie()//检查是否已选性别
{
if (adds.xing == 0)
{
adds.m_set = "男";
return TRUE;
}
else
if (adds.xing == 1)
{
adds.m_set = "女";
return TRUE;
}
else
{
MessageBox("请选择性别");
return FALSE;
}
}
void management::OnBnClickedButton1()//将数据加载至列表框
{
// TODO: 在此添加控件通知处理程序代码
while (1)
{
adds.xing = -1;
if (adds.DoModal() == IDOK && empty() && adds.FA == FALSE && checkgrade())
{
char c[20];
if (checknumber(c) && checkxingbie())
{
char c1[5], c2[5], c3[5];
_itoa_s(adds.program, c1, 10);
_itoa_s(adds.math, c2, 10);
_itoa_s(adds.lisan, c3, 10);
m_list.InsertItem(0, c); //每次都是把新的信息加到第一行
m_list.SetItemText(0, ++m_index, adds.name);
m_list.SetItemText(0, ++m_index, adds.m_set);
m_list.SetItemText(0, ++m_index, adds.grade);
m_list.SetItemText(0, ++m_index, adds.classs);
m_list.SetItemText(0, ++m_index, c1);
m_list.SetItemText(0, ++m_index, c2);
m_list.SetItemText(0, ++m_index, c3);
m_line++;
m_stusum = m_line; //用于显示
UpdateData(FALSE);
m_index = 0;
check = FALSE;
adds.name = "";
adds.grade = "";
adds.classs = "";
adds.number = 0;
adds.program = 0;
adds.math = 0;
adds.lisan = 0;
}
}
if (adds.FA == TRUE)
{
adds.FA = FALSE;
break;
}
}
}
//—————————————————————————————————————删除————————————————————————————————
void management::deletenull()//删除列表框的所有数据
{
m_list.DeleteAllItems();
m_line = 0;
m_stusum = m_line;
UpdateData(FALSE);
}
void management::delete_q()//删除单个数据+调用上面函数删除所有数据
{
if (deletes.a == 0 && deletes.b != "")
{
for (UINT i = 0; i < m_line; i++)
{
CString s = m_list.GetItemText(i, 1);
if (deletes.b == s)
{
m_list.DeleteItem(i);
m_line--;
deletes.b = "";
judge = TRUE;
m_stusum = m_line;
UpdateData(FALSE);
MessageBox("删除成功");
break;
}
}
if (judge == FALSE)
MessageBox("没有此名字的学生");
}
else if (deletes.a == 1 && deletes.b != "")
{
for (UINT i = 0; i < m_line; i++)
{
CString s = m_list.GetItemText(i, 0);
if (deletes.b == s)
{
m_list.DeleteItem(i);
m_line--;
deletes.b = "";
judge = TRUE;
m_stusum = m_line;
UpdateData(FALSE);
MessageBox("删除成功");
break;
}
}
if (judge == FALSE)
MessageBox("没有此学号的学生");
}
else if (deletes.a == 2)
{
deletenull();
}
else
{
MessageBox("请输入一项数据删除");
}
}
void management::OnBnClickedButton2()//删除按钮响应函数
{
if (!nodata() )
{
MessageBox("列表中没有数据");
}
while (nodata())
{
if (deletes.DoModal() == IDOK)
{
delete_q();
}
if (deletes.FA == TRUE|| !nodata())
{
deletes.FA = FALSE;
break;
}
}
}
//——————————————————————————————————————保存————————————————————————————————
void management::OnBnClickedButton3()//保存按钮响应函数
{
BOOL jdg = FALSE;
glsave saves;
CFileDialog filesaves(FALSE);
filesaves.m_ofn.lpstrTitle = "选择文件并保存";
filesaves.m_ofn.lpstrFilter = "所有文件(*.*)\0*.*\0\0";
if (filesaves.DoModal() == IDOK)
{
filename = filesaves.GetPathName();
finds.filenaem = filename;
}
if (saves.DoModal() == IDOK && nodata())
{
if (filename == "")MessageBox("请选择保存的文件名");
else {
CFile file;
file.Open(filename, file.modeWrite | file.modeCreate);
for (UINT i = 0; i < m_line; i++)
{
for (UINT j = 0; j < 8; j++)
{
CString s = m_list.GetItemText(i, j);
int strLength2 = s.GetLength() + 1;
char chArray[20];
memset(chArray, 0, sizeof(chArray) ); //将数组的垃圾内容清空.
strncpy_s(chArray, s, strLength2);
file.Write(chArray, sizeof(chArray));
}
}
MessageBox("数据存储成功");
file.Close();
}
}
if (!nodata())
{
MessageBox("列表中没有数据,请先添加");
}
check = TRUE;
}
//——————————————————————————————————————查找————————————————————————————————
void management::reset(UINT i)//把查找的同学原来的行数传过来,将其插入第一行,达到查找效果
{
CString AID = m_list.GetItemText(i, 0);
CString Aname = m_list.GetItemText(i, 1);
CString Axing = m_list.GetItemText(i, 2);
CString Agrade = m_list.GetItemText(i, 3);
CString Aclasss = m_list.GetItemText(i, 4);
CString Aprogram = m_list.GetItemText(i, 5);
CString Amath = m_list.GetItemText(i, 6);
CString Alisan = m_list.GetItemText(i, 7);
m_list.DeleteItem(i);
m_list.InsertItem(0, AID);
m_list.SetItemText(0, 1, Aname);
m_list.SetItemText(0, 2, Axing);
m_list.SetItemText(0, 3, Agrade);
m_list.SetItemText(0, 4, Aclasss);
m_list.SetItemText(0, 5, Aprogram);
m_list.SetItemText(0, 6, Amath);
m_list.SetItemText(0, 7, Alisan);
m_list.SetItemData(0, COLOR_RED); // 给该行设置背景颜色和字体颜色使得更加突出
}
void management::find_q()//查找某学号或某名字的学生的信息
{
if (finds.a == 0 && finds.b != "")
{
for (UINT i = 0; i < m_line; i++)
{
CString s = m_list.GetItemText(i, 1);
if (finds.b == s)
{
reset(i);
finds.b = "";
judge = TRUE;
MessageBox("查找成功");
break;
}
}
if (judge == FALSE)
MessageBox("没有此名字的学生");
}
else if (finds.a == 1 && finds.b != "")
{
for (UINT i = 0; i < m_line; i++)
{
CString s = m_list.GetItemText(i, 0);
if (finds.b == s)
{
reset(i);
finds.b = "";
judge = TRUE;
MessageBox("查找成功");
break;
}
}
if (judge == FALSE)
MessageBox("没有此学号的学生");
}
else
{
MessageBox("请输入一项数据删除");
}
}
void management::OnBnClickedButton4()//查找按钮相应函数
{
if (!nodata())
{
MessageBox("列表中没有数据");
}
while (nodata())
{
if (finds.DoModal() == IDOK)
{
m_list.SetItemData(0, COLOR_DEFAULT);
find_q();
}
if (finds.FA == TRUE)
{
finds.FA = FALSE;
break;
}
}
}
void management::OnCustomdrawList2(NMHDR *pNMHDR, LRESULT *pResult) //这个用于查找时候把提到第一行的学生信息标红
{
LPNMTVCUSTOMDRAW pNMCD = reinterpret_cast<LPNMTVCUSTOMDRAW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
NMCUSTOMDRAW nmCustomDraw = pNMCD->nmcd;
switch (nmCustomDraw.dwDrawStage)
{
case CDDS_ITEMPREPAINT:
{
if (COLOR_RED == nmCustomDraw.lItemlParam)
{
pNMCD->clrTextBk = RGB(255, 0, 0); //背景颜色
pNMCD->clrText = RGB(255, 255, 255);//文字颜色
}
else if (COLOR_DEFAULT == nmCustomDraw.lItemlParam)
{
pNMCD->clrTextBk = RGB(255, 255, 255);
pNMCD->clrText = RGB(0, 0, 0);
}
break;
}
default:
{
break;
}
}
*pResult = 0;
*pResult |= CDRF_NOTIFYPOSTPAINT;
*pResult |= CDRF_NOTIFYITEMDRAW;
return;
}
//——————————————————————————————————————导入————————————————————————————————
void management::OnBnClickedButton5()//导入按钮响应函数
{
glimport dlg;
if (dlg.DoModal() == IDOK && dlg.FA == FALSE)
{
importtt();
}
else if (dlg.FA == TRUE)
{
dlg.FA = FALSE;
int line = m_list.GetItemCount();
for (int i = 0; i < line; i++)
{
m_list.DeleteItem(0);
m_line--;
}
m_stusum = m_line;
UpdateData(FALSE);
importtt();
}
}
void management::importtt()//获得需要导入的学生信息的文件的地址
{
MessageBox("请导入学生信息!");
CFileDialog filedlg(TRUE);
filedlg.m_ofn.lpstrTitle = "请选择文件并导入";
filedlg.m_ofn.lpstrFilter = "所有文件(*.*)\0*.*\0\0";
if (IDOK == filedlg.DoModal())
{
finds.filenaem = filedlg.GetPathName();
UINT num = importt();
if (num == 0)
MessageBox("导入信息成功");
}
}
UINT management::importt()//真正的导入函数主体,管理系统主菜单初始化时就调用了该函数,使得一开始就有若干学生信息
{
CFile file;
file.Open(finds.filenaem, file.modeReadWrite);
Student u;
UINT X = sizeof(u);
while (file.Read(&u, sizeof(u)))
{
m_list.InsertItem(m_line, u.ID);
m_list.SetItemText(m_line, 1, u.name);
m_list.SetItemText(m_line, 2, u.xing);
m_list.SetItemText(m_line, 3, u.grade);
m_list.SetItemText(m_line, 4, u.classs);
m_list.SetItemText(m_line, 5, u.program);
m_list.SetItemText(m_line, 6, u.math);
m_list.SetItemText(m_line, 7, u.lisan);
m_line++;
}
m_stusum = m_line;
UpdateData(FALSE);
file.Close();
return 0;
}
//——————————————————————————————————————修改————————————————————————————————
BOOL management::checknum()//检查成绩是否超出范围
{
if (changes.new_program > 100 || changes.new_math > 100 || changes.new_lisan > 100)
{
MessageBox("成绩输入不合法");
return FALSE;
}
return TRUE;
}
void management::settext(int line)//将新的信息显示出表格里面,没有填的就跳过,只会更新新的信息
{
char c[20] = "0";
char c1[5], c2[5], c3[5];
_itoa_s(changes.new_program, c1, 10);
_itoa_s(changes.new_math, c2, 10);
_itoa_s(changes.new_lisan, c3, 10);
if (changes.new_number != 0)
{
_itoa_s(changes.new_number, c, 10);
m_list.SetItemText(line, 0, c);
}
if(changes.new_grade!="")
m_list.SetItemText(line, 3, changes.new_grade);
if (changes.new_class != "")
m_list.SetItemText(line, 4, changes.new_class);
if (checknum())
{
m_list.SetItemText(line, 5, c1);
m_list.SetItemText(line, 6, c2);
m_list.SetItemText(line, 7, c3);
}
}
void management::findcheck()//个人信息修改函数
{
BOOL f = FALSE;
if (changes.name != "")
{
for (UINT i = 0; i < m_line; i++)
{
if (changes.name == m_list.GetItemText(i, 1))
{
settext(i);
f = TRUE;
}
if (f)
{
MessageBox("成功修改");
break;
}
}
if (!f)
{
MessageBox("查找的人名字可能不符,请检查");
}
}
else {
MessageBox("请输入修改同学的新旧姓名");
}
}
void management::changename()//只修改名字
{
BOOL f = FALSE;
for (UINT i = 0; i < m_line; i++)
{
if (changes.old_name == m_list.GetItemText(i, 1))
{
m_list.SetItemText(i, 1, changes.new_name);
f = TRUE;
}
if (f)
{
MessageBox("成功修改");
break;
}
}
}
void management::OnBnClickedButton6()//修改按钮相应函数
{
// TODO: 在此添加控件通知处理程序代码
while (nodata())
{
changes.old_name = "";
changes.new_name = "";
changes.new_number = 0;
changes.new_program = 0;
changes.new_math = 0;
changes.new_lisan = 0;
changes.new_class = "";
changes.new_grade = "";
if (changes.DoModal() == IDOK)
{
UpdateData(TRUE);
if (changes.cao == 0 && changes.old_name != "")
{
changename();
}
else if (changes.cao == 1 && changes.name != "")
{
findcheck();
}
else
{
MessageBox("请输入该学生的姓名");
}
}
if (changes.FA == TRUE )
{
deletes.FA = FALSE;
break;
}
}
if (!nodata())
{
MessageBox("信息为空,请先添加信息");
}
}
//—————————————————————————————————————排序————————————————————————————————
BOOL cmp(point pt1, point pt2) //利用快排函数sort()的时候会用到,升序
{
return pt1.y < pt2.y;
}
BOOL ccmp(point pt1, point pt2) //利用快排函数sort()的时候会用到,降序
{
return pt1.y > pt2.y;
}
void management::resort(UINT x) //排序函数
{
point *gl = new point[m_line]; //建立动态数组
for (UINT i = 0; i < m_line; i++)
{
CString a = m_list.GetItemText(i, x);
UINT AA = _ttoi(a);
gl[i].x = i;
gl[i].y = AA;
}
if(x==0)
sort(gl, gl + m_line, cmp); //快排
else
sort(gl, gl + m_line, ccmp);
for (int i = 0; i < m_line; i++)
{
CString a = m_list.GetItemText(gl[i].x, 0);
m_list.InsertItem(i+m_line, a);
for (UINT j = 1; j < 8; j++)
{
CString a = m_list.GetItemText(gl[i].x, j);
m_list.SetItemText(i + m_line, j, a);
}
}
for (int i = 0; i <m_line; i++)
{
m_list.DeleteItem(0);
}
delete []gl; //防止内存泄露
}
void management::OnBnClickedButton7()
{
if (!nodata())
{
MessageBox("信息为空,请先添加信息");
}
else resort(0);
}
//——————————————————————————————————————退出————————————————————————————————————
void management::OnBnClickedButton8()
{
if (MessageBox("请确认保存学生信息再退出!", "警告",MB_ICONEXCLAMATION | MB_OKCANCEL)==IDCANCEL)
{
CDialog::OnClose();
}
else
{
CDialogEx::OnCancel();
}
}
//————————————————————————————————————背景图片————————————————————————————————————
void management::OnPaint() //设置背景
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap bmpBackground;
bmpBackground.LoadBitmap(IDB_BITMAP2); //IDB_BITMAP是我的背景图片对应的ID
BITMAP bitmap;
bmpBackground.GetBitmap(&bitmap);
CBitmap *pbmpOld = dcMem.SelectObject(&bmpBackground);
dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialogEx::OnPaint()
}
//———————————————————————————强大的额外删除功能————————————————————————————————————
void management::OnDblclkList2(NMHDR *pNMHDR, LRESULT *pResult) //双击响应
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CRect rc; //矩形
m_Row = pNMListView->iItem;
m_Col = pNMListView->iSubItem;
if (pNMListView->iSubItem != -1) //在listcontrol和edit上操作
{
m_list.GetSubItemRect(m_Row, m_Col, LVIR_LABEL, rc); //获取控件矩形区域
m_edit.SetParent(&m_list); //SetParent 就是把编辑框转到列表框里面
m_edit.MoveWindow(rc);
m_edit.SetWindowText(m_list.GetItemText(m_Row, m_Col));
m_edit.ShowWindow(SW_SHOW);
m_edit.SetFocus();
m_edit.ShowCaret(); //使插入标记在屏幕的当前位置上可见
}
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
}
void management::OnKillfocusEdit2() //失去焦点时响应
{
CString tem;
m_edit.GetWindowText(tem);
m_list.SetItemText(m_Row, m_Col, tem);
m_edit.ShowWindow(SW_HIDE);
// TODO: 在此添加控件通知处理程序代码
}
//———————————————————————————强大的额外排序功能————————————————————————————————————
void management::OnColumnclickList2(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
resort(pNMLV->iSubItem);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
}
void management::OnOK() //重载函数OnOK,防止在修改信息时,不小心按了回车退出,就什么都不用加就行了
{
}
glxtDlg.cpp:
// glxtDlg.cpp: 实现文件
//
#include "stdafx.h"
#include "glxt.h"
#include "glxtDlg.h"
#include "afxdialogex.h"
#include"management.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CglxtDlg 对话框
CglxtDlg::CglxtDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(DIALOG, pParent)
, zhanghao(_T(""))
, mima(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CglxtDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT2, zhanghao);
DDX_Text(pDX, IDC_EDIT1, mima);
}
BEGIN_MESSAGE_MAP(CglxtDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CglxtDlg::OnBnClickedOk)
//ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
// CglxtDlg 消息处理程序
BOOL CglxtDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE);// 设置大图标
SetIcon(m_hIcon, FALSE);// 设置小图标
// TODO: 在此添加额外的初始化代码
SetWindowText("学生信息管理系统");
SetDlgItemText(IDC_EDIT2, "学号");
SetDlgItemText(IDC_EDIT1, "输入密码");
return FALSE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CglxtDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CglxtDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CglxtDlg::OnPaint() //用来添加背景图片
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else //设置背景图
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
CBitmap bmpBackground;
bmpBackground.LoadBitmap(IDB_BITMAP1); //IDB_BITMAP是我设置的图对应的ID
BITMAP bitmap;
bmpBackground.GetBitmap(&bitmap);
CBitmap *pbmpOld = dcMem.SelectObject(&bmpBackground);
dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcMem, 0, 0,bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
}
}
void CglxtDlg::OnBnClickedOk() //按下确定键对账号密码进行判断
{
UpdateData(TRUE);
CString zhang = zhanghao;
CString mi = mima;
if (zhang == "xsglxt" && mi == "123")
{
AfxGetMainWnd()->SendMessage(WM_CLOSE);
management dlgs;
dlgs.DoModal();
}
else if (zhang == "" || mi == "")
{
MessageBox("账号或密码不能为空", "提醒");
return;
}
else
{
MessageBox("账号或密码错误","提醒");
return;
}
UpdateData(FALSE);
CDialogEx::OnOK();
}
BOOL CglxtDlg::PreTranslateMessage(MSG* pMsg) //重载它来处理键盘和鼠标消息,这段代码主要用于当点击编辑框,
{ //会把默认文本清除,比较巧妙,用了特殊的设置密码
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
CEdit* pEdit2 = (CEdit*)GetDlgItem(IDC_EDIT2);
CString s = (CString)"";
if (pMsg->message == WM_LBUTTONDOWN)
{
UpdateData(TRUE);
if (pMsg->hwnd == pEdit->GetSafeHwnd())
{
CEdit * kd = (CEdit*)GetDlgItem(IDC_EDIT1);
kd->SetPasswordChar('*');
pEdit->SetWindowText(_T(""));
if (zhanghao== s) //细节处理
{
pEdit2->SetWindowText("学号");
}
}
else if(pMsg->hwnd == pEdit2->GetSafeHwnd())
{
pEdit2->SetWindowText("");
if (mima == s)
{
CEdit * kd = (CEdit*)GetDlgItem(IDC_EDIT1);
kd->SetPasswordChar(NULL);
pEdit->SetWindowText("输入密码");
}
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}