C 语言课程设计:SimpleCG打造实用学生信息管理(一)

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库安装方法如下

SimpleCG库安装使用_b2b160的博客-CSDN博客

SimpleGUI库下载

C 语言课程设计:SimpleCG打造实用学生信息管理(二) 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

b2b160

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值