C 语言课程设计:SimpleCG打造实用学生信息管理(二)
一、课程设计需求描述
学生信息管理
(1)问题描述
学生信息包括:学号,姓名,年龄,性别,出生年月,地址,电话,E-mail等。试设计一学生信息管理系统,使之能提供以下功能:
A、系统以菜单方式工作
B、学生信息录入功能(学生信息用文件保存)—输入
C、学生信息浏览功能——输出
D、查询、排序功能——算法
1、按学号查询
2、按姓名查询
E、学生信息的删除与修改(可选项)
(2)功能要求
界面简单明了;
有一定的容错能力,比如输入的成绩不在0~100之间,就提示不合法,要求重新输入;
最好用链表的方式实现。
二、控制台界面方式实现
按照C语言课程,刚学完C语言的同学设计这个系统会选择使用控制台程序实现。一方面对同学来说比较熟悉,因为上课大部分学的都是控制台输出输入。另一方面api比较简单直观,可以把重点放在逻辑设计上,方便检验同学的算法和数据结构的掌握程度。所以下面我们先用控制台界面简单实现一下。
为了后面的升级或更换系统方便,我们采用数据和界面分离的方式开发,将数据逻辑写在student.c和student.h里面。这样可以为以后的复用提供便利。在主界面逻辑中调用相关功能即可。
student.h 内容如下:
#include <tchar.h>
#define bool int
#define true 1
#define false 0
#ifdef __cplusplus
extern "C"
{
#endif
struct _tagStudent
{
TCHAR strID[20]; //学号
TCHAR strName[20]; //姓名
int nAge; //年龄
int nSex; //性别
int nYear; //出生年月
int nMonth; //出生年月
int nDay; //出生年月
TCHAR strAddress[60]; //地址
TCHAR strPhone[20]; //电话
TCHAR strEmail[30]; //E-mail
};
typedef struct _tagStudent tagStudent;
//初始化链表
bool InitList();
//释放链表
void ReleaseList();
//添加学生
bool AddStudent( tagStudent *pStudent );
//按学号查找学生
tagStudent * FindStuddent( TCHAR *pStrID );
//按学号查找学生
tagStudent * FindStuddentByName( TCHAR *pName );
//按学号删除学生
bool DelStuddent( TCHAR *pStrID );
//按学号更新学生
bool UpdateStudent( TCHAR *pStrID, tagStudent *pNewStudent );
//学生列表头
tagStudent* FirtStudent();
//下一个学生
tagStudent* NextStudent(tagStudent*pStudent);
//学生数量
int GetStudentCnt();
//保存Student
bool SaveStudent(FILE *pFile, tagStudent *pStudent);
//读取Student
bool LoadStudent(FILE *pFile, tagStudent *pStudent);
//保存所有
bool SaveToFile(TCHAR *pFileName);
//读取所有
bool LoadFromeFile(TCHAR *pFileName);
#ifdef __cplusplus
}
#endif
student.c实现代码如下
#include "stdlib.h"
#include "stdio.h"
#include "student.h"
struct _tagDLNode
{
tagStudent oStudent;
struct _tagDLNode *pPrev;
struct _tagDLNode *pNext;
};
typedef struct _tagDLNode tagDLNode;
int g_nTotal;
tagDLNode* g_pStudentHead = NULL;
tagDLNode* g_pStudentTail = NULL;
//初始化链表
bool InitList()
{
static tagDLNode s_list;
s_list.pNext = s_list.pPrev = &s_list;
g_pStudentHead = &s_list;
g_pStudentTail = &s_list;
return true;
}
//释放链表
void ReleaseList()
{
int nCnt = 0;
tagDLNode *pStudent = g_pStudentHead->pNext;
while( pStudent != g_pStudentHead )
{
tagDLNode *pNext = pStudent->pNext;
free(pStudent);
pStudent = pNext;
}
InitList();
return;
}
//添加学生
bool AddStudent( tagStudent *pStudent )
{
tagDLNode *pNewStudent = (tagDLNode *)malloc(sizeof(tagDLNode));
if( NULL == pNewStudent )
return false;
pNewStudent->oStudent = *pStudent;
pNewStudent->pPrev = g_pStudentTail;
pNewStudent->pNext = g_pStudentTail->pNext;
g_pStudentTail->pNext->pPrev = pNewStudent;
g_pStudentTail->pNext = pNewStudent;
g_pStudentTail=pNewStudent;
return true;
}
//按节点删除学生
bool DelStuddentNode( tagDLNode *pNewStudent )
{
if(NULL==pNewStudent)
return false;
pNewStudent->pNext->pPrev=pNewStudent->pPrev;
pNewStudent->pPrev->pNext=pNewStudent->pNext;
free(pNewStudent);
return true;
}
//按学号查找学生
tagStudent* FindStuddent( TCHAR *pStrID )
{
tagDLNode *pStudent = g_pStudentHead->pNext;
while(pStudent != g_pStudentHead )
{
if( _tcsncmp( pStrID, pStudent->oStudent.strID, 20 )==0 )
{
return &pStudent->oStudent;
}
pStudent = pStudent->pNext;
}
return NULL;
}
//按学号查找学生
tagStudent * FindStuddentByName( TCHAR *pName )
{
tagDLNode *pStudent = g_pStudentHead->pNext;
while(pStudent != g_pStudentHead )
{
if( _tcsncmp( pName, pStudent->oStudent.strName, 20 )==0 )
{
return &pStudent->oStudent;
}
pStudent = pStudent->pNext;
}
return NULL;
}
//按学号查找学生
tagDLNode* FindStudentNode( TCHAR *pStrID )
{
tagDLNode *pStudent = g_pStudentHead->pNext;
while(pStudent != g_pStudentHead )
{
if( _tcsncmp( pStrID, pStudent->oStudent.strID, 20 )==0 )
{
return pStudent;
}
pStudent = pStudent->pNext;
}
return NULL;
}
//按学号删除学生
bool DelStuddent( TCHAR *pStrID )
{
tagDLNode *pStudent = FindStudentNode( pStrID );
if( NULL == pStudent )
return false;
return DelStuddentNode(pStudent);
}
//按学号更新学生
bool UpdateStudent( TCHAR *pStrID, tagStudent *pNewStudent )
{
tagDLNode *pStudent = FindStudentNode( pStrID );
if( NULL == pStudent )
return false;
pStudent->oStudent = *pNewStudent;
return true;
}
//学生列表头
tagStudent* FirtStudent()
{
tagDLNode *pStudent = g_pStudentHead->pNext;
if( pStudent == g_pStudentHead )
{
return NULL;
}
return &pStudent->oStudent;
}
//下一个学生
tagStudent* NextStudent( tagStudent *pStudent)
{
tagDLNode *pNext = ((tagDLNode*)pStudent)->pNext;
if( pNext == g_pStudentHead )
{
return NULL;
}
return &pNext->oStudent;
}
//学生数量
int GetStudentCnt()
{
int nCnt = 0;
tagDLNode *pStudent = g_pStudentHead->pNext;
while( pStudent != g_pStudentHead )
{
++nCnt;
pStudent = pStudent->pNext;
}
return nCnt;
}
//保存Student
bool SaveStudent(FILE *pFile, tagStudent *pStudent)
{
_ftprintf(pFile, _T("%s %s %d "), pStudent->strID, pStudent->strName, pStudent->nAge);
_ftprintf(pFile, _T("%d %d-%d "), pStudent->nSex, pStudent->nYear, pStudent->nMonth);
_ftprintf(pFile, _T("%s %s %s \n"), pStudent->strAddress, pStudent->strPhone, pStudent->strEmail);
return true;
}
//读取Student
bool LoadStudent(FILE *pFile, tagStudent *pStudent)
{
if( feof(pFile) )
return false;
_ftscanf(pFile, _T("%s %s %d "), pStudent->strID, pStudent->strName, &pStudent->nAge);
if( feof(pFile) )
return false;
_ftscanf(pFile, _T("%d %d-%d "), &pStudent->nSex, &pStudent->nYear, &pStudent->nMonth);
if( feof(pFile) )
return false;
_ftscanf(pFile, _T("%s %s %s "), pStudent->strAddress, pStudent->strPhone, pStudent->strEmail);
return true;
}
//保存所有
bool SaveToFile(TCHAR *pFileName)
{
int nCnt = 0;
FILE *pFile = NULL;
errno_t nErr;
tagDLNode *pStudent = NULL;
nErr = _tfopen_s( &pFile, pFileName, _T("w"));
if( nErr )
return false;
nCnt = GetStudentCnt();
pStudent = g_pStudentHead->pNext;
if( NULL == pFile )
return false;
while( pStudent != g_pStudentHead )
{
if( !SaveStudent( pFile, &pStudent->oStudent ))
{
fclose(pFile);
return false;
}
pStudent = pStudent->pNext;
}
fclose(pFile);
return true;
}
//读取所有
bool LoadFromeFile(TCHAR *pFileName)
{
int nCnt = 0;
FILE *pFile = NULL;
errno_t nErr;
tagStudent oStudent;
nErr = _tfopen_s( &pFile, pFileName, _T("r"));
if( nErr )
return false;
if( NULL == pFile )
return false;
ReleaseList();
while( LoadStudent( pFile, &oStudent ) )
{
++nCnt;
AddStudent( &oStudent );
}
fclose(pFile);
return true;
}
我们使用的是双链表保存数据,方便增加和删除数据。
CDStudentManageCon.c交互代码如下:
// CDStudentManageCon.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "locale.h"
#include "student.h"
#define MAX_PATH 260
int ShowMenu()
{
int nMenu = 0;
system("cls");
_tprintf(_T("\t***\tXXX学生信息管理系统\t***\t\n"));
_tprintf(_T("\n"));
_tprintf(_T("\t***\t1 - 添加学生\t\t***\t\n"));
_tprintf(_T("\t***\t2 - 删除学生\t\t***\t\n"));
_tprintf(_T("\t***\t3 - 修改学生\t\t***\t\n"));
_tprintf(_T("\t***\t4 - 浏览学生\t\t***\t\n"));
_tprintf(_T("\t***\t5 - 查找学生\t\t***\t\n"));
_tprintf(_T("\t***\t6 - 保存所有\t\t***\t\n"));
_tprintf(_T("\t***\t7 - 读取存档\t\t***\t\n"));
_tprintf(_T("\t***\t0 - 退出\t\t***\t\n"));
_tprintf(_T("\n"));
_tprintf(_T("请输入0到7之间的数字并回车选择操作:"));
_tscanf(_T("%d"),&nMenu);
return nMenu;
}
bool InputStudentInfo(tagStudent *student)
{
_tprintf(_T("请输入学号:"));
_tscanf(_T("%s"),student->strID);
_tprintf(_T("请输入姓名:"));
_tscanf(_T("%s"),student->strName);
_tprintf(_T("请输入性别:"));
_tscanf(_T("%d"),&student->nSex);
_tprintf(_T("请输入年龄:"));//下面有出生年月,可以省略这个
_tscanf(_T("%d"),&student->nAge);
_tprintf(_T("请输入出生年月(例子:2000-01):"));
_tscanf(_T("%d-%d"), &student->nYear, &student->nMonth );
_tprintf(_T("请输入地址:"));
_tscanf(_T("%s"),student->strAddress);
_tprintf(_T("请输入电话:"));
_tscanf(_T("%s"),student->strPhone);
_tprintf(_T("请输入EMAIL:"));
_tscanf(_T("%s"),student->strEmail);
return true;
}
void ShowAdd()
{
tagStudent student;
if( !InputStudentInfo(&student) )
return;
if( AddStudent( &student ))
_tprintf(_T("添加成功\n"));
else
_tprintf(_T("添加失败\n"));
//_tprintf(_T("任意键回到菜单....\n"));
system("pause");
}
void ShowDel()
{
TCHAR pStuID[20];
_tprintf(_T("请输入要删除的学号:"));
_tscanf(_T("%s"),pStuID);
if( DelStuddent( pStuID ) )
_tprintf(_T("删除%s成功\n"),pStuID);
else
_tprintf(_T("删除%s失败,确认是否存在该学号\n"),pStuID);
system("pause");
}
void ShowModify()
{
TCHAR pStuID[20];
tagStudent student;
tagStudent* pFind = NULL;
_tprintf(_T("请输入要修改的学号:"));
_tscanf(_T("%s"),pStuID);
pFind = FindStuddent( pStuID );
if(NULL==pFind)
{
_tprintf(_T("档案中不存在此学号\n"));
system("pause");
return;
}
if( !InputStudentInfo(&student) )
return;
if( UpdateStudent( pStuID, &student ) )
_tprintf(_T("%s更新成功\n"),pStuID);
else
_tprintf(_T("%s更新失败\n"),pStuID);
system("pause");
}
void ShowStudentDetail()
{
TCHAR pKeyWord[20];
int nType = 0;
tagStudent* pStudent = NULL;
_tprintf(_T("请输入查询方式(0-按学号,1-按名字):"));
_tscanf(_T("%d"), &nType);
if( nType==0)
{
_tprintf(_T("请输入要查找的学生学号:"));
_tscanf(_T("%s"),pKeyWord);
pStudent = FindStuddent(pKeyWord);
}
else
{
_tprintf(_T("请输入要查找的学生姓名:"));
_tscanf(_T("%s"),pKeyWord);
pStudent = FindStuddentByName(pKeyWord);
}
if( NULL == pStudent )
{
_tprintf(_T("没有查询到该学生\n"));
system("pause");
return;
}
_tprintf(_T("\n"));
if( pStudent )
{
_tprintf(_T("学号:\t%s\n"),pStudent->strID);
_tprintf(_T("姓名:\t%s\n"),pStudent->strName);
_tprintf(_T("性别:\t%s\n"),pStudent->nSex?_T("男"):_T("女"));
_tprintf(_T("年龄:\t%d\n"),pStudent->nAge);
_tprintf(_T("出生年月:\t%d-%d\t\n"),pStudent->nYear,pStudent->nMonth);
_tprintf(_T("地址:\t%s\n"),pStudent->strAddress);
_tprintf(_T("电话:\t%s\n"),pStudent->strPhone);
_tprintf(_T("EMAIL:\t%s\n"),pStudent->strEmail);
_tprintf(_T("\n"));
pStudent = NextStudent(pStudent);
}
_tprintf(_T("\n"));
system("pause");
}
void ShowList()
{
tagStudent* pStudent = FirtStudent();
_tprintf(_T("\n"));
_tprintf(_T("学号\t姓名\t性别\t年龄\t出生年月\t电话\t\n"),pStudent->strID);
while( pStudent )
{
_tprintf(_T("%s\t"),pStudent->strID);
_tprintf(_T("%s\t"),pStudent->strName);
_tprintf(_T("%s\t"),pStudent->nSex?_T("男"):_T("女"));
_tprintf(_T("%d\t"),pStudent->nAge);
_tprintf(_T("%d-%d\t\t"),pStudent->nYear,pStudent->nMonth);
_tprintf(_T("%s\t"),pStudent->strPhone);
_tprintf(_T("\n"));
pStudent = NextStudent(pStudent);
}
_tprintf(_T("\n"));
system("pause");
}
void SaveList()
{
TCHAR pFileName[MAX_PATH];
_tprintf(_T("请输入保存文件名:"));
_tscanf(_T("%s"),pFileName);
if(SaveToFile(pFileName))
_tprintf(_T("保存成功\n"));
else
_tprintf(_T("保存失败\n"));
system("pause");
}
void LoadList()
{
TCHAR pFileName[MAX_PATH];
TCHAR pYesNo;
getchar();
if( GetStudentCnt()>0 )
{
_tprintf(_T("将要重新装载学生列表,是否继续?(y/n):"));
_tscanf(_T("%c"),&pYesNo);
if(pYesNo==_T('n'))
return;
}
_tprintf(_T("请输入要读取的文件名:"));
_tscanf(_T("%s"),pFileName);
if(LoadFromeFile(pFileName))
_tprintf(_T("读取成功\n"));
else
_tprintf(_T("读取失败\n"));
system("pause");
}
int _tmain(int argc, _TCHAR* argv[])
{
int nMenu = 0;
setlocale(LC_ALL, "");
if( NULL == InitList() )
return 1;
nMenu = ShowMenu();
while( nMenu != 0 )
{
switch(nMenu)
{
case 0:
break;
case 1:
ShowAdd();
break;
case 2:
ShowDel();
break;
case 3:
ShowModify();
break;
case 4:
ShowList();
break;
case 5:
ShowStudentDetail();
break;
case 6:
SaveList();
break;
case 7:
LoadList();
break;
default:
break;
}
nMenu = ShowMenu();
}
ReleaseList();
_tprintf(_T("正在退出系统,再见!"));
return 0;
}
作为课程设计,这个代码已经基本完成了题目要求,除了成绩管理方面功能被剔除了,不过在学生资料里直接加上各科目字段,然后添加相关字段操作就可以实现题目要求了,而且按以往经验,很多同学也是这样实现的。不过我暂时舍弃了成绩字段,因为我觉得那样的设计是不实用的,一个学生管理系统不可能只能管理一次成绩。后续将添加额外的数据结构保存不同批次的成绩。另外字符界面交互方式属于早期的技术,虽然在一些对运行效率要求高的程序中有很大作用,但在现在图形界面时代,这种字符型界面除了程序员喜欢外,一般的使用者也就是学校的各科老师是不会习惯的。所以下面我们尝试利用SimpleCG库对此系统进行界面的升级改造。
三、SimpleCG库进行图形方式的实现
这节我们改用图形界面,我们借助SimpleCG对上面的程序增加图形界面交互功能。其中界面部分是用Simple库实现的一个小型界面库SimpleGUI实现。下面介绍大概逻辑。
由于前期的数据和界面代码分离编写,所以我们能够复用原来的大部分数据相关代码。我们只需要修改界面相关的部分。前面说了为了尽量让系统实用,我们设计成多个表,所以数据部分分成三个表,分别为Student学生、Exam科目表、Score分数表。因为跟界面分离,分成三个实现文件,加上头文件就6个文件。代码分别如下:
Student.h
#include <tchar.h>
#define bool int
#define true 1
#define false 0
#ifdef __cplusplus
extern "C"
{
#endif
struct _tagStudent
{
int nID;
TCHAR strID[20]; //学号
TCHAR strName[20]; //姓名
int nAge; //年龄
int nSex; //性别
int nYear; //出生年月
int nMonth; //出生年月
int nDay; //出生年月
TCHAR strAddress[60]; //地址
TCHAR strPhone[20]; //电话
TCHAR strEmail[30]; //E-mail
};
typedef struct _tagStudent tagStudent;
//初始化链表
bool InitList();
//释放链表
void ReleaseList();
//添加学生
bool AddStudent( tagStudent *pStudent );
//按id查找学生
tagStudent * FindStudent( int nID );
//按学号查找学生
tagStudent * FindStudentByStuID( TCHAR *pStrID );
//按学号查找学生
tagStudent * FindStudentByName( TCHAR *pName );
//按学号删除学生
bool DelStudent( int nID );
bool DelStudentByStuID( TCHAR *pStrID );
//按学号更新学生
bool UpdateStudent( int nID, tagStudent *pNewStudent );
bool UpdateStudentByStuID( TCHAR *pStrID, tagStudent *pNewStudent );
//学生列表头
tagStudent* FirtStudent();
//上一个学生
tagStudent* PrevStudent( tagStudent *pStudent);
//下一个学生
tagStudent* NextStudent(tagStudent*pStudent);
//按序号查找学生
tagStudent* GetStudentByIndex(int nIndex);
//学生数量
int GetStudentCnt();
//学生MaxID
int GetMaxStudentID();
//保存Student
bool SaveStudent(FILE *pFile, tagStudent *pStudent);
//读取Student
bool LoadStudent(FILE *pFile, tagStudent *pStudent);
//保存所有
bool SaveToFile(TCHAR *pFileName);
//读取所有
bool LoadFromeFile(TCHAR *pFileName);
#ifdef __cplusplus
}
#endif
Student.c
#include "stdlib.h"
#include "stdio.h"
#include "student.h"
struct _tagDLNode
{
tagStudent oStudent;
struct _tagDLNode *pPrev;
struct _tagDLNode *pNext;
};
typedef struct _tagDLNode tagDLNode;
int g_nTotal;
int g_nCur;
int g_nMaxStudentID = 0;
tagStudent* g_pStudentCur = NULL;
tagDLNode* g_pStudentHead = NULL;
tagDLNode* g_pStudentTail = NULL;
//初始化链表
bool InitList()
{
static tagDLNode s_list;
s_list.pNext = s_list.pPrev = &s_list;
g_pStudentHead = &s_list;
g_pStudentTail = &s_list;
g_nCur = -1;
g_pStudentCur = NULL;
g_nMaxStudentID = 0;
return true;
}
//释放链表
void ReleaseList()
{
int nCnt = 0;
tagDLNode *pStudent = g_pStudentHead->pNext;
while( pStudent != g_pStudentHead )
{
tagDLNode *pNext = pStudent->pNext;
free(pStudent);
pStudent = pNext;
}
InitList();
return;
}
//添加学生
bool AddStudent( tagStudent *pStudent )
{
tagDLNode *pNewStudent = (tagDLNode *)malloc(sizeof(tagDLNode));
if( NULL == pNewStudent )
return false;
pNewStudent->oStudent = *pStudent;
//pNewStudent->oStudent.nID = g_nMaxStudentID+1;
if( g_nMaxStudentID<pNewStudent->oStudent.nID)
g_nMaxStudentID = pNewStudent->oStudent.nID;
pNewStudent->pPrev = g_pStudentTail;
pNewStudent->pNext = g_pStudentTail->pNext;
g_pStudentTail->pNext->pPrev = pNewStudent;
g_pStudentTail->pNext = pNewStudent;
g_pStudentTail=pNewStudent;
return true;
}
//按节点删除学生
bool DelStudentNode( tagDLNode *pDelStudent )
{
if(NULL==pDelStudent)
return false;
pDelStudent->pNext->pPrev=pDelStudent->pPrev;
pDelStudent->pPrev->pNext=pDelStudent->pNext;
if(g_pStudentCur==&pDelStudent->oStudent)
{
g_pStudentCur = &pDelStudent->pPrev->oStudent;
}
--g_nCur;
free(pDelStudent);
return true;
}
//按id查找学生
tagStudent * FindStudent( int nID )
{
tagDLNode *pStudent = g_pStudentHead->pNext;
while(pStudent != g_pStudentHead )
{
if( nID==pStudent->oStudent.nID )
{
return &pStudent->oStudent;
}
pStudent = pStudent->pNext;
}
return NULL;
}
//按学号查找学生
tagStudent* FindStudentByStuID( TCHAR *pStrID )
{
tagDLNode *pStudent = g_pStudentHead->pNext;
while(pStudent != g_pStudentHead )
{
if( _tcsncmp( pStrID, pStudent->oStudent.strID, 20 )==0 )
{
return &pStudent->oStudent;
}
pStudent = pStudent->pNext;
}
return NULL;
}
//按学号查找学生
tagStudent * FindStudentByName( TCHAR *pName )
{
tagDLNode *pStudent = g_pStudentHead->pNext;
while(pStudent != g_pStudentHead )
{
if( _tcsncmp( pName, pStudent->oStudent.strName, 20 )==0 )
{
return &pStudent->oStudent;
}
pStudent = pStudent->pNext;
}
return NULL;
}
//按学号查找学生
tagDLNode* FindStudentNode( int nID )
{
tagDLNode *pStudent = g_pStudentHead->pNext;
while(pStudent != g_pStudentHead )
{
if( nID==pStudent->oStudent.nID )
{
return pStudent;
}
pStudent = pStudent->pNext;
}
return NULL;
}
tagDLNode* FindStudentNodeByStuID( TCHAR *pStrID )
{
tagDLNode *pStudent = g_pStudentHead->pNext;
while(pStudent != g_pStudentHead )
{
if( _tcsncmp( pStrID, pStudent->oStudent.strID, 20 )==0 )
{
return pStudent;
}
pStudent = pStudent->pNext;
}
return NULL;
}
//按学号删除学生
bool DelStudent( int nID )
{
tagDLNode *pStudent = FindStudentNode( nID );
if( NULL == pStudent )
return false;
return DelStudentNode(pStudent);
}
bool DelStudentByStuID( TCHAR *pStrID )
{
tagDLNode *pStudent = FindStudentNodeByStuID( pStrID );
if( NULL == pStudent )
return false;
return DelStudentNode(pStudent);
}
//按学号更新学生
bool UpdateStudent( int nID, tagStudent *pNewStudent )
{
tagDLNode *pStudent = FindStudentNode( nID );
if( NULL == pStudent )
return false;
pStudent->oStudent = *pNewStudent;
return true;
}
bool UpdateStudentByStuID( TCHAR *pStrID, tagStudent *pNewStudent )
{
tagDLNode *pStudent = FindStudentNodeByStuID( pStrID );
if( NULL == pStudent )
return false;
pStudent->oStudent = *pNewStudent;
return true;
}
//学生列表头
tagStudent* FirtStudent()
{
tagDLNode *pStudent = g_pStudentHead->pNext;
if( pStudent == g_pStudentHead )
{
return NULL;
}
/*g_nCur = 0;
g_pStudentCur = &pStudent->oStudent;*/
return &pStudent->oStudent;
}
//上一个学生
tagStudent* PrevStudent( tagStudent *pStudent)
{
tagDLNode *pNext = ((tagDLNode*)pStudent)->pPrev;
if( pNext == g_pStudentHead )
{
return NULL;
}
/*--g_nCur;
g_pStudentCur = &pNext->oStudent;*/
return &pNext->oStudent;
}
//下一个学生
tagStudent* NextStudent( tagStudent *pStudent)
{
tagDLNode *pNext = ((tagDLNode*)pStudent)->pNext;
if( pNext == g_pStudentHead )
{
return NULL;
}
/*++g_nCur;
g_pStudentCur = &pNext->oStudent;*/
return &pNext->oStudent;
}
//按序号查找学生
tagStudent* GetStudentByIndex(int nIndex)
{
int i=0;
tagDLNode *pNext = NULL;
if( nIndex == g_nCur )
return g_pStudentCur;
pNext = ((tagDLNode*)g_pStudentCur);
if(pNext==NULL)
{
pNext = ((tagDLNode*)g_pStudentHead);
g_nCur = -1;
}
if( nIndex<g_nCur )
{
for( i=g_nCur; i>nIndex; --i)
{
pNext=pNext->pPrev;
if( pNext == g_pStudentHead )
{
return NULL;
}
}
}
else
{
for( i=g_nCur; i<nIndex; ++i)
{
pNext=pNext->pNext;
if( pNext == g_pStudentHead )
{
return NULL;
}
}
}
if(i!=nIndex)
return NULL;
g_pStudentCur = &pNext->oStudent;
g_nCur=nIndex;
return &pNext->oStudent;
}
//学生数量
int GetStudentCnt()
{
int nCnt = 0;
tagDLNode *pStudent = g_pStudentHead->pNext;
while( pStudent != g_pStudentHead )
{
++nCnt;
pStudent = pStudent->pNext;
}
return nCnt;
}
//学生MaxID
int GetMaxStudentID()
{
return g_nMaxStudentID;
}
//保存Student
bool SaveStudent(FILE *pFile, tagStudent *pStudent)
{
_ftprintf(pFile, _T("%d %s %s %d "), pStudent->nID, pStudent->strID, pStudent->strName, pStudent->nAge);
_ftprintf(pFile, _T("%d %d-%d "), pStudent->nSex, pStudent->nYear, pStudent->nMonth);
_ftprintf(pFile, _T("%s %s %s \n"), pStudent->strAddress, pStudent->strPhone, pStudent->strEmail);
return true;
}
//读取Student
bool LoadStudent(FILE *pFile, tagStudent *pStudent)
{
if( feof(pFile) )
return false;
_ftscanf_s(pFile, _T("%d %s %s %d "), &pStudent->nID, pStudent->strID, 20, pStudent->strName, 20, &pStudent->nAge);
if( feof(pFile) )
return false;
_ftscanf_s(pFile, _T("%d %d-%d "), &pStudent->nSex, &pStudent->nYear, &pStudent->nMonth);
if( feof(pFile) )
return false;
_ftscanf_s(pFile, _T("%s %s %s "), pStudent->strAddress, 60, pStudent->strPhone, 20, pStudent->strEmail, 30);
return true;
}
//保存所有
bool SaveToFile(TCHAR *pFileName)
{
int nCnt = 0;
FILE *pFile = NULL;
errno_t nErr;
tagDLNode *pStudent = NULL;
nErr = _tfopen_s( &pFile, pFileName, _T("w"));
if( nErr )
return false;
nCnt = GetStudentCnt();
pStudent = g_pStudentHead->pNext;
if( NULL == pFile )
return false;
while( pStudent != g_pStudentHead )
{
if( !SaveStudent( pFile, &pStudent->oStudent ))
{
fclose(pFile);
return false;
}
pStudent = pStudent->pNext;
}
fclose(pFile);
return true;
}
//读取所有
bool LoadFromeFile(TCHAR *pFileName)
{
int nCnt = 0;
FILE *pFile = NULL;
errno_t nErr;
tagStudent oStudent;
nErr = _tfopen_s( &pFile, pFileName, _T("r"));
if( nErr )
return false;
if( NULL == pFile )
return false;
ReleaseList();
while( LoadStudent( pFile, &oStudent ) )
{
++nCnt;
AddStudent( &oStudent );
}
fclose(pFile);
return true;
}
Exam.h
#include <tchar.h>
#define bool int
#define true 1
#define false 0
#ifdef __cplusplus
extern "C"
{
#endif
struct _tagExam
{
int nID; //科目ID
TCHAR strName[20]; //科目名称
TCHAR strBatch[20]; //科目批次
int nCount; //当前人数
float fFaileScore; //及格分
float fExcellentScore; //优秀分
float fAveScore; //平均分
float fMax; //最高分
float fMin; //最低分
};
typedef struct _tagExam tagExam;
//初始化链表
bool InitExamList();
//释放链表
void ReleaseListExam();
//添加科目
bool AddExam( tagExam *pExam );
//按学号查找科目
//tagExam * FindExam( TCHAR *pStrID );
tagExam * FindExam( int nID );
//按学号查找科目
tagExam * FindExamByName( TCHAR *pName );
//按学号删除科目
bool DelExam( int nID );
//按学号更新科目
bool UpdateExam( int nID, tagExam *pNewExam );
//科目列表头
tagExam* FirtExam();
//上一个科目
tagExam* PrevExam( tagExam *pExam);
//下一个科目
tagExam* NextExam(tagExam*pExam);
//按序号查找科目
tagExam* GetExamByIndex(int nIndex);
//科目数量
int GetExamCnt();
//学生科目ID
int GetMaxExamID();
//保存Exam
bool SaveExam(FILE *pFile, tagExam *pExam);
//读取Exam
bool LoadExam(FILE *pFile, tagExam *pExam);
//保存所有
bool SaveToFileExam(TCHAR *pFileName);
//读取所有
bool LoadFromeFileExam(TCHAR *pFileName);
#ifdef __cplusplus
}
#endif
Exam.c
#include "stdlib.h"
#include "stdio.h"
#include "exam.h"
struct _tagDLNodeExam
{
tagExam oExam;
struct _tagDLNodeExam *pPrev;
struct _tagDLNodeExam *pNext;
};
typedef struct _tagDLNodeExam tagDLNodeExam;
int g_nTotalExam;
int g_nCurExam;
int g_nMaxExamID = 0;
tagExam* g_pExamCur = NULL;
tagDLNodeExam* g_pExamHead = NULL;
tagDLNodeExam* g_pExamTail = NULL;
//初始化链表
bool InitExamList()
{
static tagDLNodeExam s_list;
s_list.pNext = s_list.pPrev = &s_list;
g_pExamHead = &s_list;
g_pExamTail = &s_list;
g_nCurExam = -1;
g_pExamCur = NULL;
g_nMaxExamID = 0;
return true;
}
//释放链表
void ReleaseListExam()
{
int nCnt = 0;
tagDLNodeExam *pExam = g_pExamHead->pNext;
while( pExam != g_pExamHead )
{
tagDLNodeExam *pNext = pExam->pNext;
free(pExam);
pExam = pNext;
}
InitExamList();
return;
}
//添加科目
bool AddExam( tagExam *pExam )
{
tagDLNodeExam *pNewExam = (tagDLNodeExam *)malloc(sizeof(tagDLNodeExam));
if( NULL == pNewExam )
return false;
pNewExam->oExam = *pExam;
if( g_nMaxExamID<pNewExam->oExam.nID)
g_nMaxExamID = pNewExam->oExam.nID;
pNewExam->pPrev = g_pExamTail;
pNewExam->pNext = g_pExamTail->pNext;
g_pExamTail->pNext->pPrev = pNewExam;
g_pExamTail->pNext = pNewExam;
g_pExamTail=pNewExam;
return true;
}
//按节点删除科目
bool DelExamNode( tagDLNodeExam *pDelExam )
{
if(NULL==pDelExam)
return false;
pDelExam->pNext->pPrev=pDelExam->pPrev;
pDelExam->pPrev->pNext=pDelExam->pNext;
if(g_pExamTail==pDelExam)
g_pExamTail=pDelExam->pPrev;
if(g_pExamCur==&pDelExam->oExam)
{
g_pExamCur = &pDelExam->pPrev->oExam;
}
--g_nCurExam;
free(pDelExam);
return true;
}
//按学号查找科目
tagExam * FindExam( int nID )
{
tagDLNodeExam *pExam = g_pExamHead->pNext;
while(pExam != g_pExamHead )
{
//if( _tcsncmp( pStrID, pExam->oExam.strID, 20 )==0 )
if(nID==pExam->oExam.nID)
{
return &pExam->oExam;
}
pExam = pExam->pNext;
}
return NULL;
}
//按学号查找科目
tagExam * FindExamByName( TCHAR *pName )
{
tagDLNodeExam *pExam = g_pExamHead->pNext;
while(pExam != g_pExamHead )
{
if( _tcsncmp( pName, pExam->oExam.strName, 20 )==0 )
{
return &pExam->oExam;
}
pExam = pExam->pNext;
}
return NULL;
}
//按学号查找科目
tagDLNodeExam* FindExamNode( int nID )
{
tagDLNodeExam *pExam = g_pExamHead->pNext;
while(pExam != g_pExamHead )
{
if( nID==pExam->oExam.nID )
{
return pExam;
}
pExam = pExam->pNext;
}
return NULL;
}
//按学号删除科目
bool DelExam( int nID )
{
tagDLNodeExam *pExam = FindExamNode( nID );
if( NULL == pExam )
return false;
return DelExamNode(pExam);
}
//按学号更新科目
bool UpdateExam( int nID, tagExam *pNewExam )
{
tagDLNodeExam *pExam = FindExamNode( nID );
if( NULL == pExam )
return false;
pExam->oExam = *pNewExam;
return true;
}
//科目列表头
tagExam* FirtExam()
{
tagDLNodeExam *pExam = g_pExamHead->pNext;
if( pExam == g_pExamHead )
{
return NULL;
}
g_nCurExam = 0;
g_pExamCur = &pExam->oExam;
return &pExam->oExam;
}
//上一个科目
tagExam* PrevExam( tagExam *pExam)
{
tagDLNodeExam *pNext = ((tagDLNodeExam*)pExam)->pPrev;
if( pNext == g_pExamHead )
{
return NULL;
}
--g_nCurExam;
g_pExamCur = &pNext->oExam;
return &pNext->oExam;
}
//下一个科目
tagExam* NextExam( tagExam *pExam)
{
tagDLNodeExam *pNext = ((tagDLNodeExam*)pExam)->pNext;
if( pNext == g_pExamHead )
{
return NULL;
}
++g_nCurExam;
g_pExamCur = &pNext->oExam;
return &pNext->oExam;
}
//按序号查找科目
tagExam* GetExamByIndex(int nIndex)
{
int i=0;
tagDLNodeExam *pNext = NULL;
if( nIndex == g_nCurExam )
return g_pExamCur;
pNext = ((tagDLNodeExam*)g_pExamCur);
if(pNext==NULL)
{
pNext = ((tagDLNodeExam*)g_pExamHead);
g_nCurExam = -1;
}
if( nIndex<g_nCurExam )
{
for( i=g_nCurExam; i>nIndex; --i)
{
pNext=pNext->pPrev;
if( pNext == g_pExamHead )
{
return NULL;
}
}
}
else
{
for( i=g_nCurExam; i<nIndex; ++i)
{
pNext=pNext->pNext;
if( pNext == g_pExamHead )
{
return NULL;
}
}
}
if(i!=nIndex)
return NULL;
g_pExamCur = &pNext->oExam;
g_nCurExam=nIndex;
return &pNext->oExam;
}
//科目数量
int GetExamCnt()
{
int nCnt = 0;
tagDLNodeExam *pExam = g_pExamHead->pNext;
while( pExam != g_pExamHead )
{
++nCnt;
pExam = pExam->pNext;
}
return nCnt;
}
//学生科目ID
int GetMaxExamID()
{
return g_nMaxExamID;
}
//保存Exam
bool SaveExam(FILE *pFile, tagExam *pExam)
{
_ftprintf(pFile, _T("%d %s %s "), pExam->nID, pExam->strName, pExam->strBatch);
_ftprintf(pFile, _T("%d %0.2f %0.2f "), pExam->nCount, pExam->fFaileScore, pExam->fExcellentScore);
_ftprintf(pFile, _T("%0.2f %0.2f %0.2f \n"), pExam->fAveScore, pExam->fMax, pExam->fMin);
return true;
}
//读取Exam
bool LoadExam(FILE *pFile, tagExam *pExam)
{
if( feof(pFile) )
return false;
_ftscanf_s(pFile, _T("%d %s %s "), &pExam->nID, pExam->strName, 20, pExam->strBatch, 20);
if( feof(pFile) )
return false;
_ftscanf_s(pFile, _T("%d %f %f "), &pExam->nCount, &pExam->fFaileScore, &pExam->fExcellentScore);
if( feof(pFile) )
return false;
_ftscanf_s(pFile, _T("%f %f %f "), &pExam->fAveScore, &pExam->fMax, &pExam->fMin);
return true;
}
//保存所有
bool SaveToFileExam(TCHAR *pFileName)
{
int nCnt = 0;
FILE *pFile = NULL;
errno_t nErr;
tagDLNodeExam *pExam = NULL;
nErr = _tfopen_s( &pFile, pFileName, _T("w"));
if( nErr )
return false;
nCnt = GetExamCnt();
pExam = g_pExamHead->pNext;
if( NULL == pFile )
return false;
while( pExam != g_pExamHead )
{
if( !SaveExam( pFile, &pExam->oExam ))
{
fclose(pFile);
return false;
}
pExam = pExam->pNext;
}
fclose(pFile);
return true;
}
//读取所有
bool LoadFromeFileExam(TCHAR *pFileName)
{
int nCnt = 0;
FILE *pFile = NULL;
errno_t nErr;
tagExam oExam;
nErr = _tfopen_s( &pFile, pFileName, _T("r"));
if( nErr )
return false;
if( NULL == pFile )
return false;
ReleaseListExam();
while( LoadExam( pFile, &oExam ) )
{
++nCnt;
AddExam( &oExam );
}
fclose(pFile);
return true;
}
因为是用C语言,没有C++的模板及指针型数据,所以上面代码重复部分比较多。有兴趣的同学可以进行迭代升级,写的更简练一些。
下面就是图形界面部分的 实现,因为不同功能使用分页面显示,所以把页面界面创建独立出来,放到frame.h和frame.c当中。内容如下:
Frame.h
#include "../../import/SimpleGUI/include/SimpleGUI.h"
#define C_IMAGE_WIDTH 1024
#define C_IMAGE_HEIGHT 768
enum ENUM_FRAME
{
enumTABLE_STU,
enumTABLE_EXAM,
enumFRAME_STU,
enumFRAME_EXAM,
enumTABLE_SCORE,
enumFRAME_COUNT
};
enum ENUM_BUTTON
{
enumBTN_NULL,
enumBTN_STU,
enumBTN_STU_ADD,
enumBTN_STU_DEL,
enumBTN_STU_MODIFY,
enumBTN_EXAM,
enumBTN_EXAM_ADD,
enumBTN_EXAM_DEL,
enumBTN_EXAM_MODIFY,
enumBTN_EXAMRESULT_MODIFY,
enumBTN_SYS_SAVE,
enumBTN_SYS_LOAD,
enumBTN_SYS_EXIT,
enumBTN_STU_SAVEADD,
enumBTN_EXAM_SAVEADD,
enumBTN_RETURN,
enumBTN_EXAM_RETURN,
enumBTN_COUNT,
enumLISTTABLE_STU,
enumLISTTABLE_EXAM
};
enum ENUM_EDITSTU
{
enumEDITSTU_ID,
enumEDITSTU_STRID,
enumEDITSTU_STRNAME,
enumEDITSTU_AGE,
enumEDITSTU_SEX,
enumEDITSTU_YEAR,
enumEDITSTU_MONTH,
enumEDITSTU_ADDRESS,
enumEDITSTU_PHONE,
enumEDITSTU_EMAIL,
enumEDITSTU_COUNT
};
enum ENUM_EDITEXAM
{
enumEDITEXAM_ID,
enumEDITEXAM_STRNAME,
enumEDITEXAM_STRBATCH,
enumEDITEXAM_FAILESCORE,
enumEDITEXAM_EXCELLENTSCORE,
enumEDITEXAM_COUNT
};
#ifdef __cplusplus
extern "C"
{
#endif
extern HSCGTREEID g_hFrame[enumFRAME_COUNT];
extern HSCGTREEID g_hButton[enumBTN_COUNT];
extern HSCGTREEID g_hEditStu[enumEDITSTU_COUNT];
extern HSCGTREEID g_hEditExam[enumEDITEXAM_COUNT];
void ShowFrame( int nFrame);
void DrawListTable(HSCGTREEID hObjectID, tagSG_ListTableDrawParam *pParam);
HSCGTREEID GetCurFrame();
#ifdef __cplusplus
}
#endif
Frame.c
#include "Frame.h"
#include "student.h"
#include "exam.h"
#include "score.h"
HSCGTREEID g_hFrame[enumFRAME_COUNT]={0};
HSCGTREEID g_hButton[enumBTN_COUNT] = {0};
HSCGTREEID g_hEditStu[enumEDITSTU_COUNT]={0};
HSCGTREEID g_hEditExam[enumEDITEXAM_COUNT]={0};
HSCGTREEID g_nCurFrame = -1;
bool SetScoreText(HSCGTREEID hObjectID, int nLine, int nColumnIndex, const TCHAR *pText )
{
tagScore* pScore = GetScoreByIndex(nLine);
if(NULL!=pScore)
{
switch(nColumnIndex)
{
case 5:
pScore->fScore =(float)_tcstod( pText, NULL );
return true;
break;
default:
break;
}
}
return false;
}
bool GetScoreText(HSCGTREEID hObjectID, int nLine, int nColumnIndex, TCHAR *pText, int nSize )
{
tagScore* pScore = GetScoreByIndex(nLine);
if(NULL!=pScore)
{
switch(nColumnIndex)
{
case 5:
_stprintf_s( pText, nSize, _T("%0.2f"), pScore->fScore);
return true;
break;
default:
break;
}
}
return false;
}
void CreateTableStu()
{
tagSG_Box rt={180,100,C_IMAGE_WIDTH-rt.left-2,C_IMAGE_HEIGHT-rt.top-2};
//学生列表
g_hFrame[enumTABLE_STU]=create_ListTableOwnerDraw(NULL,RGB(0xAA,0xFF,0xAA),enumLISTTABLE_STU,&rt,8,DrawListTable );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_STU], 0, _T("学生ID") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_STU], 1, _T("学生姓名") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_STU], 2, _T("年龄") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_STU], 3, _T("性别") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_STU], 4, _T("出生年月") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_STU], 5, _T("地址") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_STU], 6, _T("电话") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_STU], 7, _T("E-mail") );
ListTableOwnerDraw_SetItemCount(g_hFrame[enumTABLE_STU], GetStudentCnt());
ListTableOwnerDraw_SetPageSize(g_hFrame[enumTABLE_STU], (650-30)/25);
}
void CreateTableExam()
{
tagSG_Box rt={180,100,C_IMAGE_WIDTH-rt.left-2,C_IMAGE_HEIGHT-rt.top-2};
//科目列表
g_hFrame[enumTABLE_EXAM]=create_ListTableOwnerDraw(NULL,RGB(0xAA,0xFF,0xAA),enumLISTTABLE_EXAM,&rt,7,DrawListTable );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_EXAM], 0, _T("科目ID") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_EXAM], 1, _T("科目名") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_EXAM], 2, _T("科目批次") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_EXAM], 3, _T("当前人数") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_EXAM], 4, _T("平均分") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_EXAM], 5, _T("最高分") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_EXAM], 6, _T("最低分") );
ListTableOwnerDraw_SetItemCount(g_hFrame[enumTABLE_EXAM], GetExamCnt());
ListTableOwnerDraw_SetPageSize(g_hFrame[enumTABLE_EXAM], (650-30)/25);
}
void CreateTableScore()
{
tagSG_Box rt={180,100,C_IMAGE_WIDTH-rt.left-2,C_IMAGE_HEIGHT-rt.top-2};
g_hFrame[enumTABLE_SCORE]=create_ListTableOwnerDrawEdit(NULL,RGB(0xAA,0xFF,0xAA),enumLISTTABLE_EXAM,&rt,6,DrawListTable, SetScoreText, GetScoreText);
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 0, _T("分数ID") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 1, _T("科目名") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 2, _T("科目批次") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 3, _T("学号") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 4, _T("姓名") );
ListTable_SetHeadTitle( g_hFrame[enumTABLE_SCORE], 5, _T("分数") );
ListTableOwnerDraw_SetItemCount(g_hFrame[enumTABLE_SCORE], GetExamCnt());
ListTableOwnerDraw_SetPageSize(g_hFrame[enumTABLE_SCORE], (650-30)/25);
}
void CreateFrameStu()
{
tagSG_Box rt={180,100,C_IMAGE_WIDTH-rt.left-2,C_IMAGE_HEIGHT-rt.top-2};
//添加修改学生界面
g_hFrame[enumFRAME_STU] = create_Frame( NULL, SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt);
rt.left = 100;
rt.top = 100;
rt.width = 120;
rt.height = 25;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("ID") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("学生ID") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("学生姓名") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("年龄") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("性别") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("出生年份") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("出生月份") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("地址") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("电话") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_STU], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("E-mail") );
rt.left += 130;
rt.width = 300;
rt.top = 100;
g_hEditStu[enumEDITSTU_ID] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditStu[enumEDITSTU_STRID] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditStu[enumEDITSTU_STRNAME] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditStu[enumEDITSTU_AGE] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
//g_hEditStu[enumEDITSTU_SEX] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
g_hEditStu[enumEDITSTU_SEX] = create_btnRadioGroup(g_hFrame[enumFRAME_STU],RGB(0xAA,0xFF,0xAA),-1,&rt);
if( -1 != g_hEditStu[enumEDITSTU_SEX] )
{
tagSG_Box rtRadio={0,0,60,25};
create_btnRadio(g_hEditStu[enumEDITSTU_SEX],_T("男"), RGB(0x55,0xbb,0x55),1,&rtRadio );
rtRadio.left += 60;
create_btnRadio(g_hEditStu[enumEDITSTU_SEX],_T("女"), RGB(0x55,0xbb,0x55),0,&rtRadio );
}
rt.top += 50;
g_hEditStu[enumEDITSTU_YEAR] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditStu[enumEDITSTU_MONTH] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditStu[enumEDITSTU_ADDRESS] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditStu[enumEDITSTU_PHONE] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditStu[enumEDITSTU_EMAIL] = create_SCGEdit( g_hFrame[enumFRAME_STU], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 70;
rt.width = 150;
g_hButton[enumBTN_STU_SAVEADD] = create_btnFlat(g_hFrame[enumFRAME_STU],_T("确认添加"), RGB(255,168,90),enumBTN_STU_SAVEADD,&rt);
rt.left += 170;
g_hButton[enumBTN_RETURN] = create_btnFlat(g_hFrame[enumFRAME_STU],_T("返回"), RGB(255,168,90),enumBTN_RETURN,&rt);
SCGEdit_AddProperty(g_hEditStu[enumEDITSTU_ID],enumEDITPRO_READONLY);
}
void CreateFrameExam()
{
tagSG_Box rt={180,100,C_IMAGE_WIDTH-rt.left-2,C_IMAGE_HEIGHT-rt.top-2};
//添加修改学生界面
g_hFrame[enumFRAME_EXAM] = create_Frame( NULL, SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt);
rt.left = 100;
rt.top = 100;
rt.width = 120;
rt.height = 25;
create_Label( g_hFrame[enumFRAME_EXAM], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("科目ID") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_EXAM], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("科目名") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_EXAM], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("科目批次") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_EXAM], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("及格分") );
rt.top += 50;
create_Label( g_hFrame[enumFRAME_EXAM], RGB(0xAA,0xFF,0xAA), 0, &rt, _T("优秀分") );
rt.left += 130;
rt.width = 300;
rt.top = 100;
g_hEditExam[enumEDITEXAM_ID] = create_SCGEdit( g_hFrame[enumFRAME_EXAM], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditExam[enumEDITEXAM_STRNAME] = create_SCGEdit( g_hFrame[enumFRAME_EXAM], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditExam[enumEDITEXAM_STRBATCH] = create_SCGEdit( g_hFrame[enumFRAME_EXAM], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditExam[enumEDITEXAM_FAILESCORE] = create_SCGEdit( g_hFrame[enumFRAME_EXAM], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
g_hEditExam[enumEDITEXAM_EXCELLENTSCORE] = create_SCGEdit( g_hFrame[enumFRAME_EXAM], SCGAddColor(RGB(0xAA,0xFF,0xAA),60), 0, &rt, _T("") );
rt.top += 50;
rt.top += 70;
rt.width = 150;
g_hButton[enumBTN_EXAM_SAVEADD] = create_btnFlat(g_hFrame[enumFRAME_EXAM],_T("确认添加"), RGB(255,168,90),enumBTN_EXAM_SAVEADD,&rt);
rt.left += 170;
g_hButton[enumBTN_EXAM_RETURN] = create_btnFlat(g_hFrame[enumFRAME_EXAM],_T("返回"), RGB(255,168,90),enumBTN_RETURN,&rt);
SCGEdit_AddProperty(g_hEditExam[enumEDITEXAM_ID],enumEDITPRO_READONLY);
}
void ShowFrame( int nFrame)
{
int i=0;
if( g_hFrame[nFrame] == NULL )
{
switch(nFrame)
{
case enumTABLE_STU:
CreateTableStu();
break;
case enumTABLE_EXAM:
CreateTableExam();
break;
case enumFRAME_STU:
CreateFrameStu();
break;
case enumFRAME_EXAM:
CreateFrameExam();
break;
case enumTABLE_SCORE:
CreateTableScore();
break;
}
}
for(i=0;i<enumFRAME_COUNT;++i)
{
if( i==nFrame )
{
ShowObject(g_hFrame[i],true);
g_nCurFrame = g_hFrame[i];
}
else
{
if( NULL != g_hFrame[i])
{
ShowObject(g_hFrame[i],false);
}
}
}
}
HSCGTREEID GetCurFrame()
{
return g_nCurFrame;
}
以上代码依据传入的页面类型分别生成学生资料表格页面、学生资料录入界面、课程列表界面、课程录入界面、分数录入列表界面并显示。
最后看看主界面代码
CDStudentManage.c
// CDStudentManage.cpp : 定义控制台应用程序的入口点。
//
#include "../../import/include/SimpleCG.h"
#include "../../import/SimpleGUI/include/SimpleGUI.h"
#include "../../import/SimpleGUI/include/winhelper.h"
#include "Frame.h"
#include "student.h"
#include "exam.h"
#include "score.h"
#include "locale.h"
#include "stdio.h"
#pragma comment(lib,"../../import/lib/SimpleCG_MDd.lib")
#pragma comment(lib,"../../import/SimpleGUI/lib/SimpleGUI_MDd.lib")
tagStudent* g_pStudent = NULL;
TCHAR g_pFileName[MAX_PATH]={0};
HWND g_hMainWnd = NULL;
SCG_Image imgGet;
int g_nSaveCommand = 0;
void OnStuManage();
void DrawListTableColumn(int i, tagSG_ListTableDrawParam *pParam, const TCHAR *pText, int *nX )
{
outtextRectEx( *nX+2,pParam->boxLine.top, pParam->pWidth[i]-4,pParam->boxLine.height, pText, SCG_TEXT_VCENTER);
*nX += pParam->pWidth[i];
}
void DrawStuList(tagSG_ListTableDrawParam *pParam)
{
TCHAR pText[16];
int i=0;
int nX = pParam->boxLine.left;
tagStudent* pStudent = GetStudentByIndex(pParam->nDataIndex);
if(pParam->nState ==enumLTS_SELECTED )
{
setfillcolor(SCGAddColor(RGB(140,250,0xFF),30));
}
else
{
if(pParam->nLine%2)
setfillcolor(SCGAddColor(RGB(0xAA,0xFF,0xAA),60));
else
setfillcolor(SCGAddColor(RGB(0xAA,0xFF,0xAA),80));
}
if(NULL==pStudent)
{
solidrectangle(pParam->boxLine.left+1, pParam->boxLine.top+1,pParam->boxLine.left+pParam->boxLine.width+1,pParam->boxLine.top+pParam->boxLine.height+1 );
return;
}
solidrectangle(pParam->boxLine.left+1, pParam->boxLine.top+1,pParam->boxLine.left+pParam->boxLine.width+1,pParam->boxLine.top+pParam->boxLine.height+1 );
//image_drawZoomEx(&imgGet,pParam->boxLine.left,pParam->boxLine.top,pParam->boxLine.left+pParam->boxLine.width,pParam->boxLine.top+pParam->boxLine.height, pParam->boxLine.left,pParam->boxLine.top,pParam->boxLine.left+pParam->boxLine.width,pParam->boxLine.top+pParam->boxLine.height);
DrawListTableColumn( i++, pParam, pStudent->strID, &nX );
DrawListTableColumn( i++, pParam, pStudent->strName, &nX );
_stprintf_s( pText, 16, _T("%d"), pStudent->nAge);
DrawListTableColumn( i++, pParam, pText, &nX );
_stprintf_s( pText, 16, _T("%s"), pStudent->nSex?_T("男"):_T("女"), 2);
DrawListTableColumn( i++, pParam, pText, &nX );
_stprintf_s( pText, 16, _T("%d-%d"), pStudent->nYear, pStudent->nMonth);
DrawListTableColumn( i++, pParam, pText, &nX );
DrawListTableColumn( i++, pParam, pStudent->strAddress, &nX );
DrawListTableColumn( i++, pParam, pStudent->strPhone, &nX );
DrawListTableColumn( i++, pParam, pStudent->strEmail, &nX );
}
void DrawExamList(tagSG_ListTableDrawParam *pParam)
{
TCHAR pText[16];
int i=0;
int nX = pParam->boxLine.left;
tagExam* pExam = GetExamByIndex(pParam->nDataIndex);
if(pParam->nState ==enumLTS_SELECTED )
{
setfillcolor(SCGAddColor(RGB(140,250,0xFF),30));
}
else
{
if(pParam->nLine%2)
setfillcolor(SCGAddColor(RGB(0xAA,0xFF,0xAA),60));
else
setfillcolor(SCGAddColor(RGB(0xAA,0xFF,0xAA),80));
}
if(NULL==pExam)
{
solidrectangle(pParam->boxLine.left+1, pParam->boxLine.top+1,pParam->boxLine.left+pParam->boxLine.width+1,pParam->boxLine.top+pParam->boxLine.height+1 );
return;
}
solidrectangle(pParam->boxLine.left+1, pParam->boxLine.top+1,pParam->boxLine.left+pParam->boxLine.width+1,pParam->boxLine.top+pParam->boxLine.height+1 );
_stprintf_s( pText, 16, _T("%d"), pExam->nID);
DrawListTableColumn( i++, pParam, pText, &nX );
DrawListTableColumn( i++, pParam, pExam->strName, &nX );
DrawListTableColumn( i++, pParam, pExam->strBatch, &nX );
_stprintf_s( pText, 16, _T("%d"), pExam->nCount);
DrawListTableColumn( i++, pParam, pText, &nX );
_stprintf_s( pText, 16, _T("%.2f"), pExam->fAveScore);
DrawListTableColumn( i++, pParam, pText, &nX );
_stprintf_s( pText, 16, _T("%.2f"), pExam->fMax);
DrawListTableColumn( i++, pParam, pText, &nX );
_stprintf_s( pText, 16, _T("%.2f"), pExam->fMin);
DrawListTableColumn( i++, pParam, pText, &nX );
}
void DrawScoreList(tagSG_ListTableDrawParam *pParam)
{
TCHAR pText[16];
int i=0;
int nX = pParam->boxLine.left;
tagScore* pScore = GetScoreByIndex(pParam->nDataIndex);
if(pParam->nState ==enumLTS_SELECTED )
{
setfillcolor(SCGAddColor(RGB(140,250,0xFF),30));
}
else
{
if(pParam->nLine%2)
setfillcolor(SCGAddColor(RGB(0xAA,0xFF,0xAA),60));
else
setfillcolor(SCGAddColor(RGB(0xAA,0xFF,0xAA),80));
}
if(NULL==pScore)
{
solidrectangle(pParam->boxLine.left+1, pParam->boxLine.top+1,pParam->boxLine.left+pParam->boxLine.width+1,pParam->boxLine.top+pParam->boxLine.height+1 );
return;
}
solidrectangle(pParam->boxLine.left+1, pParam->boxLine.top+1,pParam->boxLine.left+pParam->boxLine.width+1,pParam->boxLine.top+pParam->boxLine.height+1 );
_stprintf_s( pText, 16, _T("%d"), pScore->nID);
DrawListTableColumn( i++, pParam, pText, &nX );
DrawListTableColumn( i++, pParam, pScore->strExamName, &nX );
DrawListTableColumn( i++, pParam, pScore->strExamBatch, &nX );
DrawListTableColumn( i++, pParam, pScore->strStuID, &nX );
DrawListTableColumn( i++, pParam, pScore->strStuName, &nX );
/*_stprintf_s( pText, 16, _T("%d"), pScore->nExamID);
DrawListTableColumn( i++, pParam, pText, &nX );
_stprintf_s( pText, 16, _T("%d"), pScore->nStuID);
DrawListTableColumn( i++, pParam, pText, &nX );*/
_stprintf_s( pText, 16, _T("%.2f"), pScore->fScore);
DrawListTableColumn( i++, pParam, pText, &nX );
}
void DrawListTable(HSCGTREEID hObjectID, tagSG_ListTableDrawParam *pParam)
{
if(hObjectID == g_hFrame[enumTABLE_STU])
DrawStuList(pParam);
if(hObjectID == g_hFrame[enumTABLE_EXAM] )
DrawExamList(pParam);
if(hObjectID == g_hFrame[enumTABLE_SCORE] )
DrawScoreList(pParam);
}
void CreateGUI()
{
tagSG_Box rt={10,200,150,25};
g_hButton[enumBTN_STU] = create_btnFlat(NULL,_T("学生管理"), RGB(0,168,90),enumBTN_STU, &rt);
rt.top += 24;
g_hButton[enumBTN_STU_ADD] = create_btnFlat(NULL,_T("添加学生"), RGB(0xAA,0xFF,0xAA),enumBTN_STU_ADD, &rt);
rt.top += 24;
g_hButton[enumBTN_STU_DEL] = create_btnFlat(NULL,_T("删除学生"), RGB(0xAA,0xFF,0xAA),enumBTN_STU_DEL,&rt);
rt.top += 24;
g_hButton[enumBTN_STU_MODIFY] = create_btnFlat(NULL,_T("修改学生"), RGB(0xAA,0xFF,0xAA),enumBTN_STU_MODIFY,&rt);
rt.top += 24;
g_hButton[enumBTN_STU] = create_btnFlat(NULL,_T("成绩管理"), RGB(0,168,90),enumBTN_EXAM, &rt);
rt.top += 24;
g_hButton[enumBTN_EXAM_ADD] = create_btnFlat(NULL,_T("添加科目"), RGB(0xAA,0xFF,0xAA),enumBTN_EXAM_ADD,&rt);
rt.top += 24;
g_hButton[enumBTN_EXAM_DEL] = create_btnFlat(NULL,_T("删除科目"), RGB(0xAA,0xFF,0xAA),enumBTN_EXAM_DEL,&rt);
rt.top += 24;
g_hButton[enumBTN_EXAM_MODIFY] = create_btnFlat(NULL,_T("修改科目"), RGB(0xAA,0xFF,0xAA),enumBTN_EXAM_MODIFY,&rt);
rt.top += 24;
g_hButton[enumBTN_EXAMRESULT_MODIFY] = create_btnFlat(NULL,_T("成绩录入"), RGB(0xAA,0xFF,0xAA),enumBTN_EXAMRESULT_MODIFY,&rt);
rt.top += 24;
g_hButton[enumBTN_SYS_SAVE] = create_btnFlat(NULL,_T("保存所有"), RGB(0,168,90),enumBTN_SYS_SAVE,&rt);
rt.top += 24;
g_hButton[enumBTN_SYS_LOAD] = create_btnFlat(NULL,_T("加载记录"), RGB(0,168,90),enumBTN_SYS_LOAD,&rt);
rt.top += 24;
g_hButton[enumBTN_SYS_EXIT] = create_btnFlat(NULL,_T("退出系统"), RGB(0,168,90),enumBTN_SYS_EXIT,&rt);
OnStuManage();
}
//绘制所有内容
void Redraw()
{
int nColor = 0;
int nMode = 0;
LOGFONT lf;
image_drawZoom(&imgGet,0,0,C_IMAGE_WIDTH,C_IMAGE_HEIGHT);
lf = *gettextfont();
nColor = settextcolor(RGB(255,127,40));
nMode = setbackmode( enumBKM_TRANSPARENT );
settextfont( 60,28,_T("微软雅黑"));
outtextXY( 200, 10, _T("SIMPLE学生信息管理"));
setbackmode( nMode );
settextcolor(nColor);
settextfontEx(&lf);
RenderAll();
}
LRESULT OnLButtonDown( HWND hWnd, WPARAM wParam, int nX, int nY )
{
POINT pt;
pt.x = nX;
pt.y = nY;
return TRUE;
}
LRESULT OnLButtonUp( HWND hWnd, WPARAM wParam, int nX, int nY )
{
POINT pt;
pt.x = nX;
pt.y = nY;
return TRUE;
}
LRESULT OnMouseMove( HWND hWnd, WPARAM wParam, int nX, int nY )
{
POINT pt;
pt.x = nX;
pt.y = nY;
if( wParam & MK_LBUTTON )
{
}
else
{
}
return TRUE;
}
void OnStuManage()
{
SCGUIButton_EnableButton(g_hButton[enumBTN_STU_ADD],true);
SCGUIButton_EnableButton(g_hButton[enumBTN_STU_DEL],true);
SCGUIButton_EnableButton(g_hButton[enumBTN_STU_MODIFY],true);
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAM_ADD],false);
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAM_DEL],false);
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAM_MODIFY],false);
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAMRESULT_MODIFY],false);
ShowFrame(enumTABLE_STU);
}
void OnExamManage()
{
SCGUIButton_EnableButton(g_hButton[enumBTN_STU_ADD],false);
SCGUIButton_EnableButton(g_hButton[enumBTN_STU_DEL],false);
SCGUIButton_EnableButton(g_hButton[enumBTN_STU_MODIFY],false);
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAM_ADD],true);
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAM_DEL],true);
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAM_MODIFY],true);
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAMRESULT_MODIFY],true);
SCGUIButton_SetText(g_hButton[enumBTN_EXAMRESULT_MODIFY],_T("成绩录入"));
ShowFrame(enumTABLE_EXAM);
}
void OnAddStu()
{
g_nSaveCommand = enumBTN_STU_ADD;
ShowFrame(enumFRAME_STU);
SCGUIButton_SetText(g_hButton[enumBTN_STU_SAVEADD],_T("确认添加"));
SCGEdit_SetTextInt( g_hEditStu[enumEDITSTU_ID], GetMaxStudentID()+1 );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_STRID], _T("") );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_STRNAME], _T("") );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_AGE], _T("") );
RadioGroup_SetCurRadio( g_hEditStu[enumEDITSTU_SEX], 0 );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_YEAR], _T("") );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_MONTH], _T("") );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_ADDRESS], _T("") );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_PHONE], _T("") );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_EMAIL], _T("") );
}
void OnAddExam()
{
g_nSaveCommand = enumBTN_EXAM_ADD;
ShowFrame(enumFRAME_EXAM);
SCGUIButton_SetText(g_hButton[enumBTN_EXAM_SAVEADD],_T("确认添加"));
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAMRESULT_MODIFY],false);
SCGEdit_SetTextInt( g_hEditExam[enumEDITEXAM_ID], GetMaxExamID()+1 );
SCGEdit_SetText( g_hEditExam[enumEDITEXAM_STRNAME], _T("") );
SCGEdit_SetText( g_hEditExam[enumEDITEXAM_STRBATCH], _T("") );
SCGEdit_SetText( g_hEditExam[enumEDITEXAM_FAILESCORE], _T("") );
SCGEdit_SetText( g_hEditExam[enumEDITEXAM_EXCELLENTSCORE], _T("") );
}
void OnModifyStu()
{
tagStudent* pStudent = NULL;
int nSel = ListTable_GetCurSel(g_hFrame[enumTABLE_STU]);
g_nSaveCommand = enumBTN_STU_MODIFY;
if(nSel<0)
{
MessageBox(NULL,_T("请选择修改的学生"),_T(""),MB_OK);
return;
}
pStudent = GetStudentByIndex(nSel);
if( NULL == pStudent)
return;
ShowFrame(enumFRAME_STU);
SCGEdit_SetTextInt( g_hEditStu[enumEDITSTU_ID], pStudent->nID );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_STRID], pStudent->strID );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_STRNAME], pStudent->strName );
SCGEdit_SetTextInt( g_hEditStu[enumEDITSTU_AGE], pStudent->nAge );
RadioGroup_SetCurRadio( g_hEditStu[enumEDITSTU_SEX], pStudent->nSex );
SCGEdit_SetTextInt( g_hEditStu[enumEDITSTU_YEAR], pStudent->nYear );
SCGEdit_SetTextInt( g_hEditStu[enumEDITSTU_MONTH], pStudent->nMonth );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_ADDRESS], pStudent->strAddress );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_PHONE], pStudent->strPhone );
SCGEdit_SetText( g_hEditStu[enumEDITSTU_EMAIL], pStudent->strEmail );
SCGUIButton_SetText(g_hButton[enumBTN_STU_SAVEADD],_T("确认修改"));
}
void OnModifyExam()
{
tagExam* pExam = NULL;
int nSel = ListTable_GetCurSel(g_hFrame[enumTABLE_EXAM]);
g_nSaveCommand = enumBTN_EXAM_MODIFY;
if(nSel<0)
{
MessageBox(NULL,_T("请选择修改的科目"),_T(""),MB_OK);
return;
}
pExam = GetExamByIndex(nSel);
if( NULL == pExam)
return;
ShowFrame(enumFRAME_EXAM);
SCGEdit_SetTextInt( g_hEditExam[enumEDITEXAM_ID], pExam->nID );
SCGEdit_SetText( g_hEditExam[enumEDITEXAM_STRNAME], pExam->strName );
SCGEdit_SetText( g_hEditExam[enumEDITEXAM_STRBATCH], pExam->strBatch );
SCGEdit_SetTextFloat( g_hEditExam[enumEDITEXAM_FAILESCORE], pExam->fFaileScore );
SCGEdit_SetTextFloat( g_hEditExam[enumEDITEXAM_EXCELLENTSCORE], pExam->fExcellentScore );
SCGUIButton_SetText(g_hButton[enumBTN_EXAM_SAVEADD],_T("确认修改"));
SCGUIButton_EnableButton(g_hButton[enumBTN_EXAMRESULT_MODIFY],false);
}
void OnSaveStu()
{
tagStudent stu;
stu.nID = SCGEdit_GetTextInt(g_hEditStu[enumEDITSTU_ID]);
SCGEdit_GetText( g_hEditStu[enumEDITSTU_STRID], stu.strID, 20 );
SCGEdit_GetText( g_hEditStu[enumEDITSTU_STRNAME], stu.strName, 20 );
stu.nAge = SCGEdit_GetTextInt(g_hEditStu[enumEDITSTU_AGE]);
stu.nSex = RadioGroup_GetCurRadioID(g_hEditStu[enumEDITSTU_SEX]);
stu.nYear = SCGEdit_GetTextInt(g_hEditStu[enumEDITSTU_YEAR]);
stu.nMonth = SCGEdit_GetTextInt(g_hEditStu[enumEDITSTU_MONTH]);
SCGEdit_GetText( g_hEditStu[enumEDITSTU_ADDRESS], stu.strAddress, 60 );
SCGEdit_GetText( g_hEditStu[enumEDITSTU_PHONE], stu.strPhone, 20 );
SCGEdit_GetText( g_hEditStu[enumEDITSTU_EMAIL], stu.strEmail, 30 );
if(enumBTN_STU_ADD == g_nSaveCommand)
{
if( AddStudent(&stu))
{
OnStuManage();
}
else
MessageBox(NULL,_T("添加失败"),_T("提示"),MB_OK);
}
else if(enumBTN_STU_MODIFY == g_nSaveCommand)
{
if( UpdateStudent(stu.nID, &stu))
{
OnStuManage();
}
else
MessageBox(NULL,_T("修改失败"),_T("提示"),MB_OK);
}
}
void OnSaveExam()
{
tagExam Exam;
Exam.nID = SCGEdit_GetTextInt( g_hEditExam[enumEDITEXAM_ID] );
SCGEdit_GetText( g_hEditExam[enumEDITEXAM_STRNAME], Exam.strName, 20 );
SCGEdit_GetText( g_hEditExam[enumEDITEXAM_STRBATCH], Exam.strBatch, 20 );
Exam.fFaileScore = SCGEdit_GetTextFloat(g_hEditExam[enumEDITEXAM_FAILESCORE]);
Exam.fExcellentScore = SCGEdit_GetTextFloat(g_hEditExam[enumEDITEXAM_EXCELLENTSCORE]);
Exam.fAveScore=0;
Exam.fMin=0;
Exam.fMax=0;
Exam.nCount=0;
if(enumBTN_EXAM_ADD == g_nSaveCommand)
{
if( AddExam(&Exam))
{
OnExamManage();
}
else
MessageBox(NULL,_T("添加失败"),_T("提示"),MB_OK);
}
else if(enumBTN_EXAM_MODIFY == g_nSaveCommand)
{
if( UpdateExam(Exam.nID, &Exam))
{
OnExamManage();
}
else
MessageBox(NULL,_T("修改失败"),_T("提示"),MB_OK);
}
}
void OnDelStu()
{
int nSel = ListTable_GetCurSel(g_hFrame[enumTABLE_STU]);
if(nSel>=0)
{
TCHAR pText[32];
tagStudent* pStu = GetStudentByIndex(nSel);
if( NULL != pStu)
{
_stprintf_s( pText, 32, _T("是否删除学生%s-%s?"), pStu->strID, pStu->strName );
if( IDNO==MessageBox(NULL,pText,_T("确认"),MB_YESNO))
return;
if( DelStudent(pStu->nID))
Redraw();
}
}
else
MessageBox(NULL,_T("请选择删除的学生"),_T(""),MB_OK);
}
void OnDelExam()
{
int nSel = ListTable_GetCurSel(g_hFrame[enumTABLE_EXAM]);
if(nSel>=0)
{
TCHAR pText[64];
tagExam* pExam = GetExamByIndex(nSel);
if( NULL != pExam)
{
_stprintf_s( pText, 64, _T("是否删除科目%d-%s?"), pExam->nID, pExam->strName, 20 );
if( IDNO==MessageBox(NULL,pText,_T("确认"),MB_YESNO))
return;
if( DelExam(pExam->nID))
Redraw();
}
}
else
MessageBox(g_hMainWnd,_T("请选择删除的科目"),_T(""),MB_OK);
}
void GetSubName(TCHAR *pExamFileName, DWORD nSize, const TCHAR *pStudentFileName, const TCHAR *pSubFileName )
{
DWORD nDot = 0;
const TCHAR *pSrc = pStudentFileName;
TCHAR *pDst = pExamFileName;
DWORD nSrcLen = _tcslen(pStudentFileName);
for( nDot = 0; nDot<nSize; ++nDot)
{
if(*pSrc==_T('.')||nSrcLen<=nDot)
{
break;
}
*pDst++ = *pSrc++;
}
nSize -= nDot;
_tcscat_s( pDst, nSize, pSubFileName );
pDst+=4;
nSize -= 4;
_tcscat_s( pDst, nSize, pSrc );
}
//成绩录入
void OnExamResult()
{
TCHAR pFileScoreName[MAX_PATH]={0};
tagExam* pExam = NULL;
tagScore* pScore = NULL;
tagStudent* pStudentList = NULL;
TCHAR pScoreName[MAX_PATH]={0};
bool bInitScore = true;
int nSel = ListTable_GetCurSel(g_hFrame[enumTABLE_EXAM]);
if(nSel<0)
{
MessageBox(NULL,_T("请选择要录入成绩的科目"),_T(""),MB_OK);
return;
}
pExam = GetExamByIndex(nSel);
if( NULL == pExam)
return;
_stprintf_s( pScoreName, MAX_PATH, _T("Score%d"), pExam->nID );
GetSubName( pFileScoreName, MAX_PATH, g_pFileName, pScoreName );
//之前如果是显示成绩录入,现在是保存
if(GetCurFrame()==g_hFrame[enumTABLE_SCORE])
{
if(SaveToFileScore(pFileScoreName))
MessageBox(g_hMainWnd,_T("成功保存当前科目分数"),_T(" 提示"),MB_OK);
return ;
}
if(LoadFromeFileScore(pFileScoreName))
{
pScore = FirtScore();
if(NULL!=pScore)
bInitScore = false;
}
else
{
InitScoreList();
}
//初始化分数表等待录入
if(bInitScore)
{
tagScore score;
pStudentList = FirtStudent();
while(pStudentList)
{
score.nID = GetMaxScoreID()+1;
score.nExamID = pExam->nID;
score.nStuID = pStudentList->nID;
score.fScore = 0.0f;
_tcscpy_s( score.strExamName, 20, pExam->strName );
_tcscpy_s( score.strExamBatch, 20, pExam->strBatch );
_tcscpy_s( score.strStuID, 20, pStudentList->strID );
_tcscpy_s( score.strStuName, 20, pStudentList->strName );
if( !AddScore(&score))
break;
pStudentList = NextStudent(pStudentList);
}
}
ShowFrame(enumTABLE_SCORE);
SCGUIButton_SetText(g_hButton[enumBTN_EXAMRESULT_MODIFY],_T("保存成绩"));
}
void OnSaveFile()
{
TCHAR pFileName[MAX_PATH]={0};
TCHAR pFileExamName[MAX_PATH]={0};
_tcsncpy_s(pFileName, MAX_PATH,_T("student.txt"), 11);
if( !WHGetSaveFileName( g_hMainWnd, pFileName, MAX_PATH, _T("文本文件(*.txt)\0*.txt\0All Files(*.*)\0*.*\0")) )
return;
GetSubName( pFileExamName, MAX_PATH, pFileName, _T("Exam") );
if( !SaveToFile(pFileName) )
return;
if( !SaveToFileExam(pFileExamName) )
return;
_tcscpy_s( g_pFileName, MAX_PATH, pFileName );
MessageBox(g_hMainWnd,_T("成功保存文件"),_T(""),MB_OK);
}
void OnOpenFile()
{
TCHAR pFileName[MAX_PATH]={0};
TCHAR pFileExamName[MAX_PATH]={0};
_tcsncpy_s(pFileName, MAX_PATH,_T("student.txt"), 11);
if( !WHGetOpenFileName( g_hMainWnd, pFileName, MAX_PATH, _T("文本文件(*.txt)\0*.txt\0All Files(*.*)\0*.*\0")) )
return;
GetSubName( pFileExamName, MAX_PATH, pFileName, _T("Exam") );
if( !LoadFromeFile(pFileName) )
return;
if( !LoadFromeFile(pFileExamName) )
return;
_tcscpy_s( g_pFileName, MAX_PATH, pFileName );
OnStuManage();
}
void OnCommand( int nCmd )
{
switch( nCmd )
{
case enumBTN_STU_ADD:
OnAddStu();
break;
case enumBTN_STU_MODIFY:
OnModifyStu();
break;
case enumBTN_STU_SAVEADD:
OnSaveStu();
break;
case enumBTN_EXAM_ADD:
OnAddExam();
break;
case enumBTN_EXAM_MODIFY:
OnModifyExam();
break;
case enumBTN_EXAM_SAVEADD:
OnSaveExam();
break;
case enumBTN_RETURN:
if(enumBTN_STU_MODIFY == g_nSaveCommand||enumBTN_STU_ADD == g_nSaveCommand)
OnStuManage();
if(enumBTN_EXAM_ADD == g_nSaveCommand||enumBTN_EXAM_MODIFY == g_nSaveCommand)
OnExamManage();
break;
case enumBTN_STU_DEL:
OnDelStu();
break;
case enumBTN_EXAM_DEL:
OnDelExam();
break;
case enumBTN_STU:
OnStuManage();
break;
case enumBTN_EXAM:
OnExamManage();
break;
case enumBTN_EXAMRESULT_MODIFY:
OnExamResult();
break;
case enumBTN_SYS_SAVE:
OnSaveFile();
break;
case enumBTN_SYS_LOAD:
OnOpenFile();
break;
case enumBTN_SYS_EXIT:
DestroyWindow(g_hMainWnd);
break;
}
}
bool OnUIMessage( HSCGTREEID hObject, UINT nMessage, int nCode, int nData )
{
switch(nMessage)
{
case enumMSGNOTIFY_COMMAND:
OnCommand( nData );
break;
}
return true;
}
void Init()
{
TCHAR pFileExamName[MAX_PATH]={0};
//初始化学生表
setlocale(LC_ALL, "");
InitList();
InitExamList();
InitScoreList();
_tcscpy_s( g_pFileName, MAX_PATH, _T("student.txt") );
GetSubName( pFileExamName, MAX_PATH, _T("student.txt"), _T("Exam"));
if(LoadFromeFile(_T("student.txt")))
_tprintf(_T("读取成功\n"));
else
_tprintf(_T("读取失败\n"));
if(LoadFromeFileExam(pFileExamName))
_tprintf(_T("读取科目成功\n"));
else
_tprintf(_T("读取科目失败\n"));
g_pStudent = FirtStudent();
}
int _tmain(int argc, _TCHAR* argv[])
{
SetMouseProcess( enumINMSG_LBUTTONDOWN, OnLButtonDown);
SetMouseProcess( enumINMSG_LBUTTONUP, OnLButtonUp);
SetMouseProcess( enumINMSG_MOUSEMOVE, OnMouseMove);
Init();
if( !InitApp(C_IMAGE_WIDTH, C_IMAGE_HEIGHT))
return 1;
imgGet=image_load( _T("back.jpg"));
g_hMainWnd = getdrawingHWND();
InitGUI(g_hMainWnd, OnUIMessage);
CreateGUI();
Redraw();
ReflushWindow();
RunningApp();
image_release(&imgGet);
CloseGUI();
ReleaseApp();
//释放学生表
ReleaseList();
ReleaseListExam();
return 0;
}
基本上就是界面显示及操作,实际数据操作由上面三个数据相关文件完成。功能上已经完成所有数据的录入功能。由于篇幅原因,数据查询功能将在下一篇文章介绍。
演示界面如下
当前功能可添加修改学生信息、课程信息,分数录入,数据保存 及加载,后续添加数据查询、数据统计功能。对代码有不明白的同学可以评论区留言,有必要的话可以在后续文章详细介绍。
四、相关项目下载
运行程序下载CDStudentManage/bin · master · b2b160 / SimpleCG_Demo · GitCode
SimpleCG库安装方法如下