MFC課程設計 --學生成績管理系統

MFC課程設計 ,C++課程設計 --學生成績管理系統

ps:因爲課設完成的過程大家都不太一樣,以下的代碼僅供學習一下在MFC下各個控件的用法,有問題歡迎留言討論。

 

 

  • 實驗目的
  1. 使用MFC類庫編制應用程序:按鈕控件、靜態控件及編輯框的應用。
  2. 瞭解MFC類的層次結構及主要類的用法,掌握使用MFC和嚮導來編寫Windows應用程序。
  3. 熟悉Microsoft Visual Studio2013的開發環境。
  4. 掌握在Microsoft Visual Studio2013開發環境調試程序的方法。
  5. 掌握靜態控件、按鈕、流動條、編輯框、列表框、組合框和對話框的創建、消息發送和控件控制等內容。
  6. 對前面所學知識的總結,通過一個比較完整的應用程序的設計,將學過的知識連貫起來,掌握開發一個實際應用程序的步驟,同時學會使用開發工具實現界面友好的應用程序。並通過本實驗,掌握如何運用面向對象技術對具體的應用系統進行分析和設計。

二、實驗內容

 

本次c++課設的學生成績管理系統是面向學生和教師的。該系統有三種身份賬號,其中學生賬號可以在裏面查詢自己的成績,而教師賬號可以添加,刪除和修改學生的成績,而管理員賬號可以添加,刪除和修改學生的成績外,還能可以添加,刪除和修改登錄使用的賬號。

另外,用單文檔設計的學生成績分析圖形繪製。並用該學生成績管理系統調用該畫圖的exe文件,實現在該學生成績管理系統中顯示學生成績的直方圖和曲線圖。

登錄界面:

 

 

學生成績管理界面:

(1)、設計一個學生類Student,包括數據成員:姓名、學號、五門課程(高等數學,離散數學,C++課設,大學英語,大學體育)的成績。

(2)、創建一個基於對話框的MFC應用程序,程序窗口的標題上有你姓名、學號和應用程序名稱。使用(1)的類,實現對學生信息和成績的輸入和管理。

(3)、創建一個單文檔的MFC應用程序,讀取(2)中保存的文件中的學生成績,分別用直方圖和折線方式顯示所有學生某課程的成績分佈圖。

(4)創建一個登錄管理界面,學生可以用學生賬號登錄查看成績,教師可以使用教師賬號登錄查看並添加,刪除,修改學生的成績。而管理員賬號可以添加,刪除和修改學生和老師的登錄賬號,老師和學生賬號只能修改自身的登錄密碼。

(5)創建一個學生成績管理主界面,上面有list控件之間將存儲在文件的學生信息顯示在主界面上,另外還有查找控件,組合控件進行排序,添加,刪除和修改控件。還有賬號管理,重新登錄和退出控件。

(6)創建一個學生信息查找後顯示的學生詳細信息界面,擁有教師賬號的用戶可以通過對這個界面信息的修改,按下“修改保存”的控件進行信息的修改。

 

 

 

 

 

 

 

(7)點擊組合框排序,按確定鍵後,會通過list和文件的操作,進行對應的排序。可以進行的排序爲:學號,高數成績,離散成績,c++課設成績,英語成績,體育成績。排序後的內容會直接顯示在學生成績管理的主界面list中。

 

 

(8)用單文檔對學生成績儲存的文件進行操作,並進行直方圖和折線圖的繪畫。在學生成績管理住界面點擊統計分析,可以直接調用該單文檔exe.

 

 

(8)創建一個重新登錄界面,用戶可以通過重新登錄的方法進行該學生成績管理系統用戶的更換。該界面需要輸入學號,舊密碼,新密碼,再次輸入新密碼才能修改該賬號的密碼。

(9)創建一個登錄賬號管理界面,只有admin的管理員賬號才能進行賬號的添加,修改和刪除。

三實驗設備

 

Win7操作系統

Microsoft Visual Studio2013

 

四、實驗要求

 

1.  使用MFC類庫編制應用程序:按鈕控件、靜態控件及編輯框的應用。

2.  瞭解MFC類的層次結構及主要類的用法,掌握使用MFC和嚮導來編寫Windows應用程序。

3掌握靜態控件、按鈕、流動條、編輯框、列表框、組合框和對話框的創建、消息發送和控件控制等內容。

4對前面所學知識的總結,通過一個比較完整的應用程序的設計,將學過的知識連貫起來,掌握開發一個實際應用程序的步驟,同時學會使用開發工具實現界面友好的應用程序。並通過本實驗,掌握如何運用面向對象技術對具體的應用系統進行分析和設計。

 

五、實驗程序

(1)登錄界面

LoginDlg.cpp的主要關鍵代碼

          //在主界面調用之前在BOOL CMFC課設學生成績管理系統App::InitInstance()

中添加

CLoginDlg dl;

         if (IDCANCEL == dl.DoModal())

                   return FALSE;

功能是實現先調用登錄窗口。

void CLoginDlg::OnBnClickedOk()    //點擊登錄的響應函數
{
	if (CheckSuer())               //登錄賬號和密碼的確定是否正確
		CDialog::OnOK();	
	else
	{
		AfxMessageBox("用戶名或密碼錯誤");   //密碼錯誤則彈出窗口提示錯誤
		SetDlgItemText(IDC_NAME, "");        //重置兩個編輯框
		SetDlgItemText(IDC_PASS, "");
		this->SetFocus();
	}
}

bool  CLoginDlg::CheckSuer()         //賬戶和密碼確認
{
	CString szName, szPass;
	GetDlgItemText(IDC_NAME, szName);
	GetDlgItemText(IDC_PASS, szPass);
	szName.MakeLower();
	
	if (szName == "admin"&&szPass == "123")    //是否爲管理員賬號
	{
		SUser u = { "admin", "123", 1 };
		theApp.m_us = u;                    //將登錄人員的信息記錄在theApp中
		return TRUE;

	}
	SUser u;
	CFile file;
	if (!file.Open("./user.dat", CFile::modeRead))
	{
		CreatUser();
		if (!file.Open("./user.dat", CFile::modeRead))
			return FALSE;
	}
	while (file.Read(&u, sizeof(u)))
	{
		if (szName == u.sName&&szPass == u.sPass)
		{
			theApp.m_us = u;
			return TRUE;
		}
	}
	return FALSE;
}
void CLoginDlg::CreatUser()          //如果不存在賬號和密碼存儲的文件,則新建一個存儲文件
{
	CFile file;
	if (!file.Open("./user.dat", CFile::modeCreate | CFile::modeWrite))
	{
		AfxMessageBox("用戶文件創建失敗");
		return;
	}
}

(2)學生成績管理主界面

BEGIN_MESSAGE_MAP(CMFC課設學生成績管理系統Dlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_ManagePower, &CMFC課設學生成績管理系統Dlg::OnBnClickedManagepower)
	ON_BN_CLICKED(IDC_AGAIN_LOGIN, &CMFC課設學生成績管理系統Dlg::OnBnClickedAgainLogin)
	ON_BN_CLICKED(IDC_STUDENT_ADD, &CMFC課設學生成績管理系統Dlg::OnBnClickedStudentAdd)
	ON_BN_CLICKED(IDC_STUDENT_DEL, &CMFC課設學生成績管理系統Dlg::OnBnClickedStudentDel)
	ON_BN_CLICKED(IDC_STUDENT_SEEK, &CMFC課設學生成績管理系統Dlg::OnBnClickedStudentSeek)
	ON_BN_CLICKED(IDC_STUDENT_CHANGE, &CMFC課設學生成績管理系統Dlg::OnBnClickedStudentChange)
	ON_BN_CLICKED(IDC_BUTTON8, &CMFC課設學生成績管理系統Dlg::OnBnClickedButton8)
	ON_BN_CLICKED(IDC_STUDENT_IDCANCEL, &CMFC課設學生成績管理系統Dlg::OnBnClickedStudentIdcancel)
	ON_BN_CLICKED(IDC_STUDENT_DIALOG_OKSORT, &CMFC課設學生成績管理系統Dlg::OnBnClickedStudentDialogOksort)
	ON_BN_CLICKED(IDC_PICTURE_ANALYSIS, &CMFC課設學生成績管理系統Dlg::OnBnClickedPictureAnalysis)
END_MESSAGE_MAP()


// CMFC課設學生成績管理系統Dlg 消息處理程序

BOOL CMFC課設學生成績管理系統Dlg::OnInitDialog()  //初始化窗口
{
	CDialogEx::OnInitDialog();
	CString str = "1606100*** 卟咚君 學生成績管理系統           用戶:";    //在窗口左上角設置自己的姓名和學號(課設要求),以及本次顯示登錄的賬號
	str += theApp.m_us.sName;
	SetWindowText(str);
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_STUDENT_DIALOG_LIST);     // 初始化(IDC_STUDENT_DIALOG)ListCtrl控件
	pList->InsertColumn(0, "體育", 0, 80);    
	pList->InsertColumn(0, "英語", 0, 80);
	pList->InsertColumn(0, " c++", 0, 80);
	pList->InsertColumn(0, "離散", 0, 80);
	pList->InsertColumn(0, "高數", 0, 80);
	pList->InsertColumn(0, "姓名", 0, 100);
	pList->InsertColumn(0, "學號", 0, 100);
	SortStudent(0);
	ReadStudent(pList);
	CComboBox* pComb = (CComboBox*)GetDlgItem(IDC_STUDENT_DIALOG_SORTLIST);   //設置(IDC_STUDENT_DIALOG)CComboBox控件
	pComb->AddString("學號");   
	pComb->AddString("高數");
	pComb->AddString("離散");
	pComb->AddString("c++");
	pComb->AddString("英語");
	pComb->AddString("體育");
	pComb->SetCurSel(0);
	CComboBox* pComb1 = (CComboBox*)GetDlgItem(IDC_STUDENT_DIALOG_SORTLIST);   //獲得排列組合控件的信息
	int nSel = pComb1->GetCurSel();
	GetDlgItem(IDC_STUDENT_ADD)->EnableWindow(theApp.m_us.nPrior);     //對應相應的身份權限設置是否屏蔽添加權限
	GetDlgItem(IDC_STUDENT_DEL)->EnableWindow(theApp.m_us.nPrior);     //對應相應的身份權限設置是否屏蔽刪除權限
	GetDlgItem(IDC_STUDENT_CHANGE)->EnableWindow(theApp.m_us.nPrior);   //對應相應的身份權限設置是否屏蔽修改權限
	//pComb->SetItemHeight(25,25);
	//GetDlgItem(IDC_ManagePass)->EnableWindow(theApp.m_us.nPrior);
	//GetDlgItem(IDC_ManagePower)->EnableWindow(theApp.m_us.nPrior);

	// 將“關於...”菜單項添加到系統菜單中。

	// IDM_ABOUTBOX 必須在系統命令範圍內。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 設置此對話框的圖標。  當應用程序主窗口不是對話框時,框架將自動
	//  執行此操作
	SetIcon(m_hIcon, TRUE);			// 設置大圖標
	SetIcon(m_hIcon, FALSE);		// 設置小圖標

	// TODO:  在此添加額外的初始化代碼

	return TRUE;  // 除非將焦點設置到控件,否則返回 TRUE
}

void CMFC課設學生成績管理系統Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向對話框添加最小化按鈕,則需要下面的代碼
//  來繪製該圖標。  對於使用文檔/視圖模型的 MFC 應用程序,
//  這將由框架自動完成。

void CMFC課設學生成績管理系統Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用於繪製的設備上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使圖標在工作區矩形中居中
		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;

		// 繪製圖標
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//當用戶拖動最小化窗口時系統調用此函數取得光標
//顯示。
HCURSOR CMFC課設學生成績管理系統Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CMFC課設學生成績管理系統Dlg::OnBnClickedManagepower()    //“賬號管理”控件響應函數,調用 CPower(管理權限)類的窗口
{
	CPower dl;
	dl.DoModal();
}


void CMFC課設學生成績管理系統Dlg::OnBnClickedAgainLogin()   //“重新登錄”控件響應函數
{
	CDialog::OnCancel();                                    //關閉當前的學生成績管理系統窗口
	CLoginDlg dl;                                          //調用登錄窗口
	if (IDOK == dl.DoModal())                              //成功登錄返回IDOK,在調用新的學生成績管理系統窗口
	{                                                      //登錄退出則返回IDCANCEL
		CMFC課設學生成績管理系統Dlg dlg;
		dlg.DoModal();
	}
}


void CMFC課設學生成績管理系統Dlg::OnBnClickedStudentAdd()    //“添加”控件響應函數,調用IDD_StudentSpecificAddDlg添加窗口,添加學號和相應成績信息
{
	CStudentSpecificAddDlg dl;
	if (IDCANCEL == dl.DoModal())
	{
		CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_STUDENT_DIALOG_LIST);  //關閉IDD_StudentSpecificAddDlg添加窗口,讀取儲存學生成績的文件刷新學生成績管理系統窗口
		CMFC課設學生成績管理系統Dlg::ReadStudent(pList);
		OnBnClickedStudentDialogOksort();
	}
}


void CMFC課設學生成績管理系統Dlg::ReadStudent(CListCtrl* pList)    //讀取儲存學生成績的文件,並加載在學生成績管理系統窗口的CListCtrl中
{
	CFile file;
	if (!file.Open("./studentfile.dat", CFile::modeRead | CFile::shareDenyNone))
	{
		GreatStudentfile();
		return;
	}
	pList->DeleteAllItems();
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		pList->InsertItem(i, u.sId);
		pList->SetItemText(i, 1, u.sName);
		pList->SetItemText(i, 2, u.sHigher_math);
		pList->SetItemText(i, 3, u.sDiscrete_math);
		pList->SetItemText(i, 4, u.sC_program);
		pList->SetItemText(i, 5, u.sEnglish);
		pList->SetItemText(i, 6, u.sSports);
		i++;
	}
	file.Close();
}


void CMFC課設學生成績管理系統Dlg::GreatStudentfile()   //創建用戶登錄賬號儲存文件
{
	CFile file;
	if (!file.Open("./studentfile.dat", CFile::modeCreate | CFile::modeWrite))
	{
		AfxMessageBox("用戶文件創建失敗");
		return;
	}
	file.Close();
}


void CMFC課設學生成績管理系統Dlg::OnBnClickedStudentDel()  // “刪除”控件響應函數
{
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_STUDENT_DIALOG_LIST);
	Student ur;
	int nSel = pList->GetSelectedCount();    //獲取當前鼠標選擇的學號數量
	if (nSel < 1)
	{
		AfxMessageBox("請選擇一個賬戶再刪除!");
		return;
	}
	int nSelText = pList->GetSelectionMark();   //獲取當前鼠標選擇的一個學號位置
	pList->GetItemText(nSelText, 0, ur.sId, sizeof(ur.sId));
	pList->DeleteItem(nSelText);   //刪除當前鼠標選擇的學號位置
	CFile file;
	if (!file.Open("./studentfile.dat", CFile::modeRead | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開!");
		return;
	}
	CFile temporaryfile;
	if (!temporaryfile.Open("./temporarystudentfile.dat", CFile::modeCreate|CFile::modeWrite| CFile::shareDenyNone))
	{
		GreatTemporaryStudentfile();
		return;
	}
	Student u;
	while (file.Read(&u, sizeof(u)) == sizeof(u)) //讀取學生成績儲存文件,將未刪除的學生信息寫入臨時文件temporaryfile中
	{
		if ((CString)u.sId == (CString)ur.sId)
			continue;
		temporaryfile.Write(&u, sizeof(u));
	}
	file.Close();
	temporaryfile.Close();
	if (!file.Open("./studentfile.dat", CFile::modeCreate|CFile::modeWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開!");
		return;
	}
	if (!temporaryfile.Open("./temporarystudentfile.dat", CFile::modeRead | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開!");
		return;
	}
	while (temporaryfile.Read(&u, sizeof(u)) == sizeof(u))  //讀取學生成績儲存文件,將臨時文件temporarystudentfile.dat中學生信息寫入真正存儲學生信息的studentfile.dat中
		file.Write(&u, sizeof(u));
	CMFC課設學生成績管理系統Dlg::ReadStudent(pList);  //更新學生成績管理系統界面的信息
	OnBnClickedStudentDialogOksort();
	return;
}


void CMFC課設學生成績管理系統Dlg::OnBnClickedStudentSeek()   //“查找”控件對應的函數,查找學生的學號
{
	int nNum;
	char str[20];
	GetDlgItemText(IDC_STUDENT_DIALOG_ID, str, sizeof(str));  //獲取編輯框的學號信息
	if ((CString)str == "")
	{
		AfxMessageBox("請在學號框裏輸入學號!");
		return;
	}
	nNum = Seek_Student(str);  //查詢該學號是否存在
	if (nNum == -1)
	{
		AfxMessageBox("該用戶不存在!");
	}
	Student u;
	CFile file;
	if (!file.Open("./studentfile.dat", CFile::modeRead | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開!");
		return;
	}
	while (file.Read(&u, sizeof(u)) == sizeof(u)) //查詢該學號同學的詳細信息
	{
		if ((CString)u.sId == (CString)str)
		{
			theApp.m_student = u;
			file.Close();
			CStudentSpecificSeekDlg dlg;  //將該學號同學的詳細信息顯示在詳細信息窗口(IDD_STUDENT_SPECIFIC_DIALOG)
			if (IDCANCEL == dlg.DoModal())
			{
				CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_STUDENT_DIALOG_LIST);  //更新學生成績管理系統界面的信息
				CMFC課設學生成績管理系統Dlg::ReadStudent(pList);
			}
			return;
		}
	}
	file.Close();
}


int CMFC課設學生成績管理系統Dlg::Seek_Student(char *str)   //查詢該同學是否存在學生成績管理系統的CListCtrl中
{
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_STUDENT_DIALOG_LIST);
	int nCount = pList->GetItemCount();
	int i = 0;
	while (i < nCount)
	{
		if (pList->GetItemText(i, 0) == (CString)str)
		{
			return i;
		}
		i++;
	}
	return -1;
}


void CMFC課設學生成績管理系統Dlg::OnBnClickedStudentChange()  //"修改“控件響應的函數,修改學生的信息
{
	
	OnBnClickedStudentSeek();                                  //調用查找函數,修改在查找函數中實現
}



void CMFC課設學生成績管理系統Dlg::OnBnClickedButton8()          //"退出”控件響應函數,退出學生成績管理系統
{
	CDialog::OnCancel();
}

void CMFC課設學生成績管理系統Dlg::OnBnClickedStudentIdcancel()
{
	CDialog::OnCancel();
}


void CMFC課設學生成績管理系統Dlg::GreatTemporaryStudentfile()    //創建臨時存儲學生信息的文件
{
	CFile file;
	if (!file.Open("./temporarystudentfile.dat", CFile::modeCreate | CFile::modeWrite))
	{
		AfxMessageBox("用戶文件創建失敗");
		return;
	}
	file.Close();
}


void CMFC課設學生成績管理系統Dlg::OnBnClickedStudentDialogOksort()  //排序"確定”控件響應函數,進行(學號,高數,離散,c++課設,英語,體育成績)的排序
{
	CComboBox* pComb = (CComboBox*)GetDlgItem(IDC_STUDENT_DIALOG_SORTLIST);
	int nSel = pComb->GetCurSel();
	SortStudent(nSel);
	
}

bool nsort_id(Student a, Student b)  //學號(ID)大小比較函數
{
	return _ttoi((CString)a.sId)<_ttoi((CString)b.sId);  //將char轉換成CString,在轉化成int
}
bool sort_higher_math(Student a, Student b)
{
	return _ttoi((CString)a.sHigher_math)>_ttoi((CString)b.sHigher_math);  //高數(Higher_math)大小比較函數
}
bool sort_discrete_math(Student a, Student b)
{
	return _ttoi((CString)a.sDiscrete_math) > _ttoi((CString)b.sDiscrete_math);  //離散(Discrete_math)大小比較函數
}
bool sort_c_program(Student a, Student b)
{
	return _ttoi((CString)a.sC_program) > _ttoi((CString)b.sC_program);   //c++(C_program)大小比較函數
}
bool sort_english(Student a, Student b)
{
	return _ttoi((CString)a.sEnglish) > _ttoi((CString)b.sEnglish); //英語(English)大小比較函數
}
bool sort_sports(Student a, Student b)
{
	return _ttoi((CString)a.sSports)> _ttoi((CString)b.sSports);   //英語(Sports)大小比較函數
}
void CMFC課設學生成績管理系統Dlg::SortStudent(int nNum)    //對應排序對學生信息進行排序
{
	Student SomeStudent[1000];
	CFile file;
	if (!file.Open("./studentfile.dat", CFile::modeRead | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法排序!");
		return;
	}
	int i = 0;
	while (file.Read(&SomeStudent[i], sizeof(SomeStudent[i])) == sizeof(SomeStudent[i]))
	{
		i++;
	}
	file.Close();
	int b = (CString)SomeStudent[0].sId < (CString)SomeStudent[1].sId;
	if (nNum == 0)    //0是學號成績排序
		std::sort(SomeStudent, SomeStudent+i, nsort_id);  //排序是直接調用STL中的快排
	if (nNum == 1)     //1是高數成績排序
		std::sort(SomeStudent, SomeStudent + i, sort_higher_math);
	if (nNum == 2)    //2是離散成績排序
		std::sort(SomeStudent, SomeStudent + i, sort_discrete_math);
	if (nNum == 3)    //3是C++課設成績排序
		std::sort(SomeStudent, SomeStudent + i, sort_c_program);
	if (nNum == 4)    //4是英語成績排序
		std::sort(SomeStudent, SomeStudent + i, sort_english);
	if (nNum == 5)    //5是體育成績排序
		std::sort(SomeStudent, SomeStudent + i, sort_sports);
	if (!file.Open("./studentfile.dat", CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法排序!");
		return;
	}
	int t = 0;
	while (t<i)  //將排好序的信息寫入學生成績存儲文件
	{
		file.Write(&SomeStudent[t], sizeof(SomeStudent[t]));
		t++;
	}
	file.Close();
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_STUDENT_DIALOG_LIST);
	CMFC課設學生成績管理系統Dlg::ReadStudent(pList); //將排好序的學生信息更新到學生成績管理系統的CListCtrl中

}


void CMFC課設學生成績管理系統Dlg::OnBnClickedPictureAnalysis()  //"統計分析“控件響應的函數
{
	ShellExecute(NULL, "open", "E://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//MFCApplication1.exe", NULL, NULL, SW_SHOWNORMAL);
	//用ShellExecute調用可以畫直方圖和折線圖的exe文件
}

3)添加學生信息的窗口

BEGIN_MESSAGE_MAP(CStudentSpecificAddDlg, CDialog)
	ON_BN_CLICKED(IDC_STUDENG_SPECIFIC_ADD_SAVE, &CStudentSpecificAddDlg::OnBnClickedStudengSpecificAddSave)
	ON_BN_CLICKED(IDC_STUDENG_SPECIFIC_ADD_INCANCE, &CStudentSpecificAddDlg::OnBnClickedStudengSpecificAddIncance)
END_MESSAGE_MAP()


// CStudentSpecificAddDlg 消息處理程序


BOOL CStudentSpecificAddDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	return TRUE;
}


void CStudentSpecificAddDlg::OnBnClickedStudengSpecificAddSave()  //"添加保存:控件響應函數
{
	// TODO:  在此添加控件通知處理程序代碼
	Student u;
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_ID, u.sId, sizeof(u.sId));  //將學號編輯框的內容寫入u.sId
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_NAME, u.sName, sizeof(u.sName));  //將姓名編輯框的內容寫入u.sName
	if (IDC_STUDENG_SPECIFIC_ADD_MALE == GetCheckedRadioButton(IDC_STUDENG_SPECIFIC_ADD_MALE, IDC_STUDENG_SPECIFIC_ADD_FEMALE))
		u.nSex = true;
	else
		u.nSex = false;
	//IDC_STUDENG_SPECIFIC_ADD_MALE爲“男”控件ID,IDC_STUDENG_SPECIFIC_ADD_FEMALE爲“女'控件的ID
	//用GetCheckedRadioButton函數獲取RadioButton控件的信息,GetCheckedRadioButton(IDC_STUDENG_SPECIFIC_ADD_MALE, IDC_STUDENG_SPECIFIC_ADD_FEMALE)返回
	//IDC_STUDENG_SPECIFIC_ADD_MALE則爲男,否則爲女

	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_AGE, u.sAge, sizeof(u.sAge));  //將年齡編輯框的內容寫入u.sAge
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_ADDRESS, u.sAddress, sizeof(u.sAddress));  //將地址編輯框的內容寫入u.sAddress
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_HIGHERMATH, u.sHigher_math, sizeof(u.sHigher_math));  //將高數編輯框的內容寫入u.sHigher_math
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_DISCRETEMATH, u.sDiscrete_math, sizeof(u.sDiscrete_math));  //將離散編輯框的內容寫入u.sDiscrete_math
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_CPROGRAM, u.sC_program, sizeof(u.sC_program));  //將C++課設編輯框的內容寫入u.sC_program
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_ENGLISH, u.sEnglish, sizeof(u.sEnglish));   //將英語編輯框的內容寫入u.sEnglish
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADD_SPORTS, u.sSports, sizeof(u.sSports));   //將體育編輯框的內容寫入u.sSports
	CFile file;
	if (!file.Open("./studentfile.dat", CFile::modeReadWrite|CFile::shareDenyNone))
	{
		AfxMessageBox("添加失敗,文件打不開!");
		return ;
	}
	Student ur;
	while (file.Read(&ur, sizeof(ur)))   //讀取學生文件信息,看學號是否重複
	{
		if ((CString)ur.sId == (CString)u.sId)
		{
			AfxMessageBox("用戶已存在!");
			return;
		}
	}
	file.SeekToEnd();   //將指針移到文件末尾
	file.Write(&u, sizeof(u));  //在文件末尾寫入新的學生信息
	AfxMessageBox("添加保存成功!"); //提示保存成功
	
}


void CStudentSpecificAddDlg::OnBnClickedStudengSpecificAddIncance()  //“退出”控件響應函數,退出添加窗口
{
	CDialog::OnCancel();
	// TODO:  在此添加控件通知處理程序代碼
}

4)查找和刪除窗口

BEGIN_MESSAGE_MAP(CStudentSpecificSeekDlg, CDialog)
	ON_BN_CLICKED(IDOK, &CStudentSpecificSeekDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDC_STUDENG_SPECIFIC_CHANGE_SAVE, &CStudentSpecificSeekDlg::OnBnClickedStudengSpecificChangeSave)
	ON_BN_CLICKED(IDC_STUDENG_SPECIFIC_IDCACEL, &CStudentSpecificSeekDlg::OnBnClickedStudengSpecificIdcacel)
END_MESSAGE_MAP()


// CStudentSpecificSeekDlg 消息處理程序


BOOL CStudentSpecificSeekDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	GetDlgItem(IDC_STUDENG_SPECIFIC_CHANGE_SAVE)->EnableWindow(theApp.m_us.nPrior); //獲取賬號的權限信息,是否屏蔽“刪除”控件
	SetDlgItemText(IDC_STUDENG_SPECIFIC_ID,theApp.m_student.sId);  //設置顯示的學生的學號
	SetDlgItemText(IDC_STUDENG_SPECIFIC_NAME, theApp.m_student.sName);  //設置顯示的學生的姓名
	if (theApp.m_student.nSex==1)
	    CheckRadioButton(IDC_STUDENG_SPECIFIC_MALE, IDC_STUDENG_SPECIFIC_FEMALE, IDC_STUDENG_SPECIFIC_MALE);
	else
		CheckRadioButton(IDC_STUDENG_SPECIFIC_MALE, IDC_STUDENG_SPECIFIC_FEMALE, IDC_STUDENG_SPECIFIC_FEMALE);
	//設置顯示的學生的性別
	//用CheckRadioButton設置RadioButton的顯示
	SetDlgItemText(IDC_STUDENG_SPECIFIC_AGE, theApp.m_student.sAge); //設置顯示的學生的年齡
	SetDlgItemText(IDC_STUDENG_SPECIFIC_ADDRESS, theApp.m_student.sAddress); //設置顯示的學生的地址
	SetDlgItemText(IDC_STUDENG_SPECIFIC_HIGHERMATH, theApp.m_student.sHigher_math);//設置顯示的學生的高數成績
	SetDlgItemText(IDC_STUDENG_SPECIFIC_DISCRETEMATH, theApp.m_student.sDiscrete_math);//設置顯示的學生的離散成績
	SetDlgItemText(IDC_STUDENG_SPECIFIC_CPROGRAM, theApp.m_student.sC_program);//設置顯示的學生的c++課設成績
	SetDlgItemText(IDC_STUDENG_SPECIFIC_ENGLISH, theApp.m_student.sEnglish);//設置顯示的學生的英語成績
	SetDlgItemText(IDC_STUDENG_SPECIFIC_SPORTS, theApp.m_student.sSports);//設置顯示的學生的體育成績
	return TRUE;
}


void CStudentSpecificSeekDlg::OnBnClickedOk()  //"退出“控件響應函數
{
	// TODO:  在此添加控件通知處理程序代碼
	CDialog::OnOK();
}


void CStudentSpecificSeekDlg::OnBnClickedStudengSpecificChangeSave() //"修改”控件響應函數
{
	// TODO:  在此添加控件通知處理程序代碼
	Student u;
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ID, u.sId, sizeof(u.sId));    //將新的信息寫入u(Student)中
	GetDlgItemText(IDC_STUDENG_SPECIFIC_NAME, u.sName, sizeof(u.sName));

	if (IDC_STUDENG_SPECIFIC_MALE == GetCheckedRadioButton(IDC_STUDENG_SPECIFIC_MALE, IDC_STUDENG_SPECIFIC_FEMALE))
		u.nSex = true;
	else
		u.nSex = false;
	GetDlgItemText(IDC_STUDENG_SPECIFIC_AGE, u.sAge, sizeof(u.sAge));
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ADDRESS, u.sAddress, sizeof(u.sAddress));
	GetDlgItemText(IDC_STUDENG_SPECIFIC_HIGHERMATH, u.sHigher_math, sizeof(u.sHigher_math));
	GetDlgItemText(IDC_STUDENG_SPECIFIC_DISCRETEMATH, u.sDiscrete_math, sizeof(u.sDiscrete_math));
	GetDlgItemText(IDC_STUDENG_SPECIFIC_CPROGRAM, u.sC_program, sizeof(u.sC_program));
	GetDlgItemText(IDC_STUDENG_SPECIFIC_ENGLISH, u.sEnglish, sizeof(u.sEnglish));
	GetDlgItemText(IDC_STUDENG_SPECIFIC_SPORTS, u.sSports, sizeof(u.sSports));
	CFile file;
	//file.Open("./studentfile.dat", CFile::modeWrite | CFile::shareDenyNone);
	if ((CString)u.sId != (CString)theApp.m_student.sId)
	{
		AfxMessageBox("請輸入同一學號!");
		SetDlgItemText(IDC_STUDENG_SPECIFIC_ID, theApp.m_student.sId);
		return;
	}
	if (!file.Open("./studentfile.dat", CFile::modeRead | CFile::shareDenyNone))
	{
		AfxMessageBox("修改失敗,文件打不開!");
		return;
	}
	int i = 0;
	Student ur;
	while (file.Read(&ur, sizeof(ur)))  //讀取學生成績儲存文件,找到該學生信息儲存的對應位置
	{
		if ((CString)theApp.m_student.sId == (CString)ur.sId)
		{
			break;
		}
		i++;
	}
	file.Close();
	if (!file.Open("./studentfile.dat", CFile::modeWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("修改失敗,文件打不開!");
		return;
	}
	file.SeekToBegin(); // 重新設置file文件的寫指針時期剛好在要修改的學生信息那裏
	file.Seek(i*sizeof(u), CFile::current);
	file.Write(&u, sizeof(u));  //用新的信息對原來的信息進行覆蓋,實現修改
	AfxMessageBox("修改保存成功!");
	file.Close();
}


void CStudentSpecificSeekDlg::OnBnClickedStudengSpecificIdcacel() // "退出“控件響應函數
{
	CDialog::OnCancel();
	// TODO:  在此添加控件通知處理程序代碼
}

(5)“賬號管理”窗口

BEGIN_MESSAGE_MAP(CPower, CDialog)
	ON_BN_CLICKED(IDC_ManagePass, &CPower::OnBnClickedManagepass)
	ON_BN_CLICKED(IDC_ChangePass, &CPower::OnBnClickedChangepass)
	ON_BN_CLICKED(IDC_MANAGE_CHANGE_PASS, &CPower::OnBnClickedManageChangePass)
	ON_BN_CLICKED(IDC_GENERAL_CHANGE_PASS, &CPower::OnBnClickedGeneralChangePass)
	ON_BN_CLICKED(IDCANCEL, &CPower::OnBnClickedCancel)
END_MESSAGE_MAP()


// CPower 消息處理程序


void CPower::OnBnClickedManagepass()  //“學號密碼添加與刪除”控件響應函數,調用管理員窗口,進行學號密碼添加與刪除
{
	// TODO:  在此添加控件通知處理程序代碼
	CManagePower dl;  
	dl.DoModal();
}


void CPower::OnBnClickedChangepass()
{
	// TODO:  在此添加控件通知處理程序代碼
}


void CPower::OnBnClickedManageChangePass() //“學號密碼添加與刪除”控件響應函數,調用管理員(CManagePower)窗口,進行學號密碼的修改
{
	CManagePower dl;
	dl.DoModal();
	// TODO:  在此添加控件通知處理程序代碼
}


void CPower::OnBnClickedGeneralChangePass() //“學號密碼修改”控件響應函數,調用密碼修改(CChangePass)窗口,學生和教師權限的賬號可通過這個進行學號密碼的修改
{
	CChangePass dl;
	dl.DoModal();
	// TODO:  在此添加控件通知處理程序代碼
}


BOOL CPower::OnInitDialog()  //賬號管理窗口的初始化,根據用戶的權限是否屏蔽“學號密碼添加與刪除”控件
{
	CDialog::OnInitDialog();
	GetDlgItem(IDC_MANAGE_CHANGE_PASS)->EnableWindow((CString)theApp.m_us.sName=="admin");
	return TRUE;
}


void CPower::OnBnClickedCancel() //“退出”控件響應函數,退出賬號管理窗口
{
	// TODO:  在此添加控件通知處理程序代碼
	CDialog::OnCancel();
}

(6)學號密碼修改窗口

BEGIN_MESSAGE_MAP(CChangePass, CDialog)
	ON_BN_CLICKED(IDC_OKCHANGE_PASS, &CChangePass::OnBnClickedOkchangePass)
END_MESSAGE_MAP()


// CChangePass 消息處理程序


BOOL CChangePass::Check_ChangePass() //修改“確定”控件響應函數
{
	CString szName, szOrdedPass, szNewPassOne, szNewPasstwo; //獲取要修改的學號和密碼
	GetDlgItemText(IDC_CHANGEPASS_NAME, szName);
	GetDlgItemText(IDC_CHANGEPASS_ORDEDPASS, szOrdedPass);
	GetDlgItemText(IDC_CHANGEPASS_NEWPASS_ONE, szNewPassOne);
	GetDlgItemText(IDC_CHANGEPASS_NEWPASS_TWO, szNewPasstwo);
	szName.MakeLower();
	SUser u;
	CFile file;
	if (!file.Open("./user.dat", CFile::modeReadWrite))
	{
		return FALSE;
	}
	int i = 0;
	while (file.Read(&u, sizeof(u)))   //兩次輸入新密碼的確認
	{
		if (szName == (CString)u.sName&&szOrdedPass == (CString)u.sPass)
		{
			if (szNewPassOne != szNewPasstwo)
			{
				AfxMessageBox("新密碼兩次輸入不正確!");
				InitCCangePassDialog();
			}
			strcpy_s(u.sPass, szNewPassOne);
			file.SeekToBegin();
			file.Seek(i*sizeof(u), CFile::current);
			file.Write(&u, sizeof(u));
			AfxMessageBox("修改成功!");
			InitCCangePassDialog();
			return TRUE;
		}
		i++;
	}
	AfxMessageBox("該用戶或舊密碼不正確!");
	InitCCangePassDialog();
	return FALSE;
}


void CChangePass::OnBnClickedOkchangePass()  //修改“確定”控件響應函數
{
	Check_ChangePass();
	// TODO:  在此添加控件通知處理程序代碼
}


void CChangePass::InitCCangePassDialog()  //重置學號密碼修改窗口的編輯框
{
	SetDlgItemText(IDC_CHANGEPASS_NAME, "");
	SetDlgItemText(IDC_CHANGEPASS_ORDEDPASS, "");
	SetDlgItemText(IDC_CHANGEPASS_NEWPASS_ONE, "");
	SetDlgItemText(IDC_CHANGEPASS_NEWPASS_TWO, "");
	this->SetFocus();
}
(6)學號密碼添加與刪除窗口
BEGIN_MESSAGE_MAP(CManagePower, CDialog)
	ON_CBN_SELCHANGE(IDC_MANAGEPOWER_POWER, &CManagePower::OnCbnSelchangeManagepowerPower)
	ON_EN_CHANGE(IDC_MANAGEPOWER_PASS, &CManagePower::OnEnChangeManagepowerPass)
	ON_BN_CLICKED(IDC_ADD, &CManagePower::OnBnClickedAdd)
	ON_BN_CLICKED(IDCANCEL, &CManagePower::OnBnClickedCancel)
	ON_BN_CLICKED(IDC_DEL, &CManagePower::OnBnClickedDel)
	ON_BN_CLICKED(IDC_CHANGE, &CManagePower::OnBnClickedChange)
	ON_EN_CHANGE(IDC_MANAGEPOWER_NAME, &CManagePower::OnEnChangeManagepowerName)
END_MESSAGE_MAP()


// CManagePower 消息處理程序




BOOL CManagePower::OnInitDialog() //學號密碼添加與刪除窗口的初始化
{
	CDialog::OnInitDialog();
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_MANAGEPOWER_LIST);
	pList->InsertColumn(0, "身份", 0, 100); //學號密碼添加與刪除窗口中CListCtrl(IDC_MANAGEPOWER_LIST)初始化
	pList->InsertColumn(0, "密碼", 0, 100);
	pList->InsertColumn(0, "學號", 0, 100);
	ReadUser(pList);
	CComboBox* pComb = (CComboBox*)GetDlgItem(IDC_MANAGEPOWER_POWER);
	pComb->AddString("學生");  ////學號密碼添加與刪除窗口中CComboBox(IDC_MANAGEPOWER_POWER)初始化
	pComb->AddString("老師");
	pComb->SetCurSel(0);
	return TRUE;
}


void CManagePower::OnCbnSelchangeManagepowerPower()
{
	// TODO:  在此添加控件通知處理程序代碼
}


void CManagePower::OnEnChangeManagepowerPass()
{
	// TODO:  如果該控件是 RICHEDIT 控件,它將不
	// 發送此通知,除非重寫 CDialog::OnInitDialog()
	// 函數並調用 CRichEditCtrl().SetEventMask(),
	// 同時將 ENM_CHANGE 標誌“或”運算到掩碼中。

	// TODO:  在此添加控件通知處理程序代碼
}


void CManagePower::OnBnClickedAdd()  //"添加“控件響應函數,添加新的用戶賬號
{
	// TODO:  在此添加控件通知處理程序代碼
	SUser u;
	GetDlgItemText(IDC_MANAGEPOWER_NAME, u.sName, sizeof(u.sName)); //獲取賬號編輯框的信息
	strlwr(u.sName);    //u.sName大寫轉小寫
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_MANAGEPOWER_LIST); //獲取密碼編輯框的信息
	int i = 0;
	int nCount = pList->GetItemCount(); //獲取權限的信息
	while (i < nCount)
	{
		if (pList->GetItemText(i, 0) == u.sName)   //檢驗是否存在該用戶
		{
			AfxMessageBox("用戶已存在");
			return;
		}
		i++;
	}
	pList->InsertItem(nCount, u.sName);  //將新用戶的信息添加入列表
	GetDlgItemText(IDC_MANAGEPOWER_PASS, u.sPass, sizeof(u.sPass));
	pList->SetItemText(nCount, 1, u.sPass);
	CComboBox* pComb = (CComboBox*)GetDlgItem(IDC_MANAGEPOWER_POWER);
	int nSel = pComb->GetCurSel();
	if (nSel)
		pList->SetItemText(nCount, 2, "老師");
	else
		pList->SetItemText(nCount, 2, "學生");
}

void CManagePower::OnBnClickedCancel() //”退出“控件響應函數
{
	// TODO:  在此添加控件通知處理程序代碼
	OnDestroy();  //退出前進行保存
	CDialog::OnCancel();
}


void CManagePower::OnDestroy()   //關閉學號密碼添加與刪除窗口,關閉之前先將列表的信息保存在賬戶信息文件中
{
	CDialog::OnDestroy();
	CFile file;
	if (!file.Open("./user.dat", CFile::modeCreate | CFile::modeWrite))
	{
		AfxMessageBox("保存文件時失敗!");
		return;
	}
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_MANAGEPOWER_LIST);
	int i = 0;
	int nCount = pList->GetItemCount();
	SUser u;
	while (i < nCount)
	{
		pList->GetItemText(i, 0, u.sName, sizeof(u.sName));
		pList->GetItemText(i, 1, u.sPass, sizeof(u.sPass));
		u.nPrior = pList->GetItemText(i, 2) == "老師";
		file.Write(&u, sizeof(u));
		i++;
	}
	file.Close();
	AfxMessageBox("保存文件成功!");
}





void CManagePower::ReadUser(CListCtrl* pList)  //讀取學生成績存儲文件,將其顯示在學號密碼添加與刪除窗口CListCtrl中
{
	CFile file;
	if (!file.Open("./user.dat", CFile::modeRead | CFile::shareDenyNone))
		return;
	pList->DeleteAllItems();
	SUser u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		pList->InsertItem(i, u.sName);
		pList->SetItemText(i, 1, u.sPass);
		pList->SetItemText(i, 2, u.nPrior ? "老師" : "學生");
		i++;
	}
	file.Close();
}
	
	


void CManagePower::OnBnClickedDel()  //”刪除“控件響應函數
{
	// TODO:  在此添加控件通知處理程序代碼
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_MANAGEPOWER_LIST);
	SUser u;
	GetDlgItemText(IDC_MANAGEPOWER_NAME, u.sName, sizeof(u.sName));
	strlwr(u.sName);
	
	int nSel = pList->GetSelectedCount(); //選擇一個賬戶
	if (nSel < 1&&u.sName=="")
	{
		AfxMessageBox("請選擇一個賬戶再刪除!");
		return;
	}
	if (nSel < 1 && (CString)u.sName != "")
	{
		int i = 0;
		int nCount = pList->GetItemCount();
		SUser ur;
		while (i < nCount)
		{
			pList->GetItemText(i, 0, ur.sName, sizeof(ur.sName));
			pList->GetItemText(i, 1, ur.sPass, sizeof(ur.sPass));
			ur.nPrior = pList->GetItemText(i, 2) == "老師";
			if ((CString)u.sName == (CString)ur.sName)
			{
				pList->DeleteItem(i);
				return;
			}
			i++;
		}
		AfxMessageBox("該賬戶不存在!");
		return;
	}
	else
	{
		if (nSel >= 1 && (CString)u.sName == "")
		{
			int nSelText = pList->GetSelectionMark();
			pList->DeleteItem(nSelText);
		}
		else
		{
			int nSelText = pList->GetSelectionMark();
			SUser ur;
			pList->GetItemText(nSelText, 0, ur.sName, sizeof(ur.sName));
			if ((CString)ur.sName == (CString)u.sName)
				pList->DeleteItem(nSelText);
			else
			{
				AfxMessageBox("請選擇同一個賬戶再刪除!");
				return;
			}
		}
	}
}


void CManagePower::OnBnClickedChange() //"修改“控件響應函數
{
	// TODO:  在此添加控件通知處理程序代碼
	CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_MANAGEPOWER_LIST);//獲取需要更改信息
	SUser u;
	GetDlgItemText(IDC_MANAGEPOWER_NAME, u.sName, sizeof(u.sName));
	GetDlgItemText(IDC_MANAGEPOWER_PASS, u.sPass, sizeof(u.sPass));
	strlwr(u.sName);
	CComboBox* pComb = (CComboBox*)GetDlgItem(IDC_MANAGEPOWER_POWER);
	u.nPrior = pComb->GetCurSel();
	int nSel = pList->GetSelectedCount();
	if (nSel < 1 && u.sName == "")
	{
		AfxMessageBox("請選擇一個賬戶再!");
		return;
	}
	if (nSel < 1 && (CString)u.sName != "")  //進行賬戶密碼信息更改
	{
		int i = 0;
		int nCount = pList->GetItemCount();
		SUser ur;
		while (i < nCount)
		{
			pList->GetItemText(i, 0, ur.sName, sizeof(ur.sName));
			pList->GetItemText(i, 1, ur.sPass, sizeof(ur.sPass));
			ur.nPrior = pList->GetItemText(i, 2) == "老師";
			if ((CString)u.sName == (CString)ur.sName)
			{
				pList->DeleteItem(i);
				pList->InsertItem(i, u.sName);
				pList->SetItemText(i, 1, u.sPass);
				pList->SetItemText(i, 2, u.nPrior ? "老師" : "學生");
				return;
			}
			i++;
		}
		AfxMessageBox("該賬戶不存在!");
		return;
	}
	else
	{
		if (nSel >= 1 && (CString)u.sName == "")
		{
			int nSelText = pList->GetSelectionMark();
			SUser ur;
			pList->GetItemText(nSelText, 0, ur.sName, sizeof(ur.sName));
			pList->DeleteItem(nSelText);
			pList->InsertItem(nSelText, ur.sName);
			pList->SetItemText(nSelText, 1, u.sPass);
			pList->SetItemText(nSelText, 2, u.nPrior ? "老師" : "學生");
		}
		else
		{
			int nSelText = pList->GetSelectionMark();
			SUser ur;
			pList->GetItemText(nSelText, 0, ur.sName, sizeof(u.sName));
			if ((CString)ur.sName == (CString)u.sName)
			{
				pList->DeleteItem(nSelText);
				pList->InsertItem(nSelText, ur.sName);
				pList->SetItemText(nSelText, 1, u.sPass);
				pList->SetItemText(nSelText, 2, u.nPrior ? "老師" : "學生");
			}
			else
			{
				AfxMessageBox("請選擇同一個賬戶再刪除!");
				return;
			}
		}
	}

}

(7)用單文檔讀取學生成績文件,進行直方圖和折線圖的繪畫

void CMFCApplication1View::OnDraw(CDC* pDC)
{
	CMFCApplication1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
}

// CMFCApplication1View 打印

BOOL CMFCApplication1View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默認準備
	return DoPreparePrinting(pInfo);
}

void CMFCApplication1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO:  添加額外的打印前進行的初始化過程
}

void CMFCApplication1View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO:  添加打印後進行的清理過程
}


// CMFCApplication1View 診斷

#ifdef _DEBUG
void CMFCApplication1View::AssertValid() const
{
	CView::AssertValid();
}

void CMFCApplication1View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMFCApplication1Doc* CMFCApplication1View::GetDocument() const // 非調試版本是內聯的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFCApplication1Doc)));
	return (CMFCApplication1Doc*)m_pDocument;
}
#endif //_DEBUG


// CMFCApplication1View 消息處理程序


void CMFCApplication1View::DrawScore(CDC* pDC, int * fScore, int nNum) //畫直方圖函數
{
	// fScore是成績數組指針,nNum是學生人數
	int nScoreNum[] = { 0, 0, 0, 0, 0 };  // 各成績段的人數的初 始值 
	// 下面是用來統計各分數段的人數   
	for (int 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 (int 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_BDIAGONAL, 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;   // 使每段的矩形寬度等於nSegWidth  
	CString strSeg[] = { (CString)"<60", (CString)"60-70", (CString)"70-80", (CString)"80-90", (CString)">=90" };
	CRect rcStr;
	for (int 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((CString)"%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->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);
}


int CMFCApplication1View::OnCreate(LPCREATESTRUCT lpCreateStruct)// 創建各個成績顯示控件
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	m_button1.Create((CString)"高等數學(直方)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(10, 10, 120, 40),            //按鈕大小
		this,                          //按鈕父指針
		IDC_HIGGER_MATH);                      //該按鈕對應的ID號
	m_button1.ShowWindow(SW_SHOWNORMAL);
	m_button2.Create((CString)"離散數學(直方)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(10, 60,120, 90),            //按鈕大小
		this,                          //按鈕父指針
		IDC_DISCRETE_MATH);                      //該按鈕對應的ID號
	m_button2.ShowWindow(SW_SHOWNORMAL);
	m_button3.Create((CString)"c+課設(直方)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(10, 110, 120, 140),            //按鈕大小
		this,                          //按鈕父指針
		IDC_C_PROGRAM);                      //該按鈕對應的ID號
	m_button3.ShowWindow(SW_SHOWNORMAL);
	m_button4.Create((CString)"大學英語(直方)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(10, 160, 120, 190),            //按鈕大小
		this,                          //按鈕父指針
		IDC_ENGLISH);                      //該按鈕對應的ID號
	m_button4.ShowWindow(SW_SHOWNORMAL);
	m_button5.Create((CString)"大學體育(直方)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(10, 210, 120, 240),            //按鈕大小
		this,                          //按鈕父指針
		IDC_SPORTS);                      //該按鈕對應的ID號
	m_button5.ShowWindow(SW_SHOWNORMAL);
	// TODO:  在此添加您專用的創建代碼

	m_button6.Create((CString)"(折線)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(120, 10, 170, 40),            //按鈕大小
		this,                          //按鈕父指針
		IDC_HIGGER_MATH_LINE);                      //該按鈕對應的ID號
	m_button6.ShowWindow(SW_SHOWNORMAL);
	m_button7.Create((CString)"(折線)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(120, 60, 170, 90),            //按鈕大小
		this,                          //按鈕父指針
		IDC_DISCRETE_MATH_LINE);                      //該按鈕對應的ID號
	m_button7.ShowWindow(SW_SHOWNORMAL);
	m_button8.Create((CString)"(折線)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(120, 110, 170, 140),            //按鈕大小
		this,                          //按鈕父指針
		IDC_C_PROGRAM_LINE);                      //該按鈕對應的ID號
	m_button8.ShowWindow(SW_SHOWNORMAL);
	m_button9.Create((CString)"(折線)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(120,160 , 170, 190),            //按鈕大小
		this,                          //按鈕父指針
		IDC_ENGLISH_LINE);                      //該按鈕對應的ID號
	m_button9.ShowWindow(SW_SHOWNORMAL);
	m_button10.Create((CString)"(折線)",//按鈕標題
		WS_CHILD | WS_VISIBLE | WS_BORDER,//按鈕風格
		CRect(120, 210, 170, 240),            //按鈕大小
		this,                          //按鈕父指針
		IDC_SPORTS_LINE);                      //該按鈕對應的ID號
	m_button10.ShowWindow(SW_SHOWNORMAL);
	return 0;
}
void CMFCApplication1View::OnClickButton_higher_math_show() //高數成績直方圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sHigher_math);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	DrawScore(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::OnClickButton_discrete_math_show()  //離散成績直方圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sDiscrete_math);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	DrawScore(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::OnClickButton_c_program_show()  //C++成績直方圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sC_program);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	DrawScore(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::OnClickButton_english_show() //英語成績直方圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sEnglish);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	DrawScore(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::OnClickButton_sports_show()//體育成績直方圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sSports);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	DrawScore(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::Drawlist(CDC* pDC, int* fScore, int nNum)//畫折線圖
{ 
	// fScore是成績數組指針,nNum是學生人數
	int nScoreNum[] = { 0, 0, 0, 0, 0 };  // 各成績段的人數的初 始值 
	// 下面是用來統計各分數段的人數   
	for (int 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 (int 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]);
	}
}
void CMFCApplication1View::OnClickButton_higher_math_listshow()//高數成績折線圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sHigher_math);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	Drawlist(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::OnClickButton_discrete_math_listshow()//離散成績折線圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sDiscrete_math);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	Drawlist(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::OnClickButton_c_program_listshow()//c++課設成績折線圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sC_program);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	Drawlist(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::OnClickButton_english_listshow()//英語成績折線圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sEnglish);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	Drawlist(GetDC(), m_Num, i);
	file.Close();
}
void CMFCApplication1View::OnClickButton_sports_listshow()//體育成績折線圖控件按鈕對應函數
{
	CFile file;
	if (!file.Open("e://打編碼//MFC//MFC課程設計-學生成績管理系統//MFC課設-學生成績管理系統//Debug//studentfile.dat", CFile::modeReadWrite | CFile::shareDenyNone))
	{
		AfxMessageBox("文件無法打開,無法畫圖!");
		return;
	}
	Student u;
	int i = 0;
	while (file.Read(&u, sizeof(u)) == sizeof(u))
	{
		m_Num[i] = _ttoi((CString)u.sSports);
		i++;
	}
	InvalidateRect(NULL);
	UpdateWindow();
	Drawlist(GetDC(), m_Num, i);
	file.Close();
}

六.實驗中的問題和提高

這個學生成績管理系統中的安全措施並不完善,整個軟件也沒有加殼,以至於這個軟件可以直接被脫殼並找出管理員的登錄賬號和密碼,我目前的能力水平有限,還不能對軟件進行加殼加密操作。

這個學生成績管理系統的用戶界面還不是很好看,使用的方面和一般的登錄界面還是有點違和感。

七、總結心得

(1)剛開始的課設製作的時候,出現了很多變量的設置,變量一多,就容易搞混,後來,我統一使用了微軟標準命名法進行控件和窗口ID以及函數,類,變量的命名。這樣在多個窗口的界面開發的過程中才不容易搞混。

(2)在修改文件內容的時候,我想使用file.Seek(-sizeof(u),CFile:: current)進行寫指針向前移動,但是出現了內存溢出的問題。我查不出問題出現在那裏,後來使用了SeekToBegin()

和file.Seek(i*sizeof(u),CFile:: current)才解決問題,可以在學生成績的存儲文件直接進行覆蓋修改。

(3)之前學會了GetDlgItemText()的用法,後來在MFC類庫中查詢到還有SetDlgItemText()的用法,可以直接在編輯框控件中提取信息,而不用設置變量。

(4)在RadioButton控件的使用中,我不知道如何提取按鍵和設置按鍵的信息,後來在網上查到GetCheckedRadioButton(IDC,IDC)和CheckRadioButton(IDC,IDC,IDC)這兩個函數才解決問題。

(5)這個學生成績管理系統的設置,比原本的實驗要求高出了很多。我添加了登錄管理系統在裏面。這個學生管理系統即使面對教師的,也是面對學生的。學生可以快速查詢自己的成績,而教師還能添加,刪除和修改學生的成績,而學生和老師賬戶可以通過管理員賬號添加,刪除,和修改。

(6)我在排序中重新定義了六種不同對象比較大小的方法,然後調用STL中的快排函數實行快排。與一般的冒泡之類的排序方法不同的是,快排是通過不斷二分插入的方法進行排序的,時間複雜度爲nlogn,大大節省了排序時間。

(7)由於我是在一個單文檔中通過按鈕消息映射繪製五種直方圖和五種折線圖。在清空界面的時候,我調用了InvalidateRect(NULL)這個函數實行清空操作,但是卻出現了連自己將要繪製的圖形也清空了的現象,後來添加了UpdateWindow()這個函數才得以解決。

(8)在運用單文檔讀取文件信息繪製直方圖和折線圖的時候,要細心修改自己設置的矩形和頂點的參數,以及移動時的參數,使得繪圖界面美觀整齊。

(9)在學生管理系統中,我設置了統計分析這個控件,調用了ShellExecute這個函數,然後這個函數可以調用我畫圖的exe文件,因此,我可以在學生管理系統中直接顯示學生成績的直方圖和折線圖。

(10)大總結:通過對學生成績管理系統的可視化編程,瞭解了開發一個實際應用程序的步驟,同時學會使用開發工具實現界面友好的應用程序。通過本實驗,掌握如何運用面向對象技術對具體的應用系統進行分析和設計。瞭解了MFC類的層次結構及主要類的用法,掌握使用MFC和嚮導來編寫Windows應用程序。明白了控件是Windows圖形用戶界面的主要組成部分之一,掌握靜態控件、按鈕、流動條、編輯框、列表框、組合框和對話框的創建、消息發送和控件控制的基本用法。看着同學們不斷的完成自己的課設,我還是堅持將這個學生成績管理系統做的更好,通過加入登錄和權限限制,讓它不僅能服務與老師,同時也能運用於學生,並實行五門成績的管理和統計繪圖。在不斷地網上查詢資料和在類庫中瞭解函數的方法,才終於完成了這個學生成績管理系統。

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章