1. 程式人生 > >MFC編寫個簡單學生管理資訊程式

MFC編寫個簡單學生管理資訊程式

這個應用參考了許多部落格然後自己彙總在編寫而成功能大體完善的應用。


大體框架如圖

附上核心程式碼

// Student_sys_YYYDlg.h : 標頭檔案
//

#pragma once
#include "afxwin.h"
#include "afxcmn.h"


// CStudent_sys_YYYDlg 對話方塊
class CStudent_sys_YYYDlg : public CDialogEx
{
// 構造
public:
	CStudent_sys_YYYDlg(CWnd* pParent = NULL);	// 標準建構函式

// 對話方塊資料
	enum { IDD = IDD_STUDENT_SYS_YYY_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支援


// 實現
protected:
	HICON m_hIcon;

	// 生成的訊息對映函式
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnEnChangeEdit1();
	afx_msg void OnBnClickedChange();
	CButton m_add;
	int age;
	CButton m_change;
	CButton m_del;
	CListCtrl m_list;
	CString m_name;
	CButton m_save;
	int m_sex;
	afx_msg void OnBnClickedRadio1();
	afx_msg void OnBnClickedRadio2();
	afx_msg void OnBnClickedAdd();
	afx_msg void OnBnClickedButton5();
	afx_msg void OnBnClickedOk();
	afx_msg void OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult);
	CString m_num;
	CString m_scoreC;
	CString m_scoreM;
	afx_msg void OnBnClickedDel();
	afx_msg void OnBnClickedSave();

	int ExportToTXT(CString& strFilePath);   //定義轉化為txt檔案的函式
	CButton m_load;
	afx_msg void OnBnClickedLoad();
	afx_msg void OnEnChangeAge();
	afx_msg void OnEnChangeName();
	afx_msg void OnEnChangeNum();
	afx_msg void OnBnClickedShow();
	CButton m_show;
	afx_msg void OnColumnclickList(NMHDR *pNMHDR, LRESULT *pResult);
};

//////////////////定義學生類
class student
{
public:
	CString namee;
	CString agee;
	CString sexx;
	CString cc;
	CString mathh;
	CString numm;
};
class Management
{
public:
	CString addd[100];
	CString dell[100];
	CString sort[100];

};

// Student_sys_YYYDlg.cpp : 實現檔案
//

#include "stdafx.h"
#include "Student_sys_YYY.h"
#include "Student_sys_YYYDlg.h"
#include "afxdialogex.h"
#include 
#include 
using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CStudent_sys_YYYDlg 對話方塊



CStudent_sys_YYYDlg::CStudent_sys_YYYDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CStudent_sys_YYYDlg::IDD, pParent)
	, age(0)
	, m_name(_T(""))
	, m_sex(0)
	, m_num(_T(""))
	, m_scoreC(_T(""))
	, m_scoreM(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CStudent_sys_YYYDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_ADD, m_add);
	DDX_Text(pDX, IDC_AGE, age);
	DDX_Control(pDX, IDC_CHANGE, m_change);
	DDX_Control(pDX, IDC_DEL, m_del);
	DDX_Control(pDX, IDC_LIST, m_list);
	DDX_Text(pDX, IDC_NAME, m_name);
	DDX_Control(pDX, IDC_SAVE, m_save);
	DDX_Text(pDX, IDC_NUM, m_num);
	DDX_Text(pDX, IDC_SCORE_C, m_scoreC);
	DDX_Text(pDX, IDC_SCORE_M, m_scoreM);
	DDX_Control(pDX, IDC_LOAD, m_load);
	DDX_Control(pDX, IDC_Show, m_show);
	
}

BEGIN_MESSAGE_MAP(CStudent_sys_YYYDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
//	ON_EN_CHANGE(IDC_EDIT1, &CStudent_sys_YYYDlg::OnEnChangeEdit1)
	ON_BN_CLICKED(IDC_CHANGE, &CStudent_sys_YYYDlg::OnBnClickedChange)
	ON_BN_CLICKED(IDC_RADIO1, &CStudent_sys_YYYDlg::OnBnClickedRadio1)
	ON_BN_CLICKED(IDC_RADIO2, &CStudent_sys_YYYDlg::OnBnClickedRadio2)
	ON_BN_CLICKED(IDC_ADD, &CStudent_sys_YYYDlg::OnBnClickedAdd)
//	ON_BN_CLICKED(IDC_BUTTON5, &CStudent_sys_YYYDlg::OnBnClickedButton5)
	ON_BN_CLICKED(IDOK, &CStudent_sys_YYYDlg::OnBnClickedOk)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, &CStudent_sys_YYYDlg::OnLvnItemchangedList)
	ON_BN_CLICKED(IDC_DEL, &CStudent_sys_YYYDlg::OnBnClickedDel)
	ON_BN_CLICKED(IDC_SAVE, &CStudent_sys_YYYDlg::OnBnClickedSave)
	ON_BN_CLICKED(IDC_LOAD, &CStudent_sys_YYYDlg::OnBnClickedLoad)
	ON_EN_CHANGE(IDC_AGE, &CStudent_sys_YYYDlg::OnEnChangeAge)
	ON_EN_CHANGE(IDC_NAME, &CStudent_sys_YYYDlg::OnEnChangeName)
	ON_EN_CHANGE(IDC_NUM, &CStudent_sys_YYYDlg::OnEnChangeNum)
	ON_BN_CLICKED(IDC_Show, &CStudent_sys_YYYDlg::OnBnClickedShow)
	
	ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST, &CStudent_sys_YYYDlg::OnColumnclickList)
END_MESSAGE_MAP()


	// 設定此對話方塊的圖示。當應用程式主視窗不是對話方塊時,框架將自動
	//  執行此操作
	SetIcon(m_hIcon, TRUE);			// 設定大圖示
	SetIcon(m_hIcon, FALSE);		// 設定小圖示

	// TODO: 在此新增額外的初始化程式碼                                       //給列表框標題附上文字
	m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); //列表檢視控制元件新增全行選中和柵格風格
	m_list.InsertColumn(0,_T("姓名"),LVCFMT_CENTER,40,0);
	m_list.InsertColumn(1,_T("年齡"),LVCFMT_CENTER,40,1);
	m_list.InsertColumn(2,_T("性別"),LVCFMT_CENTER,40,2);
	m_list.InsertColumn(3,_T("C++"),LVCFMT_CENTER,40,3);
	m_list.InsertColumn(4,_T("數學"),LVCFMT_CENTER,40,4);
	m_list.InsertColumn(5,_T("學號"),LVCFMT_CENTER,100,5);
	return TRUE;  // 除非將焦點設定到控制元件,否則返回 TRUE
}



void CStudent_sys_YYYDlg::OnBnClickedChange()               // 修改按鈕的功能
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	CListCtrl *plist=(CListCtrl *)GetDlgItem(IDC_LIST);//獲取list控制元件IDC_LIST的指標
	//這裡獲取滑鼠選取的位置
	//若沒有任何選擇,這兩行函式得出的nSel為-1,反之,nSel為現在選的行數
	POSITION pos=plist->GetFirstSelectedItemPosition();
	int nSel=plist->GetNextSelectedItem(pos);
	if(nSel<0)
	{
		MessageBox(_T("請選中要修改的項!"),MB_OK);
	}
	else
	{
		//,_T("修改確認"),MB_OKCANCEL);//後面的引數是新增確定按鈕
		if(AfxMessageBox(_T("確認修改?"),MB_YESNO)==IDYES)
		{
		  CString str;
		   //把現在的值替換被選擇那行的第0項,以此類推
		  GetDlgItemText(IDC_NAME,str);
		  plist->SetItemText(nSel,0,str);
		  GetDlgItemText(IDC_AGE,str);
		  plist->SetItemText(nSel,1,str);
		  if(m_sex==0)
		    { 
			   GetDlgItemText(IDC_RADIO1,str);
		       plist->SetItemText(nSel,2,str);
		    }
		  else if(m_sex==1)
		    {
			   GetDlgItemText(IDC_RADIO2,str);
		       plist->SetItemText(nSel,2,str);
		    }
	      GetDlgItemText(IDC_SCORE_C,str);
		  plist->SetItemText(nSel,3,str);
		  GetDlgItemText(IDC_SCORE_M,str);
		  plist->SetItemText(nSel,4,str);
		   GetDlgItemText(IDC_NUM,str);
		  plist->SetItemText(nSel,5,str);


		}
	
	}

}


void CStudent_sys_YYYDlg::OnBnClickedRadio1()     //男
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	m_sex=0;
}


void CStudent_sys_YYYDlg::OnBnClickedRadio2()     //女
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	m_sex=1;
}


void CStudent_sys_YYYDlg::OnBnClickedAdd()                   //錄入資料  (核心)
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	UpdateData(true);
	int i=0;
	CString sex;
	if(m_sex==0)
		sex="男";
	else if(m_sex==1)
		sex="女";

      //型別轉化是道檻
	  // CString a,b,c,d;
	    CString a;
		a.Format(_T("%d"),age);
		//c.Format(_T("%f"),m_scoreC);
		//d.Format(_T("%f"),m_scoreM);
		m_list.InsertItem(i,m_name);
		m_list.SetItemText(i,1,a);
		m_list.SetItemText(i,2,sex);
		m_list.SetItemText(i,3,m_scoreC);
		m_list.SetItemText(i,4,m_scoreM);
		m_list.SetItemText(i,5,m_num);
	

	MessageBox(_T("新增成功!"));

	UpdateData(false);

    i++;
}


void CStudent_sys_YYYDlg::OnBnClickedButton5()
{
	// TODO: 在此新增控制元件通知處理程式程式碼
}


void CStudent_sys_YYYDlg::OnBnClickedOk()
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	CDialogEx::OnOK();
}


void CStudent_sys_YYYDlg::OnLvnItemchangedList(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
	
		*pResult = 0;
	// TODO: 在此新增控制元件通知處理程式程式碼
	*pResult = 0;
}


void CStudent_sys_YYYDlg::OnBnClickedDel()      //刪除按鈕的功能
{
	// TODO: 在此新增控制元件通知處理程式程式碼  
	POSITION pos=m_list.GetFirstSelectedItemPosition();//得出
	if (pos==NULL)
	{
	  return;
	} 
	else
	{
	  while(pos)
	  {
		      int nItem = m_list.GetNextSelectedItem(pos);
			      m_list.DeleteItem(nItem);
	  }
	}
	
}

int CStudent_sys_YYYDlg::ExportToTXT(CString & strFilePath)
{
	USES_CONVERSION;

	CFile mytxtFile;
	CString strCaption,strMsg;

	if(!mytxtFile.Open(strFilePath,CFile::modeCreate|CFile::modeReadWrite))
	{   
		MessageBox(_T("無法開啟"));
		return 0;
	}

	//計算列的寬度
	int width[6]={0};
	int i=0,j=0,nLen=0;
	int nCount=m_list.GetItemCount();

	//構造格式化字串
	char format[512]={0};
	char buf[1024]={0};

	CString str0,str1,str2,str3,str4,str5;

	str0.LoadString(IDC_NAME);//名字
	width[0]=strlen(T2A(str0));

	str1.LoadString(IDC_AGE);//年齡
	width[1]=strlen(T2A(str1));

	if(m_sex==0)   //性別
	{
		str2.LoadString(IDC_RADIO1);
		width[2]=strlen(T2A(str2));
	}
	else if(m_sex==1)
	{
		str2.LoadString(IDC_RADIO2);
		width[2]=strlen(T2A(str2));
	}

	str3.LoadString(IDC_SCORE_C);//c++分數
	width[3]=strlen(T2A(str3));

	str4.LoadString(IDC_SCORE_M);//數學
	width[4]=strlen(T2A(str4));

	str5.LoadString(IDC_NUM); //學號
	width[5]=strlen(T2A(str5));

	for(i=0;i<6;i++)
	{
	   for(j=0;jwidth[i])
			   width[i]=nLen;
	   }
	   //多點間隔
	   //width[i]+=10;
	
	}

	//format
	sprintf_s(format,"%%-%ds %%-%ds %%-%ds %%-%ds %%-%ds %%-%ds \r\n"
		     ,width[0],width[1],width[2],width[3],width[4],width[5]);

	//列印列名
	//sprintf_s(buf,format,T2A(str0),T2A(str1),T2A(str2),T2A(str3)
		      // ,T2A(str4),T2A(str5));
	mytxtFile.Write(buf,strlen(buf));

	for(i=0;iDoModal()==IDOK)//假如點選對話方塊的確定按鈕
	{
		strPath=pFile->GetPathName();//得到開啟檔案的路徑
	}
	else
	{
		return;
	}
	
	//得到檔案路徑strPath之後,按路徑將檔案讀入字串陣列變數strFile
	CStdioFile file;
	CString strLine,temp;
	CStringArray strFile;
	int count=m_list.GetItemCount();
    int i=0;//列表行號
	setlocale(LC_CTYPE,("chs"));  //重要函式,能夠將文字中文資料返回而不生成亂碼

	//CString str0,str1,str2,str3,str4,str5;
	student stu; //定義學生變數,輸入資訊
	if(!file.Open(strPath,CFile::modeRead))
      {
		temp.Format(_T("缺少檔案%s!"),strPath);
		AfxMessageBox(temp);
		return ;
	   }
	    
	  while( file.ReadString(strLine))
	   {
		   AfxExtractSubString(stu.namee,strLine,0,'-');
		   AfxExtractSubString(stu.agee,strLine,1,'-');
		   AfxExtractSubString(stu.sexx,strLine,2,'-');
		   AfxExtractSubString(stu.cc,strLine,3,'-');
		   AfxExtractSubString(stu.mathh,strLine,4,'-');
		   AfxExtractSubString(stu.numm,strLine,5,'-');

		   m_list.InsertItem(count,stu.namee);
		   m_list.SetItemText(count,1,stu.agee);
		   m_list.SetItemText(count,2,stu.sexx);
		   m_list.SetItemText(count,3,stu.cc);
		   m_list.SetItemText(count,4,stu.mathh);
		   m_list.SetItemText(count,5,stu.numm);
		      
	    }
	  
	
	file.Close();

}

void CStudent_sys_YYYDlg::OnBnClickedShow()          //展示
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	const wchar_t *str1=L"open";
	const wchar_t *str2=L"E:\\成績分佈圖\\Debug\\成績分佈圖.exe";
	ShellExecute(NULL,str1,str2,NULL,NULL,SW_SHOWNORMAL);

}



///////////////////////////////實現ListCrtl點選列頭排序
 int sort_column; //記錄點選的列
 bool method;  //記錄比較方法

//比較函式  (回撥函式)
static int CALLBACK MyCompareProc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)
{
   //從引數中提取所需比較lc的兩行資料
	 int row1=(int)lParam1;
	 int row2=(int)lParam2;
	CListCtrl *lc=(CListCtrl*)lParamSort;
	CString lp1=lc->GetItemText(lParam1,sort_column);
	CString lp2=lc->GetItemText(lParam2,sort_column);
	//比較,對不同的列,不同比較,注意記錄前一次排序方向,下一次要相反排序
	if(sort_column<2)
	{
		//int型比較
		int a=_wtoi(lp1.GetBuffer());
		int b=_wtoi(lp2.GetBuffer());
		//int a=_atoi(lp1);
		//int b=_atoi(lp2);
		if(method)
			return a-b;
		else
			return b-a;
	}
	else 
	{
		//文字型比較
		if(method)
			return lp1.CompareNoCase(lp2);
		else 
			return lp2.CompareNoCase(lp1);
	}
	return 0;

}

void CStudent_sys_YYYDlg::OnColumnclickList(NMHDR *pNMHDR, LRESULT *pResult)  //點選ListCrtl控制元件頭的訊息響應
{
	LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR);
	
		
	// TODO: 在此新增控制元件通知處理程式程式碼
		sort_column=pNMLV->iSubItem; //點選的列
		int count=m_list.GetItemCount();

		for(int i=0;i


對映變數的圖




由於我程式是對話方塊+單文件的。(點選成績分佈圖可以彈出單文件,即顯示成績的直方圖和折線圖)

怎麼可以弄成這效果。只需簡單的3行程式碼,即成績分佈圖按鈕中的函式

void CStudent_sys_YYYDlg::OnBnClickedShow()          //展示
{
// TODO: 在此新增控制元件通知處理程式程式碼
const wchar_t *str1=L"open";
const wchar_t *str2=L"E:\\成績分佈圖\\Debug\\成績分佈圖.exe";//自己寫路徑,注意要用\\雙斜線

ShellExecute(NULL,str1,str2,NULL,NULL,SW_SHOWNORMAL);
}


附上單文件的程式碼:

//標頭檔案

 

///////////////////自定義類

class student

{

public:

    CString name[100];

    CString age[100];

    CString sex[100];

    CString num[100];

    CString C[100];

    CString M[100];

 

 

};


//=============================================宣告根據成績繪製直方圖的函式
#include 


static int c_num[4]={0,0,0,0};//分為4個階段
static int number=0;//學生人數
void C成績分佈圖View::OnDraw(CDC* pDC)
{
	C成績分佈圖Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此處為本機資料新增繪製程式碼
	CFileDialog *pFile;
	CString strPath;
	//得到檔案路徑
    pFile = new CFileDialog(TRUE,_T("txt"),NULL,OFN_FILEMUSTEXIST |OFN_HIDEREADONLY
			                ,_T("檔案型別(*.txt)|*.txt|所有檔案(*.*)|*.*|")); 
	if(pFile->DoModal()==IDOK)
	{
		strPath=pFile->GetPathName();
	}
	else 
		return;
	CStringArray strFile;
    CStdioFile file; 
	file.Open(strPath,CFile::modeRead);
    CString strLine;  
	setlocale(LC_CTYPE,("chs"));  //重要函式,能夠將文字中文資料返回而不生成亂碼
	student stu;//定義一個學生變數
	
	int CC,MM;
	CString str0,str1,str2,str3,str4,str5;
	while (file.ReadString(strLine))  
	{
		//讀取並處理txt檔案中的資料
	       number++;
		   AfxExtractSubString(str0,strLine,0,'-');
		   AfxExtractSubString(str1,strLine,1,'-');
		   AfxExtractSubString(str2,strLine,2,'-');
		   AfxExtractSubString(str3,strLine,3,'-');
		   AfxExtractSubString(str4,strLine,4,'-');
		   AfxExtractSubString(str5,strLine,5,'-');
		  
		   CC=_ttoi(str3);
		   MM=_ttoi(str4);

		   //用於統計各階段的人數
		   if(CC>90)
			   c_num[3]++;
		   if(CC<=90&&CC>80)
			   c_num[2]++;
		   if(CC<=80&&CC>70)
			   c_num[1]++;
		   if(CC<=70)
			   c_num[0]++;
		}	
	
	pDC->MoveTo(420,193);
	pDC->LineTo(420,13);
	pDC->LineTo(425,18);
	pDC->MoveTo(420,13);
	pDC->LineTo(415,18);
	pDC->TextOut(430,13,_T("人數"));

	pDC->MoveTo(400,173);
	pDC->LineTo(640,173);
	pDC->LineTo(635,168);
	pDC->MoveTo(640,173);
	pDC->LineTo(635,178);
	pDC->TextOut(650,173,_T("成績/分"));

	int i=160/number;
	//畫直方圖
	pDC->Rectangle(430,173-i*c_num[0],480,173);
	pDC->Rectangle(480,173-i*c_num[1],530,173);
	pDC->Rectangle(530,173-i*c_num[2],580,173);
	pDC->Rectangle(580,173-i*c_num[3],630,173);

	//折線圖
	CPen pen;
	pen.CreatePen(PS_SOLID,3,RGB(255,0,0));
	CPen* oldpen=pDC->SelectObject(&pen);
	
	pDC->MoveTo(450,173-i*c_num[0]);
	pDC->LineTo(505,173-i*c_num[1]);
	pDC->LineTo(560,173-i*c_num[2]);
	pDC->LineTo(615,173-i*c_num[3]);

	CPen pen1;
	pen1.CreatePen(PS_SOLID,0,RGB(0,0,200));
	CPen* newpen=pDC->SelectObject(&pen1);

	CString aaa,bbb,ccc,ddd;
	int aa,bb,cc,dd;
	aa=c_num[0];
	bb=c_num[1];
	cc=c_num[2];
	dd=c_num[3];
	aaa.Format(_T("%d"),aa);
	bbb.Format(_T("%d"),bb);
	ccc.Format(_T("%d"),cc);
	ddd.Format(_T("%d"),dd);
	pDC->TextOut(450,173-i*c_num[0]-20,aaa);
	pDC->TextOut(505,173-i*c_num[1]-20,bbb);
	pDC->TextOut(560,173-i*c_num[2]-20,ccc);
	pDC->TextOut(615,173-i*c_num[3]-20,ddd);

	pDC->TextOut(430,183,_T("<70"));
	pDC->TextOut(485,183,_T("70~80"));
	pDC->TextOut(540,183,_T("80~90"));
	pDC->TextOut(595,183,_T(">90"));

	pDC->TextOut(450,210,_T("成績分佈直方圖&折線圖"));
	


	file.Close();

}




----------------------------------------------------------------------------------------------------- 附上一些參考資料: http://blog.csdn.net/lovton/article/details/6527208      ( MFC ListControl用法

http://blog.csdn.net/abidepan/article/details/8266028     (MFC學習之 將 list 表裡的資訊寫入.txt文字 和 .xls EXCEL 檔案中)

http://blog.csdn.net/jilong17/article/details/6943755    (MFC之MessageBox用法)

http://blog.csdn.net/yongh701/article/details/42404619  (【mfc】學生資訊管理,實現List控制元件節點的增刪改查)

http://blog.csdn.net/zwgdft/article/details/7565331   (MFC總結之CListCtrl用法及技巧(二))

http://blog.csdn.net/zwgdft/article/details/7560592    (MFC總結之CListCtrl用法及技巧(一))