需求分析
采用面向对象设计思想,管理2类人员。教师信息(姓名,编号,年龄,职称,学历,籍贯,工作日期,管理员编号),学生信息(姓名,年龄,学号,籍贯,入学日期,指导老师编号,管理员编号)。完整输入/输出设计,写入ACCESS文件,分别建立两个表信息,一个存储教师信息,一个存储学生信息。采用工程文件方式组织程序。能进行增、 删、 查、改等操作。还有一个管理员表,记录管理员的用户名和密码,初始完成密码认证框的编写。
概念结构设计(E-R图)
逻辑结构设计
①ACCESS表
表password:
Puser | 文本 | Ppassword | 文本 |
Pisadmin | 是/否 |
Sname | 文本 | Sno | 文本 |
Sage | 文本 | Snative | 文本 |
Setime | 文本 | Tno | 文本 |
Tname | 文本 | Tno | 文本 |
Tage | 文本 | Ttitle | 文本 |
Tdegree | 文本 | Tnative | 文本 |
Twtime | 文本 |
表teacher的主码为Tno。
详细设计
1.MFC类
class CUserSet : public CRecordset //用户数据定义
{
CString m_Puser;
CString m_Ppassword;
BOOL m_Pisadmin;
}
class CStudentSet : public CRecordset //学生数据定义
{
CString m_Sname;
CString m_Sno;
CString m_Sage;
CString m_Snative;
CString m_Setime;
}
class CTeacherSet : public CRecordset //教师数据定义
{
CString m_Tname;
CString m_Tno;
CString m_Tage;
CString m_Ttitle;
CString m_Tdegree;
CString m_Tnative;
CString m_Twtime;
}
2.模块设计
系统共分成五个模块,分别是:用户登录模块,用户管理模块,学生信息查询模块,学生信息编辑模块,教师信息编辑模块。
3.使用说明
登录系统时可根据ACCESS表password查看用户名和密码。无需建立ODBC。
登录成功后显示主菜单,有系统管理,学生信息管理,教师信息管理。在系统管理中,你可以进行用户管理,注销/重新登录和退出系统。在学生信息管理中,你可以进行学生信息查询和添加/修改信息。教师信息管理中,你可以进行教师信息查询和添加/修改信息。在帮助中,你可以查看软件的相关内容。
特别提醒:如果你的登录是非管理员,那么你将没有用户管理,添加/修改信息等操作。
在用户管理中,你可以修改密码,新增用户,删除用户。
在信息查询中,你可以通过编号查询或姓名查询。可以同时输入或不输,若不输则显示全部信息。
在添加/修改信息中,你可以对信息进行添加,修改,删除等操作。
4.测试结果与分析
运行程序,显示登录界面。(管理员建议使用:用户名“aaa”,密码“1234”)
成功登录后显示主界面。然后根据内容依次运行。
这是用户信息界面。以管理员身份进入该界面。
这是新增加用户“ddd”后的操作结果。
这是学生信息查询界面。若不输入查询项查询,则显示所有数据。
这是根据学生学号查询。
显示,添加,修改,删除一体化。根据所需要的操作进行操作。新增007号学生胡夏的操作与结果。
图为教师信息编辑。操作方法如同学生信息编辑
课程设计总结
在这次课程设计中,是三张ACCESS表,一张储存用户名和密码,一张储存学生信息,还有一张储存教师信息。创建对话框三个,分别对应。内容简单,功能也满足要求,但是缺乏创新。于是在此基础上又加入了注册和修改密码。反复改,反复改,不知不觉的一个工程做了好几遍。
首先是创建ODBC,从需要自己创建ODBC开始到程序生成ODBC,再有就是采用列表控件,只要会了方法,输出信息非常方便。原来我程序思想是在学生信息中分为查询、添加、修改、删除等模块,现在进行统一,查询还是查询系统,添加、修改和删除融合成一个编辑系统。教师也是一样。在对于用户,也不局限于一旦创建只能修改密码,现在还可以注销账号。最后是各个功能的衔接,用菜单来调用。同时根据是否是管理员进行判定某些操作是否可用。
附录:源程序代码(核心部分代码)
文件: Rygl.cpp :
#include "stdafx.h"
#include "Rygl.h"
#include"LoginDlg.h"
#include "MainFrm.h"
#include "RyglSet.h"
#include "RyglDoc.h"
#include "RyglView.h"
#include "LoginDlg.h"
//#include "SkinPlusPlus.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// CRyglApp
BEGIN_MESSAGE_MAP(CRyglApp, CWinApp)
//{{AFX_MSG_MAP(CRyglApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
// Standard print setup command
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
// CRyglApp construction
CRyglApp::CRyglApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CRyglApp object
CRyglApp theApp;
// CRyglApp initialization
BOOL CRyglApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
/* SQLConfigDataSource(NULL,ODBC_ADD_DSN, //通过程序创建ODBC
"Microsoft Access Driver (*.mdb)
"DSN=WhODBC\\0"
"Description=Hotel\\0"
"FileType=Access\\0"
"DBQ=.\\\\Wh.mdb\\0 );
*/
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
LoginDlg login;
login.DoModal();
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CRyglDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CRyglView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
m_pMainWnd->SetWindowText("人员管理系统"); //显示主菜单标题
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CRyglApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CRyglApp message handlers
文件: StudenteDlg.cpp
#include "stdafx.h"
#include "Rygl.h"
#include "StudenteDlg.h"
#include"StudentSet.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// CStudenteDlg dialog
CStudenteDlg::CStudenteDlg(CWnd* pParent /*=NULL*/)
: CDialog(CStudenteDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CStudenteDlg)
m_valSname = _T("");
m_valSno = _T("");
m_valSage = _T("");
m_valSnative = _T("");
m_valSetime = _T("");
//}}AFX_DATA_INIT
}
void CStudenteDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CStudenteDlg)
DDX_Control(pDX, IDC_LIST1, m_ctlList);
DDX_Text(pDX, IDC_EDIT1, m_valSname);
DDX_Text(pDX, IDC_EDIT2, m_valSno);
DDX_Text(pDX, IDC_EDIT3, m_valSage);
DDX_Text(pDX, IDC_EDIT4, m_valSnative);
DDX_Text(pDX, IDC_EDIT5, m_valSetime);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CStudenteDlg, CDialog)
//{{AFX_MSG_MAP(CStudenteDlg)
ON_BN_CLICKED(IDC_BUTTON2, OnSeaddnew)
ON_BN_CLICKED(IDC_BUTTON4, OnSedelete)
ON_BN_CLICKED(IDC_BUTTON5, OnSeonall)
ON_BN_CLICKED(IDC_BUTTON3, OnSeedit)
ON_BN_CLICKED(IDC_BUTTON6, OnCancel)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CStudenteDlg message handlers
BOOL CStudenteDlg::OnInitDialog()
{ CDialog::OnInitDialog();
m_ctlList.InsertString(0,"学生学号 学生姓名 学生年龄 学生籍贯 入学日期");
m_ctlList.SetColumnWidth(120);
m_ctlList.SetColumnWidth(90);
m_ctlList.SetColumnWidth(60);
m_ctlList.SetColumnWidth(90);
m_ctlList.SetColumnWidth(155);
// m_ctlList.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
CStudentSet recordset; //初始化学生信息
if(!recordset.Open(AFX_DB_USE_DEFAULT_TYPE,"select * from student"))
{ MessageBox("打开数据库失败!数据库错误",MB_ICONSTOP);
return FALSE;
}
recordset.Close();
return TRUE;
}
void CStudenteDlg::OnSeaddnew()
{
// TODO: Add your control notification handler code here
UpdateData( TRUE );
CStudentSet m_recordset;
if(m_valSname.IsEmpty())
{ MessageBox("请输入学生姓名!");
return; }
if(m_valSno.IsEmpty())
{ MessageBox("请输入学生学号!");
return;
}
if(m_valSage.IsEmpty())
{ MessageBox("请输入学生年龄!");
return; }
if(m_valSnative.IsEmpty())
{ MessageBox("请输入学生籍贯!");
return; }
if(m_valSetime.IsEmpty())
{ MessageBox("请输入学生入学日期!");
return; }
CString str="select * from student";
int flag=0;
if( !m_recordset.Open( AFX_DB_USE_DEFAULT_TYPE , _T(str) ) )
{ MessageBox("打开数据库失败!数据库错误",MB_ICONSTOP);
return ; }
while( !m_recordset.IsEOF() )
{ if( m_valSno == m_recordset.m_Sno )
{ flag=1;
break; }
else
{ m_recordset.MoveNext(); }
}
if( flag==1)
{ MessageBox( "已有此人,添加失败!", "学生信息", MB_ICONEXCLAMATION);
return; }
//添加学生记录
m_recordset.AddNew();
m_recordset.m_Sno = m_valSno;
m_recordset.m_Sname = m_valSname;
m_recordset.m_Sage = m_valSage;
m_recordset.m_Snative= m_valSnative;
m_recordset.m_Setime = m_valSetime;
m_recordset.Update();
m_recordset.Close();
//更新列表
CStudenteDlg::OnSeonall();
//更新界面显示
m_valSno = _T("");
m_valSname = _T("");
m_valSage = _T("");
m_valSnative = _T("");
m_valSetime = _T("");
UpdateData(FALSE);
}
void CStudenteDlg::OnSedelete()
{
// TODO: Add your control notification handler code here
int i = m_ctlList.GetAnchorIndex();
if(0>i)
{ MessageBox("请选择一条记录进行删除!");
return; }
CString strSQL;
CStudentSet m_recordset;
strSQL.Format("select * from student where Sno = '%s' ",m_ctlList.GetItemRect(i,0));
if(!m_recordset.Open(AFX_DB_USE_DEFAULT_TYPE,strSQL))
{ MessageBox("打开数据库失败!");
return ; }
if (MessageBox( "你确定吗?", "删除信息", MB_OKCANCEL)==IDCANCEL)
{ return; }
m_recordset.Delete();
m_recordset.Close();
// m_ctlList.DeleteItem(i);
//更新界面显示
m_valSno = _T("");
m_valSname = _T("");
m_valSage = _T("");
m_valSnative = _T("");
m_valSetime = _T("");
UpdateData(FALSE);
}
void CStudenteDlg::OnSeonall()
{
// TODO: Add your control notification handler code here
// m_ctlList.DeleteAllItems();
m_ctlList.SetRedraw(FALSE);
UpdateData(TRUE);
CString strSQL;
CStudentSet m_recordset;
strSQL.Format( "select * from student ");
if(!m_recordset.Open(AFX_DB_USE_DEFAULT_TYPE,strSQL))
{ MessageBox("打开数据库失败!数据库错误",MB_ICONSTOP);
return ; }
int i=0;
CString strTime;
CString str1;
while(!m_recordset.IsEOF())
{
str1=m_recordset.m_Sno+" "+m_recordset.m_Sname+" "+m_recordset.m_Sage+" "+m_recordset.m_Snative+" "+m_recordset.m_Setime;
m_ctlList.InsertString(1,str1);
i++;
m_recordset.MoveNext();
}
m_recordset.Close();
m_ctlList.SetRedraw(TRUE);
}
void CStudenteDlg::OnSeedit()
{
// TODO: Add your control notification handler code here
UpdateData( TRUE );
CStudentSet m_recordset;
if(m_valSname.IsEmpty())
{ MessageBox("请输入学生姓名!");
return; }
if(m_valSno.IsEmpty())
{ MessageBox("请输入学生学号!");
return; }
if(m_valSage.IsEmpty())
{ MessageBox("请输入学生年龄!");
return; }
if(m_valSnative.IsEmpty())
{ MessageBox("请输入学生籍贯!");
return; }
if(m_valSetime.IsEmpty())
{ MessageBox("请输入学生入学日期!");
return; }
CString str="select * from student";
int flag=0;
if( !m_recordset.Open( AFX_DB_USE_DEFAULT_TYPE, _T(str) ) )
{ MessageBox("打开数据库失败!数据库错误",MB_ICONSTOP);
return ; }
while( !m_recordset.IsEOF() )
{ if( m_valSno == m_recordset.m_Sno )
{ flag=1;
break; }
else
{ m_recordset.MoveNext(); }
}
if( flag==0)
{ MessageBox( "查无此人,默认添加!", "学生信息", MB_ICONINFORMATION );
CStudenteDlg::OnSeaddnew();
return; }
//修改学生记录
m_recordset.Edit();
m_recordset.m_Sno = m_valSno;
m_recordset.m_Sname = m_valSname;
m_recordset.m_Sage = m_valSage;
m_recordset.m_Snative= m_valSnative;
m_recordset.m_Setime = m_valSetime;
m_recordset.Update();
m_recordset.Close();
//更新列表
CStudenteDlg::OnSeonall();
//更新界面显示
m_valSno = _T("");
m_valSname = _T("");
m_valSage = _T("");
m_valSnative = _T("");
m_valSetime = _T("");
UpdateData(FALSE);
}
void CStudenteDlg::OnCancel()
{
// TODO: Add your control notification handler code here
CDialog::OnCancel();
}