先看个效果图:
使用的是MFC编程;
课程设计的要求
1.学生作业管理系统
问题描述:设计一个学生作业管理系统,实现对学生作业提交情况的检查、查询、文件名的规范等操作。
系统运行要求:
(1)“学生信息表”已经存在,初始为教师的教务管理系统中导出的点名表,是Excel表格,具体表格见附件一。
(2)学生提交的作业文档已存在,并保存在同一目录下,作业文件名由学号+姓名组成。
系统基本要求: 程序采用图形界面下进行交互的工作方式,完成如下功能:
(1)规范学生作业文件名
往往有同学上交的文件没有按照规范命名,这些文件名中可能包含了学号和姓名,但顺序不对;或者除学号、姓名外有其他信息;或者只有学号、只有姓名等;对不规范的命名文件要能够进行重命名,顺序不对的进行调整;信息多余的予以删除;信息不全的则到学生信息表中查找补充;对无法规范的文件名统一管理报告,保存到专门的不规范文件列表文件unnamed.txt,并能够随时打开显示。能够规范的文件在生成规范的文件名后以新文件名对老的文件名进行修改。
(2)多种方式建立学生作业信息
l 规范后的每个学生的作业文件放在一个目录下,通过读取这些文件名形成学生作业信息表,表中每个节点代表一个学生的作业信息,至少包括学生的学号、姓名、作业文件存放路径,并将作业提交情况信息添加到“学生信息表”保存,在该表中标记已交和未交学生情况;同时将作业信息表保存到StudentFile.txt;
l 若在目录中新存入一个文件,则可允许通过手工录入的方式录入作业信息,同时更新StudentFile.txt和“学生信息表”;
l 也可以导入某个路径下存放学生作业信息的文本文件。
(3)检查浏览学生作业提交情况及作业文档
l 以列表方式显示所有学生的作业提交信息,区别已交学生和未交学生
l 可选中某一学生,调用word等编辑器打开其作业文档
(4)按照学号对所有学生信息进行升序、降序排列,并输出
l 可选用冒泡、选择、快速排序等算法;
l 不仅输出屏幕显示,还可根据需要写入相关信息文件。
(5)按姓名、学号等方式,实现对学生作业信息的精确查询、模糊查询,输出屏幕显示,并能调用word等编辑器打开选中学生的作业文档
l 精确查询结果演示
查询“姓名是刘梅”同学信息,则输出
学号 姓名 作业提交情况 作业文件
2004112011 刘梅 已交 c:\file\2004112011刘梅.doc
查询“作业提交情况是未交”的同学信息,则输出
学号 姓名 作业提交情况 作业文件
2004112012 刘强 未交
2004112021 张计 未交
2004112037 赵冈 未交
…
l 模糊查询结果演示
查询“姓刘”的同学信息,则输出
学号 姓名 作业提交情况 作业文件
2004112011 刘梅 已交 c:\file\2004112011刘梅.doc
2004112012 刘强 未交
2004112013 刘星 已交 c:\file\2004112013刘星.doc
l 能够实现连续多次查询,并根据用户要求将查询结果保存为文件
(6)学生作业信息的插入、删除、修改。
l 通过插入、删除和修改后,保持所有学生信息的有序性;
l 插入、删除和修改后,对存放所有学生信息的文件及时更新。
(7)数据的统计功能
l 统计已交学生名单;
l 统计未交学生名单;
l 将上述统计结果,根据用户需要写入相应文件。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
可编辑部分
一. 当单击list控件的单元框时实现可编辑
1. 前提是list控件的风格是表格格式
CListCtrl::SetExtendedStyle(LVS_EX_GRIDLINES)设置为LVS_EX_GRIDLINES风格,这样可以看到单元格,不设置也可以,不过看不到相应的一行
2. 获取鼠标的位置
在list控件上添加鼠标单击事件,生成的函数为OnClickList1(NMHDR* pNMHDR, LRESULT* pResult);
在函数里可以进行强制转换NM_LISTVIEW *pEditCtrl = (NM_LISTVIEW *)pNMHDR;
这样pEditCtrl->iSubItem表示单击的是第几列,pEditCtrl->iItem表示的是单击了第几行,这样既可以确定鼠标单击的位置
3. 创建虚拟的Edit控件
在单击鼠标的位置创建该控件,然后再该控件输入内容,然后获取该控件的内容,显示在list控件的相应的单元框中,然后把Edit销毁,每单击一次鼠标,就
创建一次,然后销毁(还有一种不用销毁控件方法就是把控件隐藏,用的时候在显示,显示:m_Edit.ShowWindow(SW_SHOW),隐藏:m_Edit.ShowWindow(SW_HIDE);)
定义一个CEdit类得对象CEdit m_Edit;然后利用该类的Create()函数
我的代码:
m_Edit.Create(ES_AUTOHSCROLL|WS_CHILD|ES_LEFT|ES_WANTRETURN|WS_BORDER,CRect(0,0,0,0),this,IDC_EDIT);
//IDC_EDIT已近在头文件中定义,这个很重要,很多时候会忽略,
//网上找到的实现编辑办法中这个都没说明
//我定义为#define IDC_EDIT 0xffff
设置编辑框的字体:
m_Edit.SetFont(this->GetFont(),FALSE);//设置字体
设置框的大小:
CRect EditRect;
EditRect.SetRect(EditRect.left,EditRect.top,EditRect.left+m_list.GetColumnWidth(m_SubItem),EditRect.bottom);
//m_list.GetColumnWidth(m_SubItem)获取列的宽度
在显示Edit控件之前要设置父窗口,因为要在list控件上显示,所以将该控件设置为父窗口
m_Edit.SetParent(&m_list); //将list control设置为父窗口,生成的Edit才能正确定位,这个也很重要,
显示控件:
m_Edit.MoveWindow(&EditRect);
m_Edit.ShowWindow(SW_SHOW);
在Edit控件内输出内容:
m_Edit.SetWindowText();
获取控件内的内容:
m_Edit.GetWindowText();
在创建Edit控件前最好判断该控件存在不存在,若存在先销毁然后再创建
if (m_Edit.m_hWnd != NULL)
{
m_Edit.ShowWindow(SW_HIDE);
m_Edit.DestroyWindow();
}
4. 创建一个下拉式Combo Box控件
定义一个CComboBox类的对象CComboBox m_comBox;
创建
m_comBox.Create(WS_CHILD|WS_VISIBLE|CBS_SORT|CBS_DROPDOWN|CBS_OEMCONVERT,CRect(0,0,80,80),this,0xffff); //CBS_OEMCONVERT 实现可编辑 //CBS_DROPDOWN 产生一个下拉式框,小图标
//CBS_DROPDOWNLIST 图标代替单元格
添加下拉框的选项
//添加选项
m_comBox.AddString("已交"); m_comBox.AddString("未交");
还有在单击的位置显示该Box控件,获取内容,销毁控件的方法和Edit控件方法一样
二 . 在list控件中
插入一行
m_list.InsertItem(item,iSubItem);
//item行数,从0开始
//iSubItem列数,从0开始
//修改一行的各个单元框的内容
m_list.SetItemText(item,iSubItem,"内容");
插入一列
m_list.InsertColumn(0,"学号",LVCFMT_LEFT,100);
m_list.InsertColumn(1,"姓名",LVCFMT_LEFT,100);
m_list.InsertColumn(2,"作业情况",LVCFMT_LEFT,100);
m_list.InsertColumn(3,"作业文件",LVCFMT_LEFT,rect.Width()-3*100);
第一个参数是列数,第二个参数是内容,第三个参数是对齐内容(左对齐,右对齐,中间对齐),第四个是宽度
获取list控件中选中的已行
m_list.GetSelectionMark(); //选中的一行
返回选中的行数
//如果list control中有数据则全部删除
if (m_list.GetItemCount() != 0)
{
m_list.DeleteAllItems(); //删除所有行 while(m_list.DeleteColumn(0)); //删除所有列
}
获取总行数
m_list.GetItemCount()
获取总的列数
m_list.GetHeaderCtrl()->GetItemCount()
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
双击打开作业
ShellExecute(this->m_hWnd,"open","WINWORD.EXE",filepath,NULL,SW_SHOWDEFAULT);
第三个参数是要调用的程序,第四个是要打开的文件的路径
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
单击右键菜单
先添加一个菜单,设计好菜单后,可以使用类向导关联相应的函数,
CPoint point;
CMenu Menu;
GetCursorPos(&point); //获取鼠标位置
Menu.LoadMenu(IDR_MENU1); //加载菜单
Menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,this);
//显示菜单
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
弹出选择文件的对话框
//弹出对话框,默认打开Excel文件,可以选择
CFileDialog fileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Excel文件(*.xls)|*.xls|文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||");
获取选中的文件的路径
CString strPathName;
strPathName = fileDlg.GetPathName(); //获取文件路径
CString str = strPathName.Right(3); //获取后面3为字符
弹出选择文件夹的对话框
char szSelected[MAX_PATH];//用来存放文件夹路径
//选择文件夹框
BROWSEINFO bi;
LPITEMIDLIST pidl;
bi.hwndOwner = this->m_hWnd;
bi.pidlRoot = NULL;
bi.pszDisplayName = szSelected;
bi.lpszTitle = "选择作业文件路径:";
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.lParam = NULL;
bi.iImage = NULL;
if((pidl = SHBrowseForFolder(&bi)) != NULL)
{
if(SUCCEEDED(SHGetPathFromIDList(pidl,szSelected)))//得到文件夹的全路径,不要的话,只得本文件夹名
{
strcpy(SPath,szSelected);
}
}
CString str;
str.Format("是否要删除?\n学号: %s\n姓名: %s\n作业情况: %s\n作业文件: %s\n",
pDel->pNext->stuNo,pDel->pNext->stuName,pDel->pNext->stuWork,pDel->pNext->stuWorKPath);
if (MessageBox(str,"警告", MB_ICONWARNING|MB_YESNO) == IDYES) //确定是否删除
{
pTemp = pDel->pNext;
pDel->pNext = pTemp->pNext;
free(pTemp);
m_list.DeleteItem(item);
}
效果: