以学生信息管理系统为例,通过对简单应用软件系统的设计,编制、调试,实现简单的增加、删除、修改、排序等运算,以学习应用MFC库类编写对话框的原理,加深对C++类的学习及应用。初步掌握基于MFC库类对话框界面的设计,通过创建类成员函数成员变量,编辑控件创建消息映射,调用消息函数完成数据的输入输出,实现相关功能。
1.需求分析
该程序要能实现对学生成绩信息的显示、增加、删除、修改,实现对学生按学号、按姓名查询显示,实现字段筛选功能,能够统计统计全部学生的总成绩,及其平均成绩,各个输入字段要有验证功能,能够进行各个学科的排序检索以及成绩数据分析功能。
2.功能介绍
(1)添加功能:程序能够添加学生记录和各科成绩,提供选择界面供用户选择所要添加的类别。添加记录时,要求学号唯一,如果是添加了重复记录,则提示数据添加重复并取消添加。
(2)删除功能:主要实现对已添加的学生和成绩记录进行删除。如果当前系统中没有相应的记录,则提示为空并返回操作。
(3)修改功能:用户根据选择的记录进行修改,修改时保持学号编号唯一,设置只读功能,其他信息皆可更改。
(4)显示功能:程序设置数据在列表控件中,每条记录占据一行。
(5)保存功能:在添加、删除、修改的同时读取文件,自动保存数据到文件。
(6)查询功能:程序设计三种查询方式,第一种按学号进行查询,第一种按姓名查询,第三种按照班别筛选查询。
(7)排序功能:首先依照排序的依据,可根据学号、各科成绩、总分以及平均分进行排序,页面刷新显示数据。
(8)统计功能:转跳另一个可执行文件进行学生成绩数据整体分析,统计某个分数段内的学生人数,绘制各科成绩的直方图和折线图。
(9)登录功能:设计管理员登录才进入学生成绩信息管理系统进行增删改查等操作。
设计一个基于MFC对话框的C++应用程序开发,因此要创建一个主对话框,和一些必要的子对话框。在主对话框中添加列表控件用来显示学生的基本信息,并且列表控件要有较强的数据处理函数。因此选择列表控件,对于学生信息的录入、查询、排序、删除与修改都采用按钮控件,并为每个按钮添加消息响应函数用来处理学生的信息操作。对于录入功能和修改功能,可以为它设置一个子对话框来填写学生的基本信息。接下来就要把学生的基本信息能够保存下来,因此要用到文件的操作。
此外,还运用到单文档设计的学生成绩分析图形绘制。并用该学生成绩信息管理系统调用该画图的exe文件,实现在该学生成绩信息管理系统中显示学生成绩的直方图和折线图。
综上所述,必须掌握按钮控件、列表控件、组合框控件的构建,编辑控件和消息的相应与处理原理,同时掌握CFile类和图像和文字绘制类的运用。
1.系统登录界面:
运行程序,首先出现登录界面,输入管理员用户名和密码,输入正确进入系统。
(一)设计Student类
总图
设计一个学生类,包括数据成员:姓名、学号,八门课程(语文、数学、英语、物理、化学、生物、历史、体育)的成绩。Student类添加在 类CEx_StudentApp之上
// Ex_Student.h : main header file for the EX_STUDENT application
//
#if !defined(AFX_EX_STUDENT_H__1201A7FC_72F9_41BB_8775_1B2AFB4378FA__INCLUDED_)
#define AFX_EX_STUDENT_H__1201A7FC_72F9_41BB_8775_1B2AFB4378FA__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include
#include
#include
#include
using namespace std;
#include "resource.h" // main symbols
/
// CEx_StudentApp:
// See Ex_Student.cpp for the implementation of this class
//
class Student {
public:
char strName[20];
char strID[20];
char sClass[20];
char sSex[2];
char sAddress[100];
char sBirthday[20];
char sAge[5];
char fChinese[5];
char fMath[5];
char fEnglish[5];
char fPhysics[5];
char fBiology[5];
char fChemistry[5];
char fHistory[5];
char fSport[5];
char fAve[20];
char fTotal[20];
Student() {
};
bool sort_id(Student a, Student b);
bool sort_total(Student a, Student b);
bool sort_ave(Student a, Student b);
bool sort_chinese(Student a, Student b);
bool sort_math(Student a, Student b);
bool sort_english(Student a, Student b);
bool sort_pyhsics(Student a, Student b);
bool sort_chemistry(Student a, Student b);
bool sort_biology(Student a, Student b);
bool sort_history(Student a, Student b);
bool sort_sport(Student a, Student b);
};
class CEx_StudentApp : public CWinApp
{
public:
CEx_StudentApp();
Student temp; //全局变量,存放学生的临时数据
// Overrides
// ClassWizard generated virtual function overrides
//{
{AFX_VIRTUAL(CEx_StudentApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{
{AFX_MSG(CEx_StudentApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/
//{
{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EX_STUDENT_H__1201A7FC_72F9_41BB_8775_1B2AFB4378FA__INCLUDED_)
(二)主框架源代码
1. 主框架变量
ID控件 | 变量名 |
---|---|
IDC_COMBO_CLASS | CComboBox m_ComboBoxClass; |
IDC_COMBO_SORT | CComboBox m_ComboBoxSort; |
IDC_LIST | CListCtrl m_list; |
2.主框架头文件
// Ex_StudentDlg.h : header file
//
#if !defined(AFX_EX_STUDENTDLG_H__DB137ADD_497D_455F_A457_A4497BF81B6E__INCLUDED_)
#define AFX_EX_STUDENTDLG_H__DB137ADD_497D_455F_A457_A4497BF81B6E__INCLUDED_
#include "Ex_Student.h" // Added by ClassView
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
extern CEx_StudentApp theApp; //引用全局变量theApp
/
// CEx_StudentDlg dialog
class CEx_StudentDlg : public CDialog
{
// Constructio
public:
void SortStudent(int nNum);
int Seek_Student(char *str);
void ComboBoxAddString();
void ReadStudent(CListCtrl* pList);
CEx_StudentDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{
{AFX_DATA(CEx_StudentDlg)
enum {
IDD = IDD_EX_STUDENT_DIALOG };
CComboBox m_ComboBoxClass;
CComboBox m_ComboBoxSort;
CListCtrl m_list;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{
{AFX_VIRTUAL(CEx_StudentDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{
{AFX_MSG(CEx_StudentDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButtonAdd();
afx_msg void OnButtonDel();
afx_msg void OnButtonQuest();
afx_msg void OnButtonSort();
afx_msg void OnButtonEdit();
afx_msg void OnButtonAnalysis();
afx_msg void OnButtonScreen();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{
{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EX_STUDENTDLG_H__DB137ADD_497D_455F_A457_A4497BF81B6E__INCLUDED_)
3. 主框架源代码
// Ex_StudentDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Ex_Student.h"
#include "Ex_StudentDlg.h"
#include "StuAddDlg.h"
#include "StuModifyDlg.h" //引用修改子对话框头文件
#include
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{
{AFX_DATA(CAboutDlg)
enum {
IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{
{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{
{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{
{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{
{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{
{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CEx_StudentDlg dialog
CEx_StudentDlg::CEx_StudentDlg(CWnd* pParent /*=NULL*/)
: CDialog(CEx_StudentDlg::IDD, pParent)
{
//{
{AFX_DATA_INIT(CEx_StudentDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CEx_StudentDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{
{AFX_DATA_MAP(CEx_StudentDlg)
DDX_Control(pDX, IDC_COMBO_CLASS, m_ComboBoxClass);
DDX_Control(pDX, IDC_COMBO_SORT, m_ComboBoxSort);
DDX_Control(pDX, IDC_LIST, m_list);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CEx_StudentDlg, CDialog)
//{
{AFX_MSG_MAP(CEx_StudentDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd)
ON_BN_CLICKED(IDC_BUTTON_DEL, OnButtonDel)
ON_BN_CLICKED(IDC_BUTTON_QUEST, OnButtonQuest)
ON_BN_CLICKED(IDC_BUTTON_SORT, OnButtonSort)
ON_BN_CLICKED(IDC_BUTTON_EDIT, OnButtonEdit)
ON_BN_CLICKED(IDC_BUTTON_ANALYSIS, OnButtonAnalysis)
ON_BN_CLICKED(IDC_BUTTON_SCREEN, OnButtonScreen)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CEx_StudentDlg message handlers
BOOL CEx_StudentDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
//初始化CListCtrl控件。插入一些标头,设置宽度和序列号。
CRect rect;
// 获取编程语言列表视图控件的位置和大小
m_list.GetClientRect(&rect);
// 为列表视图控件添加全行选中和栅格风格
m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
CString col[13] = {
_T("学号"), _T("姓名"), _T("班级"), _T("语文"),_T("数学"),_T("英语"),_T("物理"),_T("化学"),_T("生物"),_T("历史"),_T("体育"),_T("总分"),_T("平均分")};
for (int i = 0; i < 13; i++) {
m_list.InsertColumn(i, col[i], LVCFMT_CENTER, 80);
}
CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
CEx_StudentDlg::ReadStudent(pList); //更新CListCtrl里的数据
CEx_StudentDlg::ComboBoxAddString(); //更新下拉框数据
CheckRadioButton(IDC_RADIO_ID, IDC_RADIO_NAME, IDC_RADIO_ID); //默认单选按钮为学号
CEx_StudentDlg::OnButtonSort(); //默认按学号排序
m_ComboBoxClass.SetCurSel(0); //默认班级为第一个选项
return TRUE; // return TRUE unless you set the focus to a control
}
void CEx_StudentDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CEx_StudentDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CEx_StudentDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//添加按钮控件函数
void CEx_StudentDlg::OnButtonAdd()
{
// TODO: Add your control notification handler code here
CStuAddDlg dlg;
if(IDOK == dlg.DoModal()) {
CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
CEx_StudentDlg::ReadStudent(pList);
CEx_StudentDlg::ComboBoxAddString();
CEx_StudentDlg::OnButtonSort(); //默认按学号排序
}
}
//读取储存学生成绩的文件,并加载在学生成绩管理系统窗口的CListCtrl中
void CEx_StudentDlg::ReadStudent(CListCtrl *pList)
{
CFile file;
if (!file.Open("./studentfile.dat", CFile::modeRead | CFile::modeCreate | CFile::modeNoTruncate))
{
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
pList->DeleteAllItems();
Student u;
int i = 0;
while(file.Read(&u, sizeof(u)) == sizeof(u)) {
pList->InsertItem(i, u.strID);
pList->SetItemText(i, 1, u.strName);
pList->SetItemText(i, 2, u.sClass);
pList->SetItemText(i, 3, u.fChinese);
pList->SetItemText(i, 4, u.fMath);
pList->SetItemText(i, 5, u.fEnglish);
pList->SetItemText(i, 6, u.fPhysics);
pList->SetItemText(i, 7, u.fChemistry);
pList->SetItemText(i, 8, u.fBiology);
pList->SetItemText(i, 9, u.fHistory);
pList->SetItemText(i, 10, u.fSport);
pList->SetItemText(i, 11, u.fTotal);
pList->SetItemText(i, 12, u.fAve);
i++;
}
file.Close();
}
//删除按钮消息映射函数
void CEx_StudentDlg::OnButtonDel()
{
// TODO: Add your control notification handler code here
CString str, strItemName;
Student ur;
/*
//删除多行
int count = m_list.GetSelectedCount();
CString *strID = new CString[count];
int j=0;
if(count < 1) {
AfxMessageBox("你还没选中列表项!");
return;
}
for(int i = m_list.GetItemCount()-1; i>=0; i--)
{
if(m_list.GetItemState(i, LVNI_ALL | LVNI_SELECTED) == LVIS_SELECTED)
{
m_list.DeleteItem(i);
m_list.GetItemText(i, 0, ur[j].strID, sizeof(ur[j].strID));
j++;
}
}
str.Format("%s", ur[0].strID);
AfxMessageBox(str);
*/
//删除一行
int nID = m_list.GetSelectedCount(); //获取当前鼠标选择的学号数量
if(nID < 1) {
AfxMessageBox("你还没选中列表项!");
return;
}
int nIDText = m_list.GetSelectionMark(); //获取当前鼠标选择的一个学号位置
m_list.GetItemText(nIDText, 0, ur.strID, sizeof(ur.strID)); //获取选中的学生的id号
strItemName = m_list.GetItemText(nIDText, 1); //获取选中的学生的姓名
str.Format("你确定要删除 %s 学生纪录吗?", strItemName);
if(IDOK != MessageBox(str, "删除确认", MB_ICONQUESTION | MB_OKCANCEL))
return;
m_list.DeleteItem(nIDText); //删除当前鼠标选择的学号位置
// 打开文件
CFile file;
if (!file.Open("./studentfile.dat", CFile::modeRead))
{
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
CFile temporaryfile;
if (!temporaryfile.Open("./temporarystudentfile.dat", CFile::modeCreate|CFile::modeWrite))
{
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
Student u;
while (file.Read(&u, sizeof(u)) == sizeof(u) ) {
//读取学生成绩储存文件,将未删除的学生信息写入临时文件temporaryfile中
if((CString)u.strID == (CString)ur.strID)
continue; //若为选中的学生纪录则跳过
temporaryfile.Write(&u, sizeof(u));
}
file.Close();
temporaryfile.Close();
if (!file.Open("./studentfile.dat", CFile::modeCreate|CFile::modeWrite))
{
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
if (!temporaryfile.Open("./temporarystudentfile.dat", CFile::modeRead))
{
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
while (temporaryfile.Read(&u, sizeof(u)) == sizeof(u)) {
//读取学生成绩储存文件,将临时文件temporarystudentfile.dat中学生信息写入真正存储学生信息的studentfile.dat中
file.Write(&u, sizeof(u));
}
file.Close();
temporaryfile.Close();
CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST); //更新学生成绩管理系统界面的信息
CEx_StudentDlg::ReadStudent(pList);
return;
}
//查找按钮消息映射函数
void CEx_StudentDlg::OnButtonQuest()
{
// TODO: Add your control notification handler code here
int nNum;
char str[20];
//查找前先取消原先选中的行的高亮样式
for(int i=0; i<m_list.GetItemCount(); i++) {
if(m_list.GetItemState(i, LVIS_SELECTED) == LVIS_SELECTED) {
//取消高亮选中
m_list.SetItemState(i, 0, LVIS_SELECTED| LVIS_FOCUSED);
}
}
GetDlgItemText(IDC_EDIT_SEANO, str, sizeof(str)); //获取编辑框的学号信息
if((CString)str == "") {
MessageBox(_T("请输入姓名或学号"), _T("警告"), MB_OK | MB_ICONWARNING);
return;
}
nNum = Seek_Student(str); //查询该学号是否存在
if (nNum == -1)
{
//AfxMessageBox("学号不存在!");
MessageBox(_T("没有找到该学生,请检查输入!"), _T("警告"), MB_OK | MB_ICONWARNING);
} else {
//高亮显示选中行
m_list.SetFocus();
m_list.SetItemState(nNum, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
m_list.EnsureVisible(nNum, FALSE);
}
}
//查找该学生是否存在成绩管理系统的CListCtrl中
int CEx_StudentDlg::Seek_Student(char *str)
{
int nCount = m_list.GetItemCount(); //listCtrl中的总行数
int i=0;
if(IDC_RADIO_ID == GetCheckedRadioButton(IDC_RADIO_ID, IDC_RADIO_NAME)) {
//如果输入的是学号
while(i<nCount) {
if(m_list.GetItemText(i, 0) == (CString)str)
return i;
i++;
}
} else {
//如果输入的是姓名
while(i<nCount) {
if(m_list.GetItemText(i, 1) == (CString)str)
return i;
i++;
}
}
return -1;
}
//设置组合框的排序依据
void CEx_StudentDlg::ComboBoxAddString()
{
m_ComboBoxSort.ResetContent(); //清空下拉框所有内容
m_ComboBoxSort.AddString("学号");
m_ComboBoxSort.AddString("总分");
m_ComboBoxSort.AddString("平均分");
m_ComboBoxSort.AddString("语文");
m_ComboBoxSort.AddString("数学");
m_ComboBoxSort.AddString("英语");
m_ComboBoxSort.AddString("物理");
m_ComboBoxSort.AddString("化学");
m_ComboBoxSort.AddString("生物");
m_ComboBoxSort.AddString("历史");
m_ComboBoxSort.AddString("体育");
m_ComboBoxSort.SetCurSel(0); //默认第一个选项
}
//排序按钮消息函数
void CEx_StudentDlg::OnButtonSort()
{
// TODO: Add your control notification handler code here
int nSel = m_ComboBoxSort.GetCurSel();
SortStudent(nSel);
}
bool sort_id(Student a, Student b) {
//学号(ID)大小比较函数
return _ttoi((CString)a.strID) < _ttoi((CString)b.strID); //将char转换成CString,在转化成int
}
bool sort_total(Student a, Student b) {
//总分大小比较函数
return atof((CString)a.fTotal) > atof((CString)b.fTotal); //将char转换成CString,在转化成float
}
bool sort_ave(Student a, Student b) {
//平均大小比较函数
return atof((CString)a.fAve) > atof((CString)b.fAve);
}
bool sort_chinese(Student a, Student b) {
//语文大小比较函数
return atof((CString)a.fChinese) > atof((CString)b.fChinese);
}
bool sort_math(Student a, Student b) {
//数学大小比较函数
return atof((CString)a.fMath) > atof((CString)b.fMath);
}
bool sort_english(Student a, Student b) {
//英语大小比较函数
return atof((CString)a.fEnglish) > atof((CString)b.fEnglish);
}
bool sort_pyhsics(Student a, Student b) {
//物理大小比较函数
return atof((CString)a.fPhysics) > atof((CString)b.fPhysics);
}
bool sort_chemistry(Student a, Student b) {
//化学大小比较函数
return atof((CString)a.fChemistry) > atof((CString)b.fChemistry);
}
bool sort_biology(Student a, Student b) {
//生物大小比较函数
return atof((CString)a.fBiology) > atof((CString)b.fBiology);
}
bool sort_history(Student a, Student b) {
//历史大小比较函数
return atof((CString)a.fHistory) > atof((CString)b.fHistory);
}
bool sort_sport(Student a, Student b) {
//体育大小比较函数
return atof((CString)a.fSport) > atof((CString)b.fSport);
}
//对应排序对学生信息进行排序
void CEx_StudentDlg::SortStudent(int nNum)
{
Student SomeStudent[1000];
CFile file;
if (!file.Open("./studentfile.dat", CFile::modeRead))
{
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
int i=0;
while (file.Read(&SomeStudent[i], sizeof(SomeStudent[i])) == sizeof(SomeStudent[i]))
{
i++;
}
file.Close();
int b = (CString)SomeStudent[0].strID < (CString)SomeStudent[1].strID;
if(nNum == 0) //0 是按学号排序
std::sort(SomeStudent, SomeStudent+i, sort_id);
if(nNum == 1) //1 是按总分成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_total);
if(nNum == 2) //2 是按平均分成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_ave);
if(nNum == 3) //3 是按语文成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_chinese);
if(nNum == 4) //4 是按数学成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_math);
if(nNum == 5) //5 是按英语成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_english);
if(nNum == 6) //6 是按物理成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_pyhsics);
if(nNum == 7) //7 是按化学成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_chemistry);
if(nNum == 8) //8 是按生物成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_biology);
if(nNum == 9) //9 是按历史成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_history);
if(nNum == 10) //10 是按体育成绩排序
std::sort(SomeStudent, SomeStudent+i, sort_sport);
if (!file.Open("./studentfile.dat", CFile::modeWrite))
{
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
int t = 0;
while(t<i) {
//将排好序的信息写入学生成绩存储文件
file.Write(&SomeStudent[t], sizeof(SomeStudent[t]));
t++;
}
file.Close();
CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
CEx_StudentDlg::ReadStudent(pList); //更新CListCtrl里的数据
}
//修改按钮控件函数
void CEx_StudentDlg::OnButtonEdit()
{
// TODO: Add your control notification handler code here
POSITION pos = m_list.GetFirstSelectedItemPosition(); //找到当前选中行
if(pos == NULL) {
MessageBox(_T("请选择要修改的数据!"), _T("警告"), MB_OK | MB_ICONWARNING);
return;
}
//将所选择的数据存入临时变量temp里
CString str;
int nItem = m_list.GetNextSelectedItem(pos);
m_list.GetItemText(nItem, 0, theApp.temp.strID, sizeof(theApp.temp.strID));
m_list.GetItemText(nItem, 1, theApp.temp.strName, sizeof(theApp.temp.strName));
m_list.GetItemText(nItem, 2, theApp.temp.sClass, sizeof(theApp.temp.sClass));
m_list.GetItemText(nItem, 3, theApp.temp.fChinese, sizeof(theApp.temp.fChinese));
m_list.GetItemText(nItem, 4, theApp.temp.fMath, sizeof(theApp.temp.fMath));
m_list.GetItemText(nItem, 5, theApp.temp.fEnglish, sizeof(theApp.temp.fEnglish));
m_list.GetItemText(nItem, 6, theApp.temp.fPhysics, sizeof(theApp.temp.fPhysics));
m_list.GetItemText(nItem, 7, theApp.temp.fChemistry, sizeof(theApp.temp.fChemistry));
m_list.GetItemText(nItem, 8, theApp.temp.fBiology, sizeof(theApp.temp.fBiology));
m_list.GetItemText(nItem, 9, theApp.temp.fHistory, sizeof(theApp.temp.fHistory));
m_list.GetItemText(nItem, 10, theApp.temp.fSport, sizeof(theApp.temp.fSport));
//测试
//str.Format("%s", theApp.temp.strName);
//AfxMessageBox(str);
CStuModifyDlg dlg;
if(IDOK == dlg.DoModal()) {
CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
CEx_StudentDlg::ReadStudent(pList);
CEx_StudentDlg::ComboBoxAddString();
CEx_StudentDlg::OnButtonSort(); //默认按学号排序
}
}
//统计按钮控件函数
void CEx_StudentDlg::OnButtonAnalysis()
{
// TODO: Add your control notification handler code here
//路径要修改,修改为自己Ex_DrawStu所在的当前路径
ShellExecute(this->m_hWnd, "open", "C:\\Users\\Administrator\\Desktop\\Ex_DrawStu\\Debug\\Ex_DrawStu.exe", NULL, NULL, SW_SHOWNORMAL);
}
//班级筛选按钮
void CEx_StudentDlg::OnButtonScreen()
{
// TODO: Add your control notification handler code here
CString className;
int nIndex = m_ComboBoxClass.GetCurSel();
m_ComboBoxClass.GetLBText(nIndex, className); //获取筛选的班别
CFile file;
if (!file.Open("./studentfile.dat", CFile::modeRead | CFile::modeCreate | CFile::modeNoTruncate))
{
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
m_list.DeleteAllItems();
Student u;
int i = 0;
while(file.Read(&u, sizeof(u)) == sizeof(u)) {
if(className == (CString)u.sClass) {
m_list.InsertItem(i, u.strID);
m_list.SetItemText(i, 1, u.strName);
m_list.SetItemText(i, 2, u.sClass);
m_list.SetItemText(i, 3, u.fChinese);
m_list.SetItemText(i, 4, u.fMath);
m_list.SetItemText(i, 5, u.fEnglish);
m_list.SetItemText(i, 6, u.fPhysics);
m_list.SetItemText(i, 7, u.fChemistry);
m_list.SetItemText(i, 8, u.fBiology);
m_list.SetItemText(i, 9, u.fHistory);
m_list.SetItemText(i, 10, u.fSport);
m_list.SetItemText(i, 11, u.fTotal);
m_list.SetItemText(i, 12, u.fAve);
i++;
}
}
file.Close();
}
(三)添加记录子对话框源代码
// StuAddDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Ex_Student.h"
#include "StuAddDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CStuAddDlg dialog
CStuAddDlg::CStuAddDlg(CWnd* pParent /*=NULL*/)
: CDialog(CStuAddDlg::IDD, pParent)
{
//{
{AFX_DATA_INIT(CStuAddDlg)
m_strName = _T("");
m_strNo = _T("");
m_fScore1 = 0.0f;
m_fScore2 = 0.0f;
m_fScore3 = 0.0f;
m_fScore4 = 0.0f;
m_strAddress = _T("");
m_sAge = _T("");
m_DateTime = 0;
m_fScore5 = 0.0f;
m_fScore6 = 0.0f;
m_fScore7 = 0.0f;
m_fScore8 = 0.0f;
//}}AFX_DATA_INIT
}
void CStuAddDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{
{AFX_DATA_MAP(CStuAddDlg)
DDX_Control(pDX, IDC_SPIN_S8, m_spinScore8);
DDX_Control(pDX, IDC_SPIN_S7, m_spinScore7);
DDX_Control(pDX, IDC_SPIN_S6, m_spinScore6);
DDX_Control(pDX, IDC_SPIN_S5, m_spinScore5);
DDX_Control(pDX, IDC_COMBO_CLASS, m_ComboBoxClass);
DDX_Control(pDX, IDC_SPIN_S4, m_spinScore4);
DDX_Control(pDX, IDC_SPIN_S3, m_spinScore3);
DDX_Control(pDX, IDC_SPIN_S2, m_spinScore2);
DDX_Control(pDX, IDC_SPIN_S1, m_spinScore1);
DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
DDV_MaxChars(pDX, m_strName, 20);
DDX_Text(pDX, IDC_EDIT_NO, m_strNo);
DDV_MaxChars(pDX, m_strNo, 20);
DDX_Text(pDX, IDC_EDIT_S1, m_fScore1);
DDV_MinMaxFloat(pDX, m_fScore1, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S2, m_fScore2);
DDV_MinMaxFloat(pDX, m_fScore2, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S3, m_fScore3);
DDV_MinMaxFloat(pDX, m_fScore3, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S4, m_fScore4);
DDV_MinMaxFloat(pDX, m_fScore4, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_ADDRESS, m_strAddress);
DDV_MaxChars(pDX, m_strAddress, 100);
DDX_Text(pDX, IDC_EDIT_AGE, m_sAge);
DDV_MaxChars(pDX, m_sAge, 5);
DDX_DateTimeCtrl(pDX, IDC_DATETIMEPICKER, m_DateTime);
DDX_Text(pDX, IDC_EDIT_S5, m_fScore5);
DDV_MinMaxFloat(pDX, m_fScore5, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S6, m_fScore6);
DDV_MinMaxFloat(pDX, m_fScore6, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S7, m_fScore7);
DDV_MinMaxFloat(pDX, m_fScore7, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S8, m_fScore8);
DDV_MinMaxFloat(pDX, m_fScore8, 0.f, 100.f);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CStuAddDlg, CDialog)
//{
{AFX_MSG_MAP(CStuAddDlg)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S1, OnDeltaposSpinS1)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S2, OnDeltaposSpinS2)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S3, OnDeltaposSpinS3)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S4, OnDeltaposSpinS4)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S5, OnDeltaposSpinS5)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S6, OnDeltaposSpinS6)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S7, OnDeltaposSpinS7)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S8, OnDeltaposSpinS8)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CStuAddDlg message handlers
BOOL CStuAddDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
m_spinScore1.SetRange(0,100);
m_spinScore2.SetRange(0,100);
m_spinScore3.SetRange(0,100);
m_spinScore4.SetRange(0,100);
m_spinScore5.SetRange(0,100);
m_spinScore6.SetRange(0,100);
m_spinScore7.SetRange(0,100);
m_spinScore8.SetRange(0,100);
CheckRadioButton(IDC_MAN, IDC_GIRL, IDC_MAN); //设置默认选中性别为男
m_ComboBoxClass.SetCurSel(0); //设置默认班级为第一个选项
m_DateTime = CTime::GetCurrentTime();
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
//旋转按钮控件12345678的通知消息函数
void CStuAddDlg::OnDeltaposSpinS1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore1 = SetSpinScore(m_fScore1, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuAddDlg::OnDeltaposSpinS2(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore2 = SetSpinScore(m_fScore2, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuAddDlg::OnDeltaposSpinS3(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore3 = SetSpinScore(m_fScore3, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuAddDlg::OnDeltaposSpinS4(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore4 = SetSpinScore(m_fScore4, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuAddDlg::OnDeltaposSpinS5(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore5 = SetSpinScore(m_fScore5, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuAddDlg::OnDeltaposSpinS6(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore6 = SetSpinScore(m_fScore6, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuAddDlg::OnDeltaposSpinS7(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore7 = SetSpinScore(m_fScore7, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuAddDlg::OnDeltaposSpinS8(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore8 = SetSpinScore(m_fScore8, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
//设置旋转控件与编辑框内容增量减量绑定函数
float CStuAddDlg::SetSpinScore(float f, NM_UPDOWN *p)
{
f += (float)p->iDelta * 0.5f;
if(f<0.0)
f = 0.0f;
if(f>100.0)
f = 100.0f;
return f;
}
//添加保存控件函数
void CStuAddDlg::OnOK()
{
// TODO: Add extra validation here
if(!IsValidate()) return;
Student u;
CString strSex, str;
//获取日期
CTime time;
CDateTimeCtrl* pCtrl = (CDateTimeCtrl*)GetDlgItem(IDC_DATETIMEPICKER);
ASSERT(pCtrl != NULL);
DWORD dwResult = pCtrl->GetTime(time);
if (dwResult == GDT_VALID)
{
str = time.Format(TEXT("%Y-%m-%d")); // 年月日
}
//获取控件输入的学生信息
GetDlgItemText(IDC_EDIT_NAME, u.strName, sizeof(u.strName));
GetDlgItemText(IDC_EDIT_NO, u.strID, sizeof(u.strID));
GetDlgItemText(IDC_EDIT_AGE, u.sAge, sizeof(u.sAge));
GetDlgItemText(IDC_EDIT_ADDRESS, u.sAddress, sizeof(u.sAddress));
GetDlgItemText(IDC_COMBO_CLASS, u.sClass, sizeof(u.sClass));
GetDlgItemText(IDC_EDIT_S1, u.fChinese, sizeof(u.fChinese));
GetDlgItemText(IDC_EDIT_S2, u.fMath, sizeof(u.fMath));
GetDlgItemText(IDC_EDIT_S3, u.fEnglish, sizeof(u.fEnglish));
GetDlgItemText(IDC_EDIT_S4, u.fSport, sizeof(u.fSport));
GetDlgItemText(IDC_EDIT_S5, u.fPhysics, sizeof(u.fPhysics));
GetDlgItemText(IDC_EDIT_S6, u.fChemistry, sizeof(u.fChemistry));
GetDlgItemText(IDC_EDIT_S7, u.fBiology, sizeof(u.fBiology));
GetDlgItemText(IDC_EDIT_S8, u.fHistory, sizeof(u.fHistory));
//获取性别
UINT nID = GetCheckedRadioButton(IDC_MAN, IDC_GIRL);
GetDlgItemText(nID, u.sSex, sizeof(u.sSex));
//获取的日期赋给u,再存入文件,使用memcpy()会出现尾部乱码
strncpy(u.sBirthday, (LPCTSTR)str, sizeof(u.sBirthday));
//str.Format(u.sClass);
//AfxMessageBox(str);
//求总分、平均分,atof()char类型转换为double
double total = atof(u.fChinese) + atof(u.fMath) + atof(u.fEnglish) + atof(u.fSport)
+atof(u.fPhysics) + atof(u.fChemistry) + atof(u.fBiology) + atof(u.fHistory);
double ave = total/8.0;
//sprintf()double转换为char类型
sprintf(u.fTotal,"%.2lf",total);
sprintf(u.fAve,"%.2lf",ave);
CFile file;
if (!file.Open("./studentfile.dat", CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate)) {
AfxMessageBox("添加失败,文件打不开!");
return;
}
Student ur;
while (file.Read(&ur, sizeof(ur))) {
//读取学生文件信息,看学号是否重复
if((CString)ur.strID == (CString)u.strID) {
AfxMessageBox("用户已存在!");
return;
}
}
file.SeekToEnd(); //将指针移到文件末尾
file.Write(&u, sizeof(u));
AfxMessageBox("添加保存成功!"); //提示保存成功
CDialog::OnOK();
}
//验证添加编辑框是否有输入
BOOL CStuAddDlg::IsValidate()
{
UpdateData();
m_strName.TrimLeft();
m_strNo.TrimLeft();
m_strAddress.TrimLeft();
m_sAge.TrimLeft();
if(m_strName.IsEmpty()) {
MessageBox("请输入姓名");
return FALSE;
} else if(m_strNo.IsEmpty()) {
MessageBox("请输入学号");
return FALSE;
} else if(m_strAddress.IsEmpty()) {
MessageBox("请输入地址");
return FALSE;
} else if(m_sAge.IsEmpty()) {
MessageBox("请输入年龄");
return FALSE;
}
return TRUE;
}
(四)修改记录子对话框源代码
变量同添加子对话框相同,spinScore变量名稍有点不同,原理同样。
// StuModifyDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Ex_Student.h"
#include "StuModifyDlg.h"
extern CEx_StudentApp theApp;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CStuModifyDlg dialog
CStuModifyDlg::CStuModifyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CStuModifyDlg::IDD, pParent)
{
//{
{AFX_DATA_INIT(CStuModifyDlg)
m_strAddress = _T("");
m_strName = _T("");
m_sAge = _T("");
m_strNo = _T("");
m_fScore1 = 0.0f;
m_fScore2 = 0.0f;
m_fScore3 = 0.0f;
m_fScore4 = 0.0f;
m_DateTime = 0;
m_fScore6 = 0.0f;
m_fScore7 = 0.0f;
m_fScore8 = 0.0f;
m_fScore9 = 0.0f;
//}}AFX_DATA_INIT
}
void CStuModifyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{
{AFX_DATA_MAP(CStuModifyDlg)
DDX_Control(pDX, IDC_SPIN_S6, m_spinScore6);
DDX_Control(pDX, IDC_SPIN_S7, m_spinScore7);
DDX_Control(pDX, IDC_SPIN_S8, m_spinScore8);
DDX_Control(pDX, IDC_SPIN_S9, m_spinScore9);
DDX_Control(pDX, IDC_SPIN_S4, m_spinScore4);
DDX_Control(pDX, IDC_SPIN_S3, m_spinScore3);
DDX_Control(pDX, IDC_SPIN_S2, m_spinScore2);
DDX_Control(pDX, IDC_SPIN_S1, m_spinScore1);
DDX_Text(pDX, IDC_EDIT_ADDRESS, m_strAddress);
DDV_MaxChars(pDX, m_strAddress, 100);
DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
DDV_MaxChars(pDX, m_strName, 20);
DDX_Text(pDX, IDC_EDIT_AGE, m_sAge);
DDV_MaxChars(pDX, m_sAge, 5);
DDX_Text(pDX, IDC_EDIT_NO, m_strNo);
DDV_MaxChars(pDX, m_strNo, 20);
DDX_Text(pDX, IDC_EDIT_S1, m_fScore1);
DDV_MinMaxFloat(pDX, m_fScore1, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S2, m_fScore2);
DDV_MinMaxFloat(pDX, m_fScore2, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S3, m_fScore3);
DDV_MinMaxFloat(pDX, m_fScore3, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S4, m_fScore4);
DDV_MinMaxFloat(pDX, m_fScore4, 0.f, 100.f);
DDX_DateTimeCtrl(pDX, IDC_DATETIMEPICKER, m_DateTime);
DDX_Text(pDX, IDC_EDIT_S6, m_fScore6);
DDV_MinMaxFloat(pDX, m_fScore6, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S7, m_fScore7);
DDV_MinMaxFloat(pDX, m_fScore7, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S8, m_fScore8);
DDV_MinMaxFloat(pDX, m_fScore8, 0.f, 100.f);
DDX_Text(pDX, IDC_EDIT_S9, m_fScore9);
DDV_MinMaxFloat(pDX, m_fScore9, 0.f, 100.f);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CStuModifyDlg, CDialog)
//{
{AFX_MSG_MAP(CStuModifyDlg)
ON_BN_CLICKED(IDOK_CHANGESAVE, OnChangeSave)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S1, OnDeltaposSpinS1)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S2, OnDeltaposSpinS2)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S3, OnDeltaposSpinS3)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S4, OnDeltaposSpinS4)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S6, OnDeltaposSpinS6)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S7, OnDeltaposSpinS7)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S8, OnDeltaposSpinS8)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_S9, OnDeltaposSpinS9)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CStuModifyDlg message handlers
BOOL CStuModifyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
m_spinScore1.SetRange(0,100);
m_spinScore2.SetRange(0,100);
m_spinScore3.SetRange(0,100);
m_spinScore4.SetRange(0,100);
m_spinScore6.SetRange(0,100);
m_spinScore7.SetRange(0,100);
m_spinScore8.SetRange(0,100);
m_spinScore9.SetRange(0,100);
//设置默认选中性别为男
CheckRadioButton(IDC_MAN, IDC_GIRL, IDC_MAN);
CFile file;
if (!file.Open("./studentfile.dat", CFile::modeRead)) {
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return 0;
}
Student u;
while (file.Read(&u, sizeof(u))) {
//读取学生文件信息,读取该学生的其他个人信息
if((CString)u.strID == (CString)theApp.temp.strID) {
memcpy(theApp.temp.sAddress, u.sAddress, strlen(u.sAddress));
memcpy(theApp.temp.sAge, u.sAge, strlen(u.sAge));
memcpy(theApp.temp.sBirthday, u.sBirthday, strlen(u.sBirthday));
memcpy(theApp.temp.sSex, u.sSex, strlen(u.sSex));
//CString str;
//str.Format(theApp.temp.sBirthday);
//MessageBox(str);
break;
}
}
//初始化对话框时显示所选中的学生信息
SetDlgItemText(IDC_EDIT_NO, theApp.temp.strID);
SetDlgItemText(IDC_EDIT_NAME, theApp.temp.strName);
SetDlgItemText(IDC_EDIT_AGE, theApp.temp.sAge);
SetDlgItemText(IDC_EDIT_ADDRESS, theApp.temp.sAddress);
SetDlgItemText(IDC_COMBO_CLASS, theApp.temp.sClass);
SetDlgItemText(IDC_EDIT_S1, theApp.temp.fChinese);
SetDlgItemText(IDC_EDIT_S2, theApp.temp.fMath);
SetDlgItemText(IDC_EDIT_S3, theApp.temp.fEnglish);
SetDlgItemText(IDC_EDIT_S4, theApp.temp.fSport);
SetDlgItemText(IDC_EDIT_S6, theApp.temp.fPhysics);
SetDlgItemText(IDC_EDIT_S7, theApp.temp.fChemistry);
SetDlgItemText(IDC_EDIT_S8, theApp.temp.fBiology);
SetDlgItemText(IDC_EDIT_S9, theApp.temp.fHistory);
//CString日期转为CTime日期,并映射到日历控件
CString s = (CString)theApp.temp.sBirthday;
int y, m, d;
sscanf(s, "%d-%d-%d", &y, &m, &d);
CDateTimeCtrl* pCtrl = (CDateTimeCtrl*)GetDlgItem(IDC_DATETIMEPICKER);
CTime t(y,m,d,0,0,0);
pCtrl->SetTime(&t);
if((CString)theApp.temp.sSex == "男")
CheckRadioButton(IDC_MAN, IDC_GIRL, IDC_MAN);
else
CheckRadioButton(IDC_MAN, IDC_GIRL, IDC_GIRL);
GetDlgItem(IDC_EDIT_NO)->EnableWindow(FALSE); //设置学号框只读
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
//修改保存控件函数
void CStuModifyDlg::OnChangeSave()
{
// TODO: Add your control notification handler code here
Student u;
CString strSex, str;
//验证
if(!IsValidate()) return;
//获取日期
CTime time;
CDateTimeCtrl* pCtrl = (CDateTimeCtrl*)GetDlgItem(IDC_DATETIMEPICKER);
ASSERT(pCtrl != NULL);
DWORD dwResult = pCtrl->GetTime(time);
if (dwResult == GDT_VALID)
str = time.Format(TEXT("%Y-%m-%d")); // 年月日
GetDlgItemText(IDC_EDIT_NAME, u.strName, sizeof(u.strName));
GetDlgItemText(IDC_EDIT_NO, u.strID, sizeof(u.strID));
GetDlgItemText(IDC_EDIT_AGE, u.sAge, sizeof(u.sAge));
GetDlgItemText(IDC_EDIT_ADDRESS, u.sAddress, sizeof(u.sAddress));
GetDlgItemText(IDC_COMBO_CLASS, u.sClass, sizeof(u.sClass));
GetDlgItemText(IDC_EDIT_S1, u.fChinese, sizeof(u.fChinese));
GetDlgItemText(IDC_EDIT_S2, u.fMath, sizeof(u.fMath));
GetDlgItemText(IDC_EDIT_S3, u.fEnglish, sizeof(u.fEnglish));
GetDlgItemText(IDC_EDIT_S4, u.fSport, sizeof(u.fSport));
GetDlgItemText(IDC_EDIT_S6, u.fPhysics, sizeof(u.fPhysics));
GetDlgItemText(IDC_EDIT_S7, u.fChemistry, sizeof(u.fChemistry));
GetDlgItemText(IDC_EDIT_S8, u.fBiology, sizeof(u.fBiology));
GetDlgItemText(IDC_EDIT_S9, u.fHistory, sizeof(u.fHistory));
UINT nID = GetCheckedRadioButton(IDC_MAN, IDC_GIRL);
GetDlgItemText(nID, u.sSex, sizeof(u.sSex));
//获取的日期赋给u,再存入文件,使用memcpy()会出现尾部乱码
strncpy(u.sBirthday, (LPCTSTR)str, sizeof(u.sBirthday));
//求总分、平均分,atof()char类型转换为double
double total = atof(u.fChinese) + atof(u.fMath) + atof(u.fEnglish) + atof(u.fSport)
+atof(u.fPhysics) + atof(u.fChemistry) + atof(u.fBiology) + atof(u.fHistory);
double ave = total/8.0;
//sprintf()double转换为char类型
sprintf(u.fTotal,"%.2lf",total);
sprintf(u.fAve,"%.2lf",ave);
//str.Format("%s + %s", u.fTotal, u.fAve);
//AfxMessageBox(str);
CFile file;
if((CString)u.strID != (CString)theApp.temp.strID) {
AfxMessageBox("请输入同一学号!");
SetDlgItemText(IDC_EDIT_NO, theApp.temp.strID);
}
if (!file.Open("./studentfile.dat", CFile::modeRead)) {
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
int i=0;
Student ur;
while(file.Read(&ur, sizeof(ur))) {
//读取学生成绩储存文件,找到该学生信息储存的对应位置
if((CString)theApp.temp.strID == (CString)ur.strID) {
break;
}
i++;
}
file.Close();
if (!file.Open("./studentfile.dat", CFile::modeWrite)) {
MessageBox(_T("无法打开文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return;
}
file.SeekToBegin();
file.Seek(i*sizeof(u), CFile::current); // 重新设置file文件的写指针时期刚好在要修改的学生信息那里
file.Write(&u, sizeof(u));
//str.Format("%s, %s", u.strID, u.strName);
//AfxMessageBox(str);
AfxMessageBox("修改保存成功!"); //提示保存成功
file.Close();
CDialog::OnOK();
}
void CStuModifyDlg::OnDeltaposSpinS1(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore1 = SetSpinScore(m_fScore1, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuModifyDlg::OnDeltaposSpinS2(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore2 = SetSpinScore(m_fScore2, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuModifyDlg::OnDeltaposSpinS3(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore3 = SetSpinScore(m_fScore3, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuModifyDlg::OnDeltaposSpinS4(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore4 = SetSpinScore(m_fScore4, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuModifyDlg::OnDeltaposSpinS6(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore6 = SetSpinScore(m_fScore6, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuModifyDlg::OnDeltaposSpinS7(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore7 = SetSpinScore(m_fScore7, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuModifyDlg::OnDeltaposSpinS8(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore8 = SetSpinScore(m_fScore8, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
void CStuModifyDlg::OnDeltaposSpinS9(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_fScore9 = SetSpinScore(m_fScore9, pNMUpDown);
UpdateData(FALSE);
*pResult = 0;
}
//设置旋转控件与编辑框内容增量减量绑定函数
float CStuModifyDlg::SetSpinScore(float f, NM_UPDOWN *p)
{
f += (float)p->iDelta * 0.5f;
if(f<0.0)
f = 0.0f;
if(f>100.0)
f = 100.0f;
return f;
}
//验证添加编辑框是否有输入
BOOL CStuModifyDlg::IsValidate()
{
UpdateData();
m_strName.TrimLeft();
m_strNo.TrimLeft();
m_strAddress.TrimLeft();
m_sAge.TrimLeft();
if(m_strName.IsEmpty()) {
MessageBox("请输入姓名");
return FALSE;
} else if(m_strNo.IsEmpty()) {
MessageBox("请输入学号");
return FALSE;
} else if(m_strAddress.IsEmpty()) {
MessageBox("请输入地址");
return FALSE;
} else if(m_sAge.IsEmpty()) {
MessageBox("请输入年龄");
return FALSE;
}
return TRUE;
}
(五)登录子对话框源代码
设置程序启动先调用Login子对话框
// Ex_Student.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "Ex_Student.h"
#include "Ex_StudentDlg.h"
#include "LoginDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CEx_StudentApp
BEGIN_MESSAGE_MAP(CEx_StudentApp, CWinApp)
//{
{AFX_MSG_MAP(CEx_StudentApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/
// CEx_StudentApp construction
CEx_StudentApp::CEx_StudentApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/
// The one and only CEx_StudentApp object
CEx_StudentApp theApp;
/
// CEx_StudentApp initialization
BOOL CEx_StudentApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
//调用登录对话框
CLoginDlg dlg;
if (IDCANCEL == dlg.DoModal())
return FALSE;
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
// LoginDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Ex_Student.h"
#include "LoginDlg.h"
#include "Ex_StudentDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CLoginDlg dialog
CLoginDlg::CLoginDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLoginDlg::IDD, pParent)
{
//{
{AFX_DATA_INIT(CLoginDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CLoginDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{
{AFX_DATA_MAP(CLoginDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLoginDlg, CDialog)
//{
{AFX_MSG_MAP(CLoginDlg)
ON_BN_CLICKED(IDOK, OnBtnClickedOK)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CLoginDlg message handlers
//登陆按钮控件函数
void CLoginDlg::OnBtnClickedOK()
{
// TODO: Add your control notification handler code here
CString sid, spw;
GetDlgItemText(IDC_EDIT_USER, sid);
GetDlgItemText(IDC_EDIT_PASSWD, spw);
if(sid == "admin" && spw == "123") {
CEx_StudentDlg dlg;
if (dlg.DoModal() == IDOK)
{
// TODO: Place code here to handle when the dialog is
}
CDialog::OnOK();
}
else {
AfxMessageBox("用户名或密码错误\n管理员: admin\n密码: 123"); //密码错误则弹出窗口提示错误
SetDlgItemText(IDC_EDIT_USER, ""); //重置两个编辑框
SetDlgItemText(IDC_EDIT_PASSWD, "");
this->SetFocus();
}
}
(六)图像绘制主框架源代码
// Ex_DrawStuView.h : interface of the CEx_DrawStuView class
//
/
#if !defined(AFX_EX_DRAWSTUVIEW_H__B14A5A68_E484_4D94_A204_82FF380CA2C5__INCLUDED_)
#define AFX_EX_DRAWSTUVIEW_H__B14A5A68_E484_4D94_A204_82FF380CA2C5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CEx_DrawStuView : public CView
{
protected: // create from serialization only
CEx_DrawStuView();
DECLARE_DYNCREATE(CEx_DrawStuView)
// Attributes
public:
CEx_DrawStuDoc* GetDocument();
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{
{AFX_VIRTUAL(CEx_DrawStuView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
//}}AFX_VIRTUAL
// Implementation
public:
void ButtonEnable();
void ButtonUnenable();
void OnButtonChemistryLineShow();
void OnButtonBiologyLineShow();
void OnButtonHistoryLineShow();
void OnButtonPhysicsLineShow();
void OnButtonBiologyShow();
void OnButtonChemistryShow();
void OnButtonHistoryShow();
void OnButtonPhysicsShow();
void OnButtonOpenFile();
void OnButtonSportLineShow();
void OnButtonEnglishLineShow();
void OnButtonMathLineShow();
void OnButtonChineseLineShow();
void OnButtonSportShow();
void OnButtonEnglishShow();
void OnButtonMathShow();
float m_Num[100];
CString GetFileName();
void OnButtonChineseShow();
//定义按钮
CButton m_btnChinese;
CButton m_btnMath;
CButton m_btnEnglish;
CButton m_btnPhysics;
CButton m_btnBiology;
CButton m_btnHistory;
CButton m_btnChemistry;
CButton m_btnSport;
CButton m_btnChineseLine;
CButton m_btnMathLine;
CButton m_btnEnglishLine;
CButton m_btnPhysicsLine;
CButton m_btnBiologyLine;
CButton m_btnHistoryLine;
CButton m_btnChemistryLine;
CButton m_btnSportLine;
CButton m_buttonOpenFile;
int OnCreate(LPCREATESTRUCT lpCreateStruct);
void DrawScore(CDC* pDC, float * fScore, int nNum, CString title);
void DrawLine(CDC* pDC, float* fScore, int nNum, CString title);
virtual ~CEx_DrawStuView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{
{AFX_MSG(CEx_DrawStuView)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in Ex_DrawStuView.cpp
inline CEx_DrawStuDoc* CEx_DrawStuView::GetDocument()
{
return (CEx_DrawStuDoc*)m_pDocument; }
#endif
/
//{
{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EX_DRAWSTUVIEW_H__B14A5A68_E484_4D94_A204_82FF380CA2C5__INCLUDED_)
源文件cpp
// Ex_DrawStuView.cpp : implementation of the CEx_DrawStuView class
//
#include "stdafx.h"
#include "Ex_DrawStu.h"
#include "Ex_DrawStuDoc.h"
#include "Ex_DrawStuView.h"
extern CEx_DrawStuApp theApp;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CEx_DrawStuView
IMPLEMENT_DYNCREATE(CEx_DrawStuView, CView)
BEGIN_MESSAGE_MAP(CEx_DrawStuView, CView)
//{
{AFX_MSG_MAP(CEx_DrawStuView)
ON_WM_CREATE()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
ON_COMMAND(IDC_HIGGER_CHINESE, OnButtonChineseShow)
ON_COMMAND(IDC_HIGGER_MATH, OnButtonMathShow)
ON_COMMAND(IDC_HIGGER_ENGLISH, OnButtonEnglishShow)
ON_COMMAND(IDC_HIGGER_PHYSICS, OnButtonPhysicsShow)
ON_COMMAND(IDC_HIGGER_HISTORY, OnButtonHistoryShow)
ON_COMMAND(IDC_HIGGER_CHEMISTRY, OnButtonChemistryShow)
ON_COMMAND(IDC_HIGGER_BIOLOGY, OnButtonBiologyShow)
ON_COMMAND(IDC_HIGGER_SPORT, OnButtonSportShow)
ON_COMMAND(IDC_HIGGER_CHINESE_LINE, OnButtonChineseLineShow)
ON_COMMAND(IDC_HIGGER_MATH_LINE, OnButtonMathLineShow)
ON_COMMAND(IDC_HIGGER_ENGLISH_LINE, OnButtonEnglishLineShow)
ON_COMMAND(IDC_HIGGER_SPORT_LINE, OnButtonSportLineShow)
ON_COMMAND(IDC_HIGGER_PHYSICS_LINE, OnButtonPhysicsLineShow)
ON_COMMAND(IDC_HIGGER_HISTORY_LINE, OnButtonHistoryLineShow)
ON_COMMAND(IDC_HIGGER_BIOLOGY_LINE, OnButtonBiologyLineShow)
ON_COMMAND(IDC_HIGGER_CHEMISTRY_LINE, OnButtonChemistryLineShow)
ON_COMMAND(IDC_BUTOON_OPENFILE, OnButtonOpenFile)
END_MESSAGE_MAP()
/
// CEx_DrawStuView construction/destruction
CEx_DrawStuView::CEx_DrawStuView()
{
// TODO: add construction code here
}
CEx_DrawStuView::~CEx_DrawStuView()
{
}
BOOL CEx_DrawStuView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/
// CEx_DrawStuView drawing
void CEx_DrawStuView::OnDraw(CDC* pDC)
{
CEx_DrawStuDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/
// CEx_DrawStuView printing
BOOL CEx_DrawStuView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CEx_DrawStuView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CEx_DrawStuView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/
// CEx_DrawStuView diagnostics
#ifdef _DEBUG
void CEx_DrawStuView::AssertValid() const
{
CView::AssertValid();
}
void CEx_DrawStuView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CEx_DrawStuDoc* CEx_DrawStuView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEx_DrawStuDoc)));
return (CEx_DrawStuDoc*)m_pDocument;
}
#endif //_DEBUG
/
// CEx_DrawStuView message handlers
//画直方图函数
void CEx_DrawStuView::DrawScore(CDC *pDC, float *fScore, int nNum, CString title)
{
int i;
int nScoreNum[] = {
0, 0, 0, 0, 0}; // 各成绩段的人数的初始值
// 下面是用来统计各分数段的人数
for(i=0; i<nNum; i++) {
int nSeg = (int)(fScore[i])/10;
if (nSeg < 6) nSeg = 5; // <60分
if (nSeg == 10) nSeg = 9; // 当为100分,算为>90分数段
nScoreNum[nSeg - 5] ++; // 各分数段计数
}
int nSegNum = sizeof(nScoreNum)/sizeof(int); //计算有多少个分数段
//求分数段上的最大的人数
int nNumMax = nScoreNum[0];
for(i=1; i<nSegNum; i++) {
if(nNumMax < nScoreNum[i])
nNumMax = nScoreNum[i];
}
CRect rc;
GetClientRect(rc);
rc.DeflateRect(180, 40); //缩小矩形大小
int nSegWidth = rc.Width() / nSegNum; //计算每段的宽度
int nSegHeight = rc.Height() / nNumMax; //计算每段的单位高度
COLORREF crSeg = RGB(0,0,192); //定义一个颜色变量
CBrush brush1(HS_FDIAGONAL, crSeg);
CBrush brush2(HS_FDIAGONAL, crSeg);
CPen pen(PS_INSIDEFRAME, 2, crSeg);
CBrush* oldBrush = pDC->SelectObject(&brush1); // 将brush1选入设备环境
CPen* oldPen = pDC->SelectObject(&pen); // 将pen选 入设备环境
CRect rcSeg(rc);
rcSeg.right = rcSeg.left + nSegWidth;
CString strSeg[] = {
"<60", "60-70", "70-80", "80-90", ">=90"};
CRect rcStr;
for(i=0; i<nSegNum; i++) {
// 保证相邻的矩形填充样式不相同
if(i%2)
pDC->SelectObject(&brush2);
else
pDC->SelectObject(&brush1);
rcSeg.top = rcSeg.bottom - nScoreNum[i]*nSegHeight - 2;
pDC->Rectangle(rcSeg);
if(nScoreNum[i]>0) {
CString str;
str.Format("%d 人", nScoreNum[i]);
pDC->DrawText(str, rcSeg, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
rcStr = rcSeg;
rcStr.top = rcStr.bottom + 2;
rcStr.bottom += 20;
pDC->DrawText(strSeg[i], rcStr, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
rcSeg.OffsetRect(nSegWidth, 0);
}
pDC->TextOut(500, 10, title);
pDC->SelectObject(oldBrush); // 恢复原来的画刷属性
pDC->SelectObject(oldPen); // 恢复原来的画笔属性
CDC* pControlDC = pDC;
pControlDC->SelectStockObject(BLACK_BRUSH);//设置画刷
CString str;
pControlDC->MoveTo(180, 40); //画y轴
pControlDC->LineTo(180,380);
pControlDC->MoveTo(180, 380);//画x轴
pControlDC->LineTo(900, 380);
}
//画折线图
void CEx_DrawStuView::DrawLine(CDC *pDC, float *fScore, int nNum, CString title)
{
int i;
int nScoreNum[] = {
0, 0, 0, 0, 0}; // 各成绩段的人数的初始值
// 下面是用来统计各分数段的人数
for(i=0; i<nNum; i++) {
int nSeg = (int)(fScore[i])/10;
if (nSeg < 6) nSeg = 5; // <60分
if (nSeg == 10) nSeg = 9; // 当为100分,算为>90分数段
nScoreNum[nSeg - 5] ++; // 各分数段计数
}
CDC* pControlDC = pDC;
pControlDC->SelectStockObject(BLACK_BRUSH); //设置画刷
CString str;
CString strSeg[] = {
(CString)"<60", (CString)"60-70", (CString)"70-80", (CString)"80-90", (CString)">=90" };
pControlDC->MoveTo(180, 40); //画线的开始位置
pControlDC->LineTo(180, 380);
pControlDC->MoveTo(180, 380); //画线的开始位置
pControlDC->LineTo(900, 380);
pControlDC->MoveTo(180, 380);
for(i=0; i<5; i++) {
pControlDC->SetPixel(0, 290, RGB(0, 0, 255)); //设置点的位置及颜色
pControlDC->LineTo(i*140+220, 380 - (380*nScoreNum[i]/nNum)); //换两点之间的线
str.Format("%d人", nScoreNum[i]);
pControlDC->TextOut(i * 140 + 220,380 - (380 * nScoreNum[i] / nNum)-20, str); //在线的上方输出文字
pControlDC->TextOut(i * 140 + 220, 390, strSeg[i]);
}
pControlDC->TextOut(500, 10, title);
}
// 创建各个成绩显示控件函数
int CEx_DrawStuView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//下面的button控件的ID还需添加到字串表
m_buttonOpenFile.Create((CString)"打开数据文件", //按钮标题
WS_CHILD | WS_VISIBLE | WS_BORDER, //按钮风格
CRect(10, 10, 120, 40), //按钮大小
this, //按钮父指针
IDC_BUTOON_OPENFILE); //该按钮对应的ID号
m_buttonOpenFile.ShowWindow(SW_SHOWNORMAL);
m_btnChinese.Create((CString)"语文成绩(直方)", //按钮标题
WS_CHILD | WS_VISIBLE | WS_BORDER, //按钮风格
CRect(10, 50, 120, 80), //按钮大小
this, //按钮父指针
IDC_HIGGER_CHINESE); //该按钮对应的ID号
m_btnChinese.ShowWindow(SW_SHOWNORMAL);
m_btnMath.Create((CString)"数学成绩(直方)", //按钮标题
WS_CHILD | WS_VISIBLE | WS_BORDER, //按钮风格
CRect(10, 90, 120, 120), //按钮大小
this, //按钮父指针
IDC_HIGGER_MATH); //该按钮对应的ID号
m_btnMath.ShowWindow(SW_SHOWNORMAL);
m_btnEnglish.Create((CString)"英语成绩(直方)",
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(10, 130, 120, 160),
this,
IDC_HIGGER_ENGLISH);
m_btnEnglish.ShowWindow(SW_SHOWNORMAL);
m_btnPhysics.Create((CString)"物理成绩(直方)",
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(10, 170, 120, 200),
this,
IDC_HIGGER_PHYSICS);
m_btnPhysics.ShowWindow(SW_SHOWNORMAL);
m_btnChemistry.Create((CString)"化学成绩(直方)",
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(10, 210, 120, 240),
this,
IDC_HIGGER_CHEMISTRY);
m_btnChemistry.ShowWindow(SW_SHOWNORMAL);
m_btnBiology.Create((CString)"生物成绩(直方)",
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(10, 250, 120, 280),
this,
IDC_HIGGER_BIOLOGY);
m_btnBiology.ShowWindow(SW_SHOWNORMAL);
m_btnHistory.Create((CString)"历史成绩(直方)",
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(10, 290, 120, 320),
this,
IDC_HIGGER_HISTORY);
m_btnHistory.ShowWindow(SW_SHOWNORMAL);
m_btnSport.Create((CString)"体育成绩(直方)",
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(10, 330, 120, 360),
this,
IDC_HIGGER_SPORT);
m_btnSport.ShowWindow(SW_SHOWNORMAL);
m_btnChineseLine.Create((CString)"折线", //语文
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(120, 50, 170, 80),
this,
IDC_HIGGER_CHINESE_LINE);
m_btnChineseLine.ShowWindow(SW_SHOWNORMAL);
m_btnMathLine.Create((CString)"折线", //数学
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(120, 90, 170, 120),
this,
IDC_HIGGER_MATH_LINE);
m_btnMathLine.ShowWindow(SW_SHOWNORMAL);
m_btnEnglishLine.Create((CString)"折线", //英语
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(120, 130, 170, 160),
this,
IDC_HIGGER_ENGLISH_LINE);
m_btnEnglishLine.ShowWindow(SW_SHOWNORMAL);
m_btnPhysicsLine.Create((CString)"折线", //物理
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(120, 170, 170, 200),
this,
IDC_HIGGER_PHYSICS_LINE);
m_btnPhysicsLine.ShowWindow(SW_SHOWNORMAL);
m_btnChemistryLine.Create((CString)"折线", //化学
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(120, 210, 170, 240),
this,
IDC_HIGGER_CHEMISTRY_LINE);
m_btnChemistryLine.ShowWindow(SW_SHOWNORMAL);
m_btnBiologyLine.Create((CString)"折线", //生物
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(120, 250, 170, 280),
this,
IDC_HIGGER_BIOLOGY_LINE);
m_btnBiologyLine.ShowWindow(SW_SHOWNORMAL);
m_btnHistoryLine.Create((CString)"折线", //历史
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(120, 290, 170, 320),
this,
IDC_HIGGER_HISTORY_LINE);
m_btnHistoryLine.ShowWindow(SW_SHOWNORMAL);
m_btnSportLine.Create((CString)"折线", //体育
WS_CHILD | WS_VISIBLE | WS_BORDER,
CRect(120, 330, 170, 360),
this,
IDC_HIGGER_SPORT_LINE);
m_btnSportLine.ShowWindow(SW_SHOWNORMAL);
ButtonUnenable(); //按钮不可用
return 0;
}
//语文成绩直方图控件按钮对应函数
void CEx_DrawStuView::OnButtonChineseShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fChinese);
}
InvalidateRect(NULL);
UpdateWindow();
DrawScore(GetDC(), m_Num, i, "语文成绩直方图");
}
//数学成绩直方图控件按钮对应函数
void CEx_DrawStuView::OnButtonMathShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fMath);
}
InvalidateRect(NULL);
UpdateWindow();
DrawScore(GetDC(), m_Num, i, "数学成绩直方图");
}
//英语成绩直方图控件按钮对应函数
void CEx_DrawStuView::OnButtonEnglishShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fEnglish);
}
InvalidateRect(NULL);
UpdateWindow();
DrawScore(GetDC(), m_Num, i, "英语成绩直方图");
}
//体育成绩直方图控件按钮对应函数
void CEx_DrawStuView::OnButtonSportShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fSport);
}
InvalidateRect(NULL);
UpdateWindow();
DrawScore(GetDC(), m_Num, i, "体育成绩直方图");
}
//物理成绩直方图
void CEx_DrawStuView::OnButtonPhysicsShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fPhysics);
}
InvalidateRect(NULL);
UpdateWindow();
DrawScore(GetDC(), m_Num, i, "物理成绩直方图");
}
//历史成绩直方图
void CEx_DrawStuView::OnButtonHistoryShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fHistory);
}
InvalidateRect(NULL);
UpdateWindow();
DrawScore(GetDC(), m_Num, i, "历史成绩直方图");
}
//化学成绩直方图
void CEx_DrawStuView::OnButtonChemistryShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fChemistry);
}
InvalidateRect(NULL);
UpdateWindow();
DrawScore(GetDC(), m_Num, i, "化学成绩直方图");
}
//生物成绩直方图
void CEx_DrawStuView::OnButtonBiologyShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fBiology);
}
InvalidateRect(NULL);
UpdateWindow();
DrawScore(GetDC(), m_Num, i, "生物成绩直方图");
}
//语文成绩折线图控件按钮对应函数
void CEx_DrawStuView::OnButtonChineseLineShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fChinese);
}
InvalidateRect(NULL);
UpdateWindow();
DrawLine(GetDC(), m_Num, i, "语文成绩折线图");
}
//数学成绩折线图控件按钮对应函数
void CEx_DrawStuView::OnButtonMathLineShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fMath);
}
InvalidateRect(NULL);
UpdateWindow();
DrawLine(GetDC(), m_Num, i, "数学成绩折线图");
}
//英语成绩折线图控件按钮对应函数
void CEx_DrawStuView::OnButtonEnglishLineShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fEnglish);
}
InvalidateRect(NULL);
UpdateWindow();
DrawLine(GetDC(), m_Num, i, "英语成绩折线图");
}
//体育成绩折线图控件按钮对应函数
void CEx_DrawStuView::OnButtonSportLineShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fSport);
}
InvalidateRect(NULL);
UpdateWindow();
DrawLine(GetDC(), m_Num, i, "体育成绩折线图");
}
//物理折线
void CEx_DrawStuView::OnButtonPhysicsLineShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fPhysics);
}
InvalidateRect(NULL);
UpdateWindow();
DrawLine(GetDC(), m_Num, i, "物理成绩折线图");
}
//历史折线
void CEx_DrawStuView::OnButtonHistoryLineShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fHistory);
}
InvalidateRect(NULL);
UpdateWindow();
DrawLine(GetDC(), m_Num, i, "历史成绩折线图");
}
//生物折线
void CEx_DrawStuView::OnButtonBiologyLineShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fBiology);
}
InvalidateRect(NULL);
UpdateWindow();
DrawLine(GetDC(), m_Num, i, "生物成绩折线图");
}
//化学折线
void CEx_DrawStuView::OnButtonChemistryLineShow()
{
for(int i=0; i<theApp.index; i++) {
m_Num[i] = (float)atof((CString)theApp.stu[i].fChemistry);
}
InvalidateRect(NULL);
UpdateWindow();
DrawLine(GetDC(), m_Num, i, "化学成绩折线图");
}
//获取文件路径
CString CEx_DrawStuView::GetFileName()
{
CString filter, strFileName;
filter = "数据文件(*.dat)|*.dat||";
CFileDialog dlg(TRUE, ".dat", NULL, OFN_HIDEREADONLY, filter);
if(dlg.DoModal() == IDOK) {
strFileName = dlg.GetPathName(); //获取文件路径
CFileStatus status;
if(!CFile::GetStatus(strFileName, status)) {
MessageBox("文件不存在!", "错误", MB_OK | MB_ICONERROR);
}
}
return strFileName;
}
//打开文件获取数据
void CEx_DrawStuView::OnButtonOpenFile()
{
CString strFileName;
//获取文件路径
strFileName = GetFileName();
CFile file;
if(!file.Open(strFileName, CFile::modeReadWrite)) {
MessageBox("文件无法打开,无法画图!", "错误", MB_OK | MB_ICONERROR);
ButtonUnenable(); //按钮不可用
return;
}
ButtonEnable(); //按钮可用
Student u;
int i=0, j=0;
while(file.Read(&theApp.stu[i], sizeof(theApp.stu[i])) == sizeof(theApp.stu[i])) {
//m_Num[i] = (float)atof((CString)u.fChinese);
i++;
}
theApp.index = i;
file.Close();
}
//按钮不可用函数
void CEx_DrawStuView::ButtonUnenable()
{
m_btnChinese.EnableWindow(FALSE);
m_btnMath.EnableWindow(FALSE);
m_btnEnglish.EnableWindow(FALSE);
m_btnPhysics.EnableWindow(FALSE);
m_btnBiology.EnableWindow(FALSE);
m_btnHistory.EnableWindow(FALSE);
m_btnChemistry.EnableWindow(FALSE);
m_btnSport.EnableWindow(FALSE);
m_btnChineseLine.EnableWindow(FALSE);
m_btnMathLine.EnableWindow(FALSE);
m_btnEnglishLine.EnableWindow(FALSE);
m_btnPhysicsLine.EnableWindow(FALSE);
m_btnBiologyLine.EnableWindow(FALSE);
m_btnHistoryLine.EnableWindow(FALSE);
m_btnChemistryLine.EnableWindow(FALSE);
m_btnSportLine.EnableWindow(FALSE);
}
//按钮可用函数
void CEx_DrawStuView::ButtonEnable()
{
m_btnChinese.EnableWindow(TRUE);
m_btnMath.EnableWindow(TRUE);
m_btnEnglish.EnableWindow(TRUE);
m_btnPhysics.EnableWindow(TRUE);
m_btnBiology.EnableWindow(TRUE);
m_btnHistory.EnableWindow(TRUE);
m_btnChemistry.EnableWindow(TRUE);
m_btnSport.EnableWindow(TRUE);
m_btnChineseLine.EnableWindow(TRUE);
m_btnMathLine.EnableWindow(TRUE);
m_btnEnglishLine.EnableWindow(TRUE);
m_btnPhysicsLine.EnableWindow(TRUE);
m_btnBiologyLine.EnableWindow(TRUE);
m_btnHistoryLine.EnableWindow(TRUE);
m_btnChemistryLine.EnableWindow(TRUE);
m_btnSportLine.EnableWindow(TRUE);
}
字串表
下载地址:
https://download.csdn.net/download/qq_33290233/12078416