摘要:本系统根据中南民族大学宿舍管理的实际情况而设计,采用Visual C++为开发工具,数据库采用的是最为普及的小型数据库管理系统Access,能实现宿舍管理中的添加信息、修改信息、删除信息、查询信息等必不可少的功能。
关键字:C++;宿舍管理系统;Access;数据库;MFC编程
1 引言
宿舍,是大学生在高校校园里一个重要的学习、生活、交往的空间环境。随着高校办学规模的扩大,学生人数不断增多,高校学生宿舍管理信息量日益庞大,如果仍采用传统的工作方式——纸媒介的账本化工作模式,会存在获取信息慢、查阅困难、准确性差等问题,很难适应高水平宿舍管理的需要。而采用计算机软件来实现信息的管理能很好的解决传统工作方式存在的问题。因此,我们设计开发了学生宿舍管理系统,旨在提高宿舍管理的效率和准确性,减少工作的盲目性,对后勤管理的现代化建设有一定的指导意义。
2 设计依据及框图
2.1 设计平台
开发本系统的过程中所用到的主要软件开发工具有:Visual C++ 6.0、Access 2000、Photoshop。现将使用情况分别介绍如下:
Visual C++ 6.0: MFC方式设计系统界面,采用OLE DB方式访问数据库。
Access 2000:采用Access设计本系统中的数据库。
Photoshop:用于添加学生、删除学生、查询学生等等按钮图标的美工设计。
2.2 设计思想
(1) 应用原型方法进行开发。原型方法将系统分析、设计、实施三个阶段融为一体,使操作者更便于使用该系统,由中南民族大学宿舍管理的实际情况出发,讲宿舍信息分层设计,有宿舍类型到楼号,由楼号到宿舍号,在找到床铺号,便于层次化管理。(2) 选用灵活、方便、友好的用户界面。采用操作简单的树型图设计,便于查找学生信息,操作快捷方便; (3) 数据库采用的是比较流行的小型数据库管理软件Access,与C++程序的连接方式为OLE DB,该方式可以让开发人员不直接向数据源发出指令,而是通过OLE DB接口与数据提供者进行交互,只需要对接口进行操作,这样简化了程序的设计。
2.3 设计框图、用户界面
本系统“宿舍管理”的设计框图如下:
主界面
“查看学生详细信息”界面
“添加学生”界面
“删除学生”界面
“学生查询”界面
2.4 数据库表结构
本系统采用Access作为数据库,使用OLE DB访问数据库。根据系统功能与需求分析,只需要创建一个数据表House,该表包含学生姓名,性别,入学时间,学号,专业,宿舍类型,楼号,房间号,床铺号,宿舍电话,备注等信息项,自然的形成了一个树型结构。不设置主键(PRIMARY KEY),由程序根据地址唯一确定用户信息的不二性。表结构如右所示:
3各模块功能及主要模块的流程图
3.1 各模块功能简介
1、罗列学生信息
在左边的树试图中,通过鼠标或者键盘选择宿舍类型、楼号或者房间号等树项,右边的列表视图就会罗列出相应宿舍类型、楼或者房间中的所有学生的简要信息。对这些罗列出来的学生可以对它们进行删除或者查看详细信息的操作。
2、查看学生详细信息
选择左边树视图中的房间号,或者双击右边列表视图中的某一学生,右边的视图就会显示该用户的详细信息(见“查看学生详细信息”界面)。
3、添加学生
单击工具条的【添加学生】按钮,或者选择菜单【系统维护】->【添加学生】,弹出“添加学生”对话框,见“添加学生”界面。在该对话框中填写完相应的信息,单击【确定】按钮完成添加。其中“学生姓名”和“宿舍地址”是必须填写完整的,如果不完整单击【确定】按钮后系统会提示用户。
4、删除学生
当程序的输入焦点在左边的树视图时,选择要删除的项,单击工具条的【删除学生】按钮,或者选择菜单【系统维护】->【删除学生】,弹出询问用户确认删除操作的对话框,见“删除学生”界面。如果删除的是宿舍类型,则该宿舍类型中的所有学生都被删除;如果删除是楼号,则该楼中的所有学生被删除,如果删除的是房间号,则该房间中的所有学生都被删除;如果删除的是学生,则该学生信息被删除。
当主窗口的右边是学生的列表视图时,并且输入焦点在其中,选择其中要删除的学生(可以选择多个),单击工具条的【删除学生】按钮,或者选择菜单【系统维护】->【删除学生】,弹出询问用户确认删除操作的对话框,单击【是】按钮删除选择的学生信息。
5、学生查询
单击工具条中的【学生查询】按钮,或者选择菜单【系统维护】->【学生查询】,弹出“查询学生”对话框,见“学生查询”界面。在该对话框中填写完查询条件,单击【确定】按钮。如果有符合条件的学生,在右边的学生列表中就会全部罗列出来,可以对这些学生进行删除或者查看详细信息的操作。
3.2 主要流程图
本软件系统对学生信息的管理主要流程图:
- 在树视图中罗列学生信息的程序流程,如图所示:
- 查询和罗列的程序流程,如图所示:
填充树视图的程序流程 查询和罗列的程序流程
- 增加学生的程序流程,如下图所示:
4 软件调试分析
本软件是基于Windows的编程开发,所以,软件调试必须在Windows环境下进行。调试前须做好以下准备工作:
(1)需要文件 MFC42.DLL、MSVCRT.DLL,如果没有,则安装Visual C++6.0环境;
(2)需要安装Access 2000的OLE DB驱动,如果没有,可以安装Access2000以上版本;
(3)需要将StuDormMS.mdb数据库文件与可执行文件StuDormMS.exe放在同一目录下,才能运行成功。
配置好之后,在Visual C++6.0环境下进行软件的调试。调试分析如下:
(1)首先进行数据库的导入,加入ATL产生的模板类,生成包含数据库的House.H[见附]头文件,该头文件是与数据库的接口,经过测试,数据库链接成功;
(2)实现界面框架,使用类CSplitterWnd切分视图和动态切换视图的类型,通过包含该类的单文件调试发现无错误后,整体系统运行能成功切换试图。
(3)系统框架的左侧为树视图,采用CLeftTreeView类来实现;右侧学生信息罗列采用类CUsersListView来实现,成功调试后能正常显示信息。
(4)“增加学生”模块,单模块调试通过后,需要在整理系统编写完后,再进行操作测试,添加一条记录后,发现在数据库中有保存该记录,如果错误输入,观察是否能正常提示信息。否则修改程序再进行调试。
(5)“查询学生”模块,该模块可以实现单项查询和组合查询,单项查询调试通过后,编写组合查询的代码,再进行调试,看是否能满足要求,并且能正常提示非法查询请求。
(6)“删除学生”模块,可以进行不同层次的删除操作,例如删除宿舍将会删除该宿舍的所有成员,如果只删除某一学生,不会影响到其他成员。本模块测试通过。
经过调试,以上各部分运行正常,能实现预期的功能。
5 结语
5.1 结论与讨论
结论:本文介绍的宿舍管理系统具有界面友好、操作简单、实用性强等特点,并已开发完毕,使用效果良好,初步取得了以下效果: (1) 操作简单,实用性强,能够快速地提供住宿学生的各种基本信息供管理者参考和使用,大大提高了工作效率; (2) 浏览、查询、添加实现数据库管理,纸质文件的流转被电子邮件代替,节约了办公经费; (3) 实现了对数据的智能处理,为领导决策起到了一定的辅助作用; (4) 使宿舍管理工作更加科学化和规范化。
讨论:本文介绍的实现方法适合与小型的数据管理,而且功能比较简单,在一定程度上能解决实际中宿舍管理中的问题。但也存在一些不完善的地方,如需要保存更多的信息,实现更多的功能,需要采用较大型的数据库管理系统,而且未来的管理以网络化为趋势,开发一套可以联网管理的软件系统能给宿舍管理工作带来更大的方便。
参考文献
- 求是科技. Visual C++ 6.0 数据库开发技术与工程实践.北京:人民邮电出版社,2004
- 郑莉,董渊,张瑞丰.C++语言程序设计.北京:清华大学出版社,2003
- (美)Paul J.Fortier等著.数据库技术大全.林瑶等译.北京:电子工业出版社,1999
附录
各类的声明见源代码*.h头文件,数据库连接文件见House.h,完整源代码见电子文档。
现将各功能函数的核心代码列表如下:
文件名称 | 功能说明 |
AddUserDlg.cpp | 添加学生信息 |
LeftTreeView.cpp | 显示树视图,完成删除操作 |
UsersListView.cpp | 实现单项、组合查询功能 |
UserinfoView.cpp | 学生详细信息显示 |
---Beganing of AddUserDlg.cpp---
// AddUserDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Inhabitants.h"
#include "AddUserDlg.h"
#include "InhabitantsDoc.h"
#include "MainFrm.h"
#include "LeftTreeView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CAddUserDlg dialog
CAddUserDlg::CAddUserDlg(CWnd* pParent /*=NULL*/)
: CDialog(CAddUserDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CAddUserDlg)
m_strMajor = _T("");
m_nBuildingNum = 0;
m_nRoomNum = 0;
m_strRemarks = _T("");
m_strHomeTel = _T("");
m_strStudentname = _T("");
m_strId = _T("");
m_strSex = _T("");
m_strNationNal = _T("");
m_nBedNum = 0;
m_strStudentName = _T("");
//}}AFX_DATA_INIT
}
void CAddUserDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAddUserDlg)
DDX_Text(pDX, IDC_EDIT_MAJOR, m_strMajor);
DDX_Text(pDX, IDC_EDIT_BUILDINGNUM, m_nBuildingNum);
DDX_Text(pDX, IDC_EDIT_ROOMNUM, m_nRoomNum);
DDX_Text(pDX, IDC_EDIT_REMARKS, m_strRemarks);
DDX_Text(pDX, IDC_EDIT_HOMETEL, m_strHomeTel);
DDX_Text(pDX, IDC_EDIT_STUDENTNAME, m_strStudentname);
DDX_Text(pDX, IDC_EDIT_ID, m_strId);
DDX_Text(pDX, IDC_EDIT_SEX, m_strSex);
DDX_Text(pDX, IDC_EDIT_NATIONAL, m_strNationNal);
DDX_Text(pDX, IDC_EDIT_BED, m_nBedNum);
DDX_Text(pDX, IDC_EDIT_ROOMTYPE, m_strStudentName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAddUserDlg, CDialog)
//{{AFX_MSG_MAP(CAddUserDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CAddUserDlg message handlers
void CAddUserDlg::OnOK()
{
//判断输入信息的合法性
UpdateData(TRUE);
CEdit* p;
if( m_strStudentname == "" )
{
AfxMessageBox("请填学生姓名");
p = (CEdit*)GetDlgItem(IDC_EDIT_STUDENTNAME);
p->SetFocus();
return;
}
if( m_strStudentName == "" )
{
AfxMessageBox("请填宿舍类型");
p = (CEdit*)GetDlgItem(IDC_EDIT_ROOMTYPE);
p->SetFocus();
return;
}
if( m_nBuildingNum == 0 )
{
AfxMessageBox("楼号不能为零");
p = (CEdit*)GetDlgItem(IDC_EDIT_BUILDINGNUM);
p->SetFocus();
return;
}
if( m_nRoomNum == 0 )
{
AfxMessageBox("房间号不能为零");
p = (CEdit*)GetDlgItem(IDC_EDIT_ROOMNUM);
p->SetFocus();
return;
}
if( m_nBedNum == 0 )
{
AfxMessageBox("床铺号不能为零");
p = (CEdit*)GetDlgItem(IDC_EDIT_BED);
p->SetFocus();
return;
}
CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CInhabitantsDoc* pDoc = (CInhabitantsDoc*)pFrame->GetActiveDocument();
//让用户确认操作
if(this->MessageBox("你真的要添加这条记录?",
"中南民族大学宿舍管理系统",MB_YESNO)==IDNO)
{
CDialog::OnCancel();
return;
}
//增加学生到数据库中
USER user;
user.strRoomtype = m_strStudentName;
user.nBuildingnum = m_nBuildingNum;
user.nRoomnum = m_nRoomNum;
user.nBednum = m_nBedNum;
user.strName = m_strStudentname;
user.strHouseTel = m_strHomeTel;
user.strSex = m_strSex;
user.strNationNal = m_strNationNal;
user.strMajor = m_strMajor;
user.strId = m_strId;
user.strRemarks = m_strRemarks;
switch(pDoc->AddUser(user))
{
case 0:
{ //已经存在该学生了
CString str;
str.Format( "%s%d号楼%d号房间%d号床铺已有学生入住!",
m_strStudentName,m_nBuildingNum,m_nRoomNum,m_nBedNum );
AfxMessageBox( str );
CEdit* p = (CEdit*)GetDlgItem(IDC_EDIT_BED);
p->SetFocus();
return;
break;
}
case 1:
{ //增加成功后刷新左边的树视图
pFrame->m_pLeftView->AddUserToTree(m_strStudentName,
m_nBuildingNum,m_nRoomNum,m_nBedNum);
break;
}
default:
return;
break;
}
CDialog::OnOK();
}
---ENDING of AddUserDlg.cpp---
---Beganing of LeftTreeView.cpp---
// LeftTreeView.cpp : implementation file
//
#include "stdafx.h"
#include "Inhabitants.h"
#include "InhabitantsDoc.h"
#include "LeftTreeView.h"
#include "MainFrm.h"
#include "UsersListView.h"
#include "UserinfoView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CLeftTreeView
IMPLEMENT_DYNCREATE(CLeftTreeView, CTreeView)
CLeftTreeView::CLeftTreeView()
{
}
CLeftTreeView::~CLeftTreeView()
{
}
BEGIN_MESSAGE_MAP(CLeftTreeView, CTreeView)
//{{AFX_MSG_MAP(CLeftTreeView)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
ON_COMMAND(ID_OPERATE_DELETE, OnOperateDelete)
ON_UPDATE_COMMAND_UI(ID_OPERATE_DELETE, OnUpdateOperateDelete)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CLeftTreeView drawing
void CLeftTreeView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/
// CLeftTreeView diagnostics
#ifdef _DEBUG
void CLeftTreeView::AssertValid() const
{
CTreeView::AssertValid();
}
void CLeftTreeView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
#endif //_DEBUG
/
// CLeftTreeView message handlers
//将数据库中的所有学生到加到树中
void CLeftTreeView::AddUsersToTree()
{
CInhabitantsDoc* pDoc = (CInhabitantsDoc*)GetDocument();
if(pDoc==NULL)
return;
//清空树
GetTreeCtrl().DeleteAllItems();
//取数据库中得所有记录
CString strSql = "select * from house";
CCommand<CAccessor<CHouseAccessor> > dbHouse;
long* pCount = new long;
if(dbHouse.Open(pDoc->m_dbHouse.m_session,strSql,NULL,pCount) != S_OK)
{
AfxMessageBox("error");
delete pCount;
return;
}
delete pCount;
if(dbHouse.MoveFirst() == S_OK)
{
do
{
AddUserToTree(dbHouse.m_roomtype,dbHouse.m_buildingnum,
dbHouse.m_roomnum,dbHouse.m_bednum);
}
while( dbHouse.MoveNext() == S_OK );
}
dbHouse.Close();
}
void CLeftTreeView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
//设置树风格
::SetWindowLong(m_hWnd,GWL_STYLE,WS_VISIBLE | WS_TABSTOP
| WS_CHILD | WS_BORDER| TVS_HASBUTTONS
| TVS_LINESATROOT | TVS_HASLINES
| TVS_DISABLEDRAGDROP|TVS_SHOWSELALWAYS);
//为树视图创建图标连表
CInhabitantsApp* pApp = (CInhabitantsApp*)AfxGetApp();
CTreeCtrl* pTreeCtrl = &GetTreeCtrl();
m_ImageList.Create(16,16,ILC_COLOR16,4,4);
m_ImageList.Add(pApp->LoadIcon(IDI_ICON_SECTION));
m_ImageList.Add(pApp->LoadIcon(IDI_ICON_BUILDING));
m_ImageList.Add(pApp->LoadIcon(IDI_ICON_CELL));
m_ImageList.Add(pApp->LoadIcon(IDI_ICON_USER));
pTreeCtrl->SetImageList(&m_ImageList,TVSIL_NORMAL);
//将学生加入树中
AddUsersToTree();
pTreeCtrl->SortChildren(TVI_ROOT);
}
void CLeftTreeView::AddUserToTree(CString strStudentName,int nBuildingNum,int nRoomNum,int nBedNum)
{
HTREEITEM hSectionItem = AddSectionToTree(strStudentName);
HTREEITEM hBuildingItem = AddBuildingToTree(hSectionItem,nBuildingNum);
HTREEITEM hCellItem = AddCellToTree(hBuildingItem,nRoomNum);
if(hCellItem == NULL)
return;
CTreeCtrl* pCtrl = &GetTreeCtrl();
TV_INSERTSTRUCT TCItem;//插入数据项数据结构
TCItem.hParent = hCellItem;
TCItem.hInsertAfter = TVI_LAST;
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽
TCItem.item.lParam=0;//序号
TCItem.item.iImage=3;//正常图标
TCItem.item.iSelectedImage=3;//选中时图标
CString str;
str.Format("%d号床铺",nBedNum);
TCItem.item.pszText = (LPTSTR)(LPCTSTR)str;
pCtrl->InsertItem(&TCItem);
pCtrl->SortChildren(hCellItem);
}
//将宿舍类型加到树视图中
HTREEITEM CLeftTreeView::AddSectionToTree(CString strStudentName)
{
CTreeCtrl* pCtrl = &GetTreeCtrl();
HTREEITEM hRootItem = pCtrl->GetRootItem();
if(hRootItem)
{
while(hRootItem)
{
CString strItemText = pCtrl->GetItemText(hRootItem);
if(strItemText == strStudentName)
return hRootItem;
hRootItem = pCtrl->GetNextSiblingItem(hRootItem);
}
}
TV_INSERTSTRUCT TCItem;//插入数据项数据结构
TCItem.hParent = TVI_ROOT;
TCItem.hInsertAfter = TVI_LAST;
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽
TCItem.item.lParam=0;//序号
TCItem.item.iImage=0;//正常图标
TCItem.item.iSelectedImage=0;//选中时图标
TCItem.item.pszText = (LPTSTR)(LPCTSTR)strStudentName;
HTREEITEM hSectionItem = pCtrl->InsertItem(&TCItem);
pCtrl->SortChildren(TVI_ROOT);
return hSectionItem;
}
HTREEITEM CLeftTreeView::AddBuildingToTree(HTREEITEM hSectionItem, int nBuildingnum)
{
if(hSectionItem == NULL)
return NULL;
CTreeCtrl* pCtrl = &GetTreeCtrl();
CString strBuildingNum;
strBuildingNum.Format("%d号楼",nBuildingnum);
if(pCtrl->ItemHasChildren(hSectionItem))
{
HTREEITEM hItem = pCtrl->GetChildItem(hSectionItem);
while(hItem)
{
CString strItemText = pCtrl->GetItemText(hItem);
if(strItemText == strBuildingNum)
return hItem;
hItem = pCtrl->GetNextSiblingItem(hItem);
}
}
TV_INSERTSTRUCT TCItem;//插入数据项数据结构
TCItem.hParent = hSectionItem;
TCItem.hInsertAfter = TVI_LAST;
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽
TCItem.item.lParam=0;//序号
TCItem.item.iImage=1;//正常图标
TCItem.item.iSelectedImage=1;//选中时图标
TCItem.item.pszText = (LPTSTR)(LPCTSTR)strBuildingNum;
HTREEITEM hBuildingItem = pCtrl->InsertItem(&TCItem);
pCtrl->SortChildren(hSectionItem);
return hBuildingItem;
}
HTREEITEM CLeftTreeView::AddCellToTree(HTREEITEM hBuildingItem, int nRoomnum)
{
if(hBuildingItem == NULL)
return NULL;
CTreeCtrl* pCtrl = &GetTreeCtrl();
CString strRoomNum;
strRoomNum.Format("%d房间",nRoomnum);
if(pCtrl->ItemHasChildren(hBuildingItem))
{
HTREEITEM hItem = pCtrl->GetChildItem(hBuildingItem);
while(hItem)
{
CString strItemText = pCtrl->GetItemText(hItem);
if(strItemText == strRoomNum)
return hItem;
hItem = pCtrl->GetNextSiblingItem(hItem);
}
}
TV_INSERTSTRUCT TCItem;//插入数据项数据结构
TCItem.hParent = hBuildingItem;
TCItem.hInsertAfter = TVI_LAST;
TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;//设屏蔽
TCItem.item.lParam=0;//序号
TCItem.item.iImage=2;//正常图标
TCItem.item.iSelectedImage=2;//选中时图标
TCItem.item.pszText = (LPTSTR)(LPCTSTR)strRoomNum;
HTREEITEM hCellItem = pCtrl->InsertItem(&TCItem);
pCtrl->SortChildren(hBuildingItem);
return hCellItem;
}
void CLeftTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
*pResult = 0;
//获得被选择项
CTreeCtrl* pCtrl = &GetTreeCtrl();
HTREEITEM hSelItem = pCtrl->GetSelectedItem();
m_hHitItem = hSelItem;
//如果没有项被选择,则将右边的列表视图清空
CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
if(hSelItem == NULL)
{
pFrame->SwitchToView(USERSVIEW);
pFrame->m_pUsersView->ShowUsers("");
return;
}
//判断选择项在树中的位置
HTREEITEM hParentItem = pCtrl->GetParentItem(hSelItem);
CString strSql,strStudentName,strBuildingNum,strRoomNum,strBedNum;
if(hParentItem == NULL)
{ //小区
CString strStudentName = pCtrl->GetItemText(hSelItem);
strSql.Format("select * from house where roomtype = '%s'",strStudentName);
pFrame->SwitchToView(USERSVIEW);
pFrame->m_pUsersView->ShowUsers(strSql);
return;
}
hParentItem = pCtrl->GetParentItem(hParentItem);
if(hParentItem == NULL)
{ //楼
strStudentName = pCtrl->GetItemText(pCtrl->GetParentItem(hSelItem));
CString str = pCtrl->GetItemText(hSelItem);
int n = str.Find("号楼");
strBuildingNum = str.Left(n);
strSql.Format("select * from house where roomtype = '%s' and buildingnum = %s",
strStudentName,strBuildingNum);
pFrame->SwitchToView(USERSVIEW);
pFrame->m_pUsersView->ShowUsers(strSql);
return;
}
hParentItem = pCtrl->GetParentItem(hParentItem);
if(hParentItem == NULL)
{ //单元
strStudentName = pCtrl->GetItemText(pCtrl->GetParentItem
(pCtrl->GetParentItem(hSelItem)));
CString str = pCtrl->GetItemText(pCtrl->GetParentItem(hSelItem));
int n = str.Find("号楼");
strBuildingNum = str.Left(n);
str = pCtrl->GetItemText(hSelItem);
n = str.Find("房间");
strRoomNum = str.Left( n );
strSql.Format("select * from house where roomtype = '%s' and buildingnum = %s and roomnum = %s",
strStudentName,strBuildingNum,strRoomNum);
pFrame->SwitchToView(USERSVIEW);
pFrame->m_pUsersView->ShowUsers(strSql);
return;
}
//选择项是房间号,则右边视图显示该住户的详细信息
strStudentName = pCtrl->GetItemText(pCtrl->GetParentItem
(pCtrl->GetParentItem(pCtrl->GetParentItem(hSelItem))));
CString str = pCtrl->GetItemText(pCtrl->GetParentItem
(pCtrl->GetParentItem(hSelItem)));
int n = str.Find("号楼");
strBuildingNum = str.Left(n);
str = pCtrl->GetItemText(pCtrl->GetParentItem(hSelItem));
n = str.Find("房间");
strRoomNum = str.Left( n );
strBedNum = pCtrl->GetItemText(hSelItem);
pFrame->SwitchToView(USERINFOVIEW);
pFrame->m_pUserinfoView->UpdateUserInfo(strStudentName,
atoi(strBuildingNum.GetBuffer(0)),
atoi(strRoomNum.GetBuffer(0)),
atoi(strBedNum.GetBuffer(0)));
}
void CLeftTreeView::OnOperateDelete()
{
if( m_hHitItem == NULL )
return;
CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CInhabitantsDoc* pDoc = (CInhabitantsDoc*)GetDocument();
CTreeCtrl* pCtrl = &GetTreeCtrl();
HTREEITEM hParentItem = pCtrl->GetParentItem( m_hHitItem );
CString strSql;
if( hParentItem == NULL && m_hHitItem != NULL )
{ //宿舍类型
CString strStudentName = pCtrl->GetItemText(m_hHitItem);
strSql.Format("delete * from house where roomtype = '%s'",strStudentName);
if(this->MessageBox("你真的要删除该宿舍区中的所有学生吗?",
"中南民族大学学生宿舍管理系统",MB_YESNO)==IDNO)
return;
}
else if( hParentItem != NULL && pCtrl->GetParentItem(hParentItem) == NULL )
{ //楼
CString strStudentName = pCtrl->GetItemText(pCtrl->GetParentItem(m_hHitItem));
CString str = pCtrl->GetItemText(m_hHitItem);
int n = str.Find("号楼");
CString strBuildingNum = str.Left(n);
strSql.Format("delete * from house where roomtype = '%s' and buildingnum = %s",
strStudentName,strBuildingNum);
if(this->MessageBox("你真的要删除该楼中的所有学生吗?",
"中南民族大学学生宿舍管理系统",MB_YESNO)==IDNO)
return;
}
else if( pCtrl->GetParentItem(hParentItem) != NULL
&& pCtrl->GetParentItem(pCtrl->GetParentItem(hParentItem)) == NULL )
{ //房间
CString strStudentName = pCtrl->GetItemText(
pCtrl->GetParentItem(pCtrl->GetParentItem(m_hHitItem)));
CString str = pCtrl->GetItemText(pCtrl->GetParentItem(m_hHitItem));
int n = str.Find("号楼");
CString strBuildingNum = str.Left(n);
str = pCtrl->GetItemText(m_hHitItem);
n = str.Find("房间");
CString strRoomNum = str.Left( n );
strSql.Format("delete * from house where roomtype = '%s' and buildingnum = %s and roomnum = %s",
strStudentName,strBuildingNum,strRoomNum);
if(this->MessageBox("你真的要删除该房间中的所有学生吗?",
"中南民族大学学生宿舍管理系统",MB_YESNO)==IDNO)
return;
}
else
{ //学生
CString strStudentName = pCtrl->GetItemText(pCtrl->GetParentItem(
pCtrl->GetParentItem(pCtrl->GetParentItem(m_hHitItem))));
CString str = pCtrl->GetItemText(pCtrl->GetParentItem(
pCtrl->GetParentItem(m_hHitItem)));
int n = str.Find("号楼");
CString strBuildingNum = str.Left(n);
str = pCtrl->GetItemText(pCtrl->GetParentItem(m_hHitItem));
n = str.Find("房间");
CString strRoomNum = str.Left( n );
CString strBedNum = pCtrl->GetItemText(m_hHitItem);
strSql.Format("delete * from house where roomtype = '%s' and buildingnum = %s and roomnum = %s and bednum = %s",
strStudentName,strBuildingNum,strRoomNum,strBedNum);
if(this->MessageBox("你真的要删除该学生吗?","中南民族大学学生宿舍管理系统",MB_YESNO)==IDNO)
return;
}
pDoc->DeleteUser(strSql);
AddUsersToTree();
}
void CLeftTreeView::OnUpdateOperateDelete(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_hHitItem != NULL);
}
---ENDING of LeftTreeView.cpp---
---Beganing of QueryDlg.cpp.cpp---
// QueryDlg.cpp : implementation file
//
#include "stdafx.h"
#include "inhabitants.h"
#include "QueryDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CQueryDlg dialog
CQueryDlg::CQueryDlg(CWnd* pParent /*=NULL*/)
: CDialog(CQueryDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CQueryDlg)
m_strMajor = _T("");
m_nBuildingNum = 0;
m_nRoomNum = 0;
m_strRemarks = _T("");
m_strHomeTel = _T("");
m_strStudentname = _T("");
m_strId = _T("");
m_strSex = _T("");
m_strNationNal = _T("");
m_nBedNum = 0;
m_strStudentName = _T("");
//}}AFX_DATA_INIT
}
void CQueryDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CQueryDlg)
DDX_Text(pDX, IDC_EDIT_MAJOR, m_strMajor);
DDX_Text(pDX, IDC_EDIT_BUILDINGNUM, m_nBuildingNum);
DDX_Text(pDX, IDC_EDIT_ROOMNUM, m_nRoomNum);
DDX_Text(pDX, IDC_EDIT_REMARKS, m_strRemarks);
DDX_Text(pDX, IDC_EDIT_HOMETEL, m_strHomeTel);
DDX_Text(pDX, IDC_EDIT_STUDENTNAME, m_strStudentname);
DDX_Text(pDX, IDC_EDIT_ID, m_strId);
DDX_Text(pDX, IDC_EDIT_SEX, m_strSex);
DDX_Text(pDX, IDC_EDIT_NATIONAL, m_strNationNal);
DDX_Text(pDX, IDC_EDIT_BED, m_nBedNum);
DDX_Text(pDX, IDC_EDIT_ROOMTYPE, m_strStudentName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CQueryDlg, CDialog)
//{{AFX_MSG_MAP(CQueryDlg)
ON_LBN_SELCHANGE(IDC_LIST3, OnSelchangeList3)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CQueryDlg message handlers
void CQueryDlg::OnOK()
{
CDialog::OnOK();
}
void CQueryDlg::OnClickTree2(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
}
void CQueryDlg::OnSelchangeList3()
{
// TODO: Add your control notification handler code here
}// QueryDlg.cpp : implementation file
//
#include "stdafx.h"
#include "inhabitants.h"
#include "QueryDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CQueryDlg dialog
CQueryDlg::CQueryDlg(CWnd* pParent /*=NULL*/)
: CDialog(CQueryDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CQueryDlg)
m_strMajor = _T("");
m_nBuildingNum = 0;
m_nRoomNum = 0;
m_strRemarks = _T("");
m_strHomeTel = _T("");
m_strStudentname = _T("");
m_strId = _T("");
m_strSex = _T("");
m_strNationNal = _T("");
m_nBedNum = 0;
m_strStudentName = _T("");
//}}AFX_DATA_INIT
}
void CQueryDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CQueryDlg)
DDX_Text(pDX, IDC_EDIT_MAJOR, m_strMajor);
DDX_Text(pDX, IDC_EDIT_BUILDINGNUM, m_nBuildingNum);
DDX_Text(pDX, IDC_EDIT_ROOMNUM, m_nRoomNum);
DDX_Text(pDX, IDC_EDIT_REMARKS, m_strRemarks);
DDX_Text(pDX, IDC_EDIT_HOMETEL, m_strHomeTel);
DDX_Text(pDX, IDC_EDIT_STUDENTNAME, m_strStudentname);
DDX_Text(pDX, IDC_EDIT_ID, m_strId);
DDX_Text(pDX, IDC_EDIT_SEX, m_strSex);
DDX_Text(pDX, IDC_EDIT_NATIONAL, m_strNationNal);
DDX_Text(pDX, IDC_EDIT_BED, m_nBedNum);
DDX_Text(pDX, IDC_EDIT_ROOMTYPE, m_strStudentName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CQueryDlg, CDialog)
//{{AFX_MSG_MAP(CQueryDlg)
ON_LBN_SELCHANGE(IDC_LIST3, OnSelchangeList3)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CQueryDlg message handlers
void CQueryDlg::OnOK()
{
CDialog::OnOK();
}
void CQueryDlg::OnClickTree2(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
}
void CQueryDlg::OnSelchangeList3()
{
// TODO: Add your control notification handler code here
}
---ENDING of QueryDlg.cpp.cpp---
---Beganing of UserinfoView.cpp---
// UserinfoView.cpp : implementation file
//
#include "stdafx.h"
#include "Inhabitants.h"
#include "UserinfoView.h"
#include "InhabitantsDoc.h"
#include "House.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CUserinfoView
IMPLEMENT_DYNCREATE(CUserinfoView, CFormView)
CUserinfoView::CUserinfoView()
: CFormView(CUserinfoView::IDD)
{
//{{AFX_DATA_INIT(CUserinfoView)
m_nBuildingnum = 0;
m_nRoomnum = 0;
m_strStudentname = _T("");
m_nBednum = 0;
m_strRoomtype = _T("");
m_strMajor = _T("");
m_strRemarks = _T("");
m_strHouseTel = _T("");
m_strId = "";
m_strSex = _T("");
m_strNationNal = _T("");
//}}AFX_DATA_INIT
}
CUserinfoView::~CUserinfoView()
{
}
void CUserinfoView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CUserinfoView)
DDX_Text(pDX, IDC_EDIT_BUILDINGNUM, m_nBuildingnum);
DDX_Text(pDX, IDC_EDIT_ROOMNUM, m_nRoomnum);
DDX_Text(pDX, IDC_EDIT_STUDENTNAME, m_strStudentname);
DDX_Text(pDX, IDC_EDIT_BED, m_nBednum);
DDX_Text(pDX, IDC_EDIT_ROOMTYPE, m_strRoomtype);
DDX_Text(pDX, IDC_EDIT_MAJOR, m_strMajor);
DDX_Text(pDX, IDC_EDIT_REMARKS, m_strRemarks);
DDX_Text(pDX, IDC_EDIT_HOMETEL, m_strHouseTel);
DDX_Text(pDX, IDC_EDIT_ID, m_strId);
DDX_Text(pDX, IDC_EDIT_SEX, m_strSex);
DDX_Text(pDX, IDC_EDIT_NATIONAL, m_strNationNal);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CUserinfoView, CFormView)
//{{AFX_MSG_MAP(CUserinfoView)
ON_EN_CHANGE(IDC_EDIT_REMARKS, OnChangeEditRemarks)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CUserinfoView diagnostics
#ifdef _DEBUG
void CUserinfoView::AssertValid() const
{
CFormView::AssertValid();
}
void CUserinfoView::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
#endif //_DEBUG
/
// CUserinfoView message handlers
//显示住址为strStudentName宿舍类型nBuildingNum号楼nRoomNum房间号nBedNum床铺的住户的详细信息
void CUserinfoView::UpdateUserInfo(CString strStudentName,int nBuildingNum,int nRoomNum,int nBedNum)
{
//查询该学生
CString strSql;
strSql.Format("select * from house where roomtype = '%s' and buildingnum = %d and roomnum = %d and bednum = %d",
strStudentName,nBuildingNum,nRoomNum,nBedNum);
CInhabitantsDoc* pDoc = (CInhabitantsDoc*)GetDocument();
CCommand<CAccessor<CHouseAccessor> > dbHouse;
long* pCount = new long;
if(dbHouse.Open(pDoc->m_dbHouse.m_session,strSql,NULL,pCount) != S_OK)
{
AfxMessageBox("error");
delete pCount;
return;
}
//显示信息
if(dbHouse.MoveFirst() == S_OK)
{
m_strStudentname = dbHouse.m_studentname;
m_strRoomtype = dbHouse.m_roomtype;
m_nBuildingnum = dbHouse.m_buildingnum;
m_nRoomnum = dbHouse.m_roomnum;
m_nBednum = dbHouse.m_bednum;
m_strHouseTel = dbHouse.m_housetel;
m_strSex = dbHouse.m_sex;
m_strNationNal = dbHouse.m_national;
m_strMajor = dbHouse.m_major;
m_strId = dbHouse.m_id;
m_strRemarks = dbHouse.m_remarks;
}
dbHouse.Close();
UpdateData(FALSE);
}
void CUserinfoView::OnChangeEditRemarks()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CFormView::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
}
---ENDING of UserinfoView.cpp---
---Beganing of UsersListView.cpp---
// UsersListView.cpp : implementation file
//
#include "stdafx.h"
#include "Inhabitants.h"
#include "UsersListView.h"
#include "InhabitantsDoc.h"
#include "MainFrm.h"
#include "House.h"
#include "UserinfoView.h"
#include "LeftTreeView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CUsersListView
IMPLEMENT_DYNCREATE(CUsersListView, CListView)
CUsersListView::CUsersListView()
{
}
CUsersListView::~CUsersListView()
{
}
BEGIN_MESSAGE_MAP(CUsersListView, CListView)
//{{AFX_MSG_MAP(CUsersListView)
ON_WM_LBUTTONDBLCLK()
ON_COMMAND(ID_OPERATE_DELETE, OnOperateDelete)
ON_WM_RBUTTONDOWN()
ON_UPDATE_COMMAND_UI(ID_OPERATE_DELETE, OnUpdateOperateDelete)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CUsersListView drawing
void CUsersListView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/
// CUsersListView diagnostics
#ifdef _DEBUG
void CUsersListView::AssertValid() const
{
CListView::AssertValid();
}
void CUsersListView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}
#endif //_DEBUG
/
// CUsersListView message handlers
void CUsersListView::SetListCtrlStyle()
{
DWORD dwStyle = GetWindowLong(m_hWnd, GWL_STYLE);
dwStyle &= ~(LVS_TYPEMASK);
dwStyle &= ~(LVS_EDITLABELS);
// Make sure we have report view and send edit label messages.
SetWindowLong( m_hWnd, GWL_STYLE,
dwStyle | LVS_REPORT|LVS_NOLABELWRAP|LVS_SHOWSELALWAYS);
// Enable the full row selection and the drag drop of headers.
DWORD styles = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES;
// Use macro since this is new and not in MFC.
ListView_SetExtendedListViewStyleEx(m_hWnd, styles, styles );
}
void CUsersListView::SetTitle()
{
TCHAR rgtsz[5][10] = {_T("学生姓名"),_T("宿舍类型"),_T("所属楼号"),
_T("所属房间"),_T("床铺号")};
LV_COLUMN lvcolumn;
CRect rect;
this->GetWindowRect(&rect);
for(int i=0;i<5;i++)
{
lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT
| LVCF_WIDTH | LVCF_ORDER;
lvcolumn.fmt = LVCFMT_LEFT;
lvcolumn.pszText = rgtsz[i];
lvcolumn.iSubItem = i;
lvcolumn.iOrder = i;
lvcolumn.cx = rect.Height()/3;
GetListCtrl().InsertColumn(i, &lvcolumn);
}
}
void CUsersListView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
SetListCtrlStyle();
SetTitle();
}
void CUsersListView::ShowUsers(CString strSql)
{
CListCtrl* p = &GetListCtrl();
//清空列表
p->DeleteAllItems();
if(strSql == "")
return;
CInhabitantsDoc* pDoc = (CInhabitantsDoc*)GetDocument();
CCommand<CAccessor<CHouseAccessor> > dbHouse;
long* pCount = new long;
//按照strSql查询符合条件的学生
if(dbHouse.Open(pDoc->m_dbHouse.m_session,strSql,NULL,pCount) != S_OK)
{
AfxMessageBox("error");
delete pCount;
return;
}
int iItem = 0;
LV_ITEM lvitem;
int iActualItem = 0;
//将查询得到的学生都逐个加入列表中
if(dbHouse.MoveFirst() == S_OK)
{
do
{
for(int iSubItem=0;iSubItem<5;iSubItem++)
{
lvitem.mask = LVIF_TEXT|(iSubItem == 0? LVIF_IMAGE : 0);
lvitem.iItem = (iSubItem == 0)? iItem : iActualItem;
lvitem.iSubItem = iSubItem;
lvitem.iImage = (iItem%2)?0:2;
CString str = "";
switch(iSubItem)
{
case 0://学生
str = dbHouse.m_studentname;
lvitem.pszText =(LPTSTR)(LPCTSTR)str;
break;
case 1://宿舍类型
{
str = dbHouse.m_roomtype;
lvitem.pszText = (LPTSTR)(LPCTSTR) str;
break;
}
case 2://楼号
{
str.Format("%d",dbHouse.m_buildingnum);
lvitem.pszText = (LPTSTR)(LPCTSTR) str;
break;
}
case 3://房间号
{
str.Format("%d",dbHouse.m_roomnum);
lvitem.pszText = (LPTSTR)(LPCTSTR)str;
break;
}
case 4://床铺号
{
str.Format("%d",dbHouse.m_bednum);
lvitem.pszText = (LPTSTR)(LPCTSTR)str;
}
}
if (iSubItem == 0)
iActualItem = GetListCtrl().InsertItem(&lvitem);
else
GetListCtrl().SetItem(&lvitem);
}
iItem ++;
}
while( dbHouse.MoveNext() == S_OK );
}
dbHouse.Close();
}
void CUsersListView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CListView::OnLButtonDblClk(nFlags, point);
//获得双击的项
CListCtrl* pCtrl = &GetListCtrl();
int nHitItem = pCtrl->HitTest(point,NULL);
if( nHitItem < 0 )
return;
CString strStudentName = pCtrl->GetItemText(nHitItem,1);
CString strBuildingNum = pCtrl->GetItemText(nHitItem,2);
CString strRoomNum = pCtrl->GetItemText(nHitItem,3);
CString strBedNum = pCtrl->GetItemText(nHitItem,4);
CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
CInhabitantsDoc* pDoc = (CInhabitantsDoc*)GetDocument();
pFrame->SwitchToView(USERINFOVIEW);
pFrame->m_pUserinfoView->UpdateUserInfo(strStudentName,atoi(strBuildingNum.GetBuffer(0)),
atoi(strRoomNum.GetBuffer(0)),atoi(strBedNum.GetBuffer(0)));
}
void CUsersListView::OnOperateDelete()
{
CListCtrl* pCtrl = &GetListCtrl();
POSITION pos = pCtrl->GetFirstSelectedItemPosition();
if( pos == NULL )
{
AfxMessageBox("请选择要删除的学生");
return;
}
if(this->MessageBox("你真的要删除选择的所有学生吗?",
"中南民族大学宿舍管理系统",MB_YESNO)==IDNO)
return;
//删除选择的所有学生
while (pos)
{
int nHitItem = pCtrl->GetNextSelectedItem(pos);
CString strStudentName = pCtrl->GetItemText(nHitItem,1);
CString strBuildingNum = pCtrl->GetItemText(nHitItem,2);
CString strRoomNum = pCtrl->GetItemText(nHitItem,3);
CString strBedNum = pCtrl->GetItemText(nHitItem,4);
CString strSql;
strSql.Format("delete * from house where roomtype = '%s' and buildingnum = %s and roomnum = %s and bednum = %s",
strStudentName,strBuildingNum,strRoomNum,strBedNum);
CInhabitantsDoc* pDoc = (CInhabitantsDoc*)GetDocument();
pDoc->DeleteUser(strSql);
}
CMainFrame* pFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;
pFrame->m_pLeftView->AddUsersToTree();
}
void CUsersListView::OnUpdateOperateDelete(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetListCtrl().GetFirstSelectedItemPosition() != NULL);
}
---ENDING of UsersListView.cpp---
致谢
本宿舍管理系统的开发得到了中南民族大学电信学院的大力支持,为我们提供了很舒适的上机环境和网络服务。感谢喻胜辉老师对我们的指导,为系统的成功开发提供了许多有价值的参考意见和建议,还要感谢和我同组的郑允富、雷惠珍同学,与他们合作很愉快,也正因为和他们的合作本系统才能得以顺利的完成,感谢他们为系统开发所作出的努力。