(1)、设计一个学生类Student,包括数据成员:姓名、学号、二门课程(面向对象程序设计、高等数学)的成绩。
(2)、创建一个管理学生的类Management,包括实现学生的数据的增加、删除、修改、按课程成绩排序、保存学生数据到文件及加载文件中的数据等功能。
(3)、创建一个基于对话框的MFC应用程序,程序窗口的标题上有你姓名、学号和应用程序名称。使用(1)和(2)中的类,实现对学生信息和成绩的输入和管理。
(4)、创建一个单文档的MFC应用程序,读取(3)中保存的文件中的学生成绩,分别用直方图和折线方式显示所有学生某课程的成绩分布图。
效果如图:
//student.h
#pragma once
#include<iostream>
using namespace std;
class student
{
public:
student();
student(int id , const char* name , float oop , float math ,char sex,int age,const char*adress );
~student();
int GetId() const { return mId; }//获取学号
void SetId(int id) { mId = id; }//修改学号
const char* GetName() const { return mName; }//获取姓名
void SetName(const char* name) { strcpy_s(mName, 31, name); }//修改姓名
float GetOop() const { return mOop; }//获取c++成绩
void SetOop(float oop) { mOop = oop; }//修改c++成绩
float GetMath() const { return mMath; }//获取数学成绩
void SetMath(float math) { mMath = math; }//修改数学成绩
char Getsex() { return msex; }//获取性别
void Setsex(char sex) { msex = sex; }//修改性别
int Getage() { return mage; }//获取年龄
void Setage(int age) { mage = age; }//修改年龄
const char* Getadress() const { return madress; }//获取地址
void Seadress(const char* adress) { strcpy_s(madress, 41, adress); }//修改地址
friend ostream& operator<<(ostream& os, const student& st);//输出学生信息
friend istream& operator>>(istream& is, student& st);//输入学生信息
friend bool LessOop(const student* st1, const student* st2);//判断c++成绩高低
friend bool LessMath(const student* st1, const student* st2);//判断数学成绩高低
private:
int mId;//学号
char mName[31];//姓名
float mOop;//c++成绩
float mMath;//数学成绩
char msex;//性别
int mage;//年龄
char madress[40];//地址
};
//student.cpp
#include "stdafx.h"
#include "student.h"
student::student(int id, const char* name, float oop, float math, char sex,int age, const char*adress)//初始化
:mId(id), mOop(oop), mMath(math),msex(sex),mage(age)
{
strcpy_s(mName, name);
strcpy_s(madress,adress);
}
student::student()
{
}
student::~student()
{
}
ostream& operator<<(ostream& os, const student& st)//输入学生信息
{
os << st.mId << '\t' << st.mName << '\t';
os << st.mOop << '\t' << st.mMath << '\t';
os << st.msex << '\t' << st.mage << '\t' << st.madress;
return os;
}
istream& operator>>(istream& is, student& st)//输出学生信息
{
is >> st.mId >> st.mName >> st.mOop >> st.mMath>>st.msex>>st.mage>>st.madress;
return is;
}
bool LessOop(const student* st1, const student* st2)//判断c++成绩高低
{
return st1->mOop < st2->mOop;
}
bool LessMath(const student* st1, const student* st2)//判断数学成绩高低
{
return st1->mMath < st2->mMath;
}
//Managerment.h
#pragma once
#include "student.h"
#include <list>
class managerment
{
public:
managerment();
~managerment();
list<student*>* GetStudents() { return &mstudents; }//student类引入
void Clear();//清除内存
void Add(student *pSt);//添加数据
student *Delete(int id);//删除数据
void Modify(int id, const char* name, float oop, float math, char sex, int age, const char*adress);//修改数据
void oopsort();//c++排序
void mathsort();//数学排序
bool Save(const char*filename);//保存文件
bool Open(const char*filename);//打开文件
private:
list<student*> mstudents;//建立链表
};
//managerment.cpp
#include "stdafx.h"
#include "managerment.h"
#include <fstream>
managerment::managerment()
{
}
managerment::~managerment()
{
for (auto iter = mstudents.begin(); iter != mstudents.end(); ++iter)
{
delete *iter;
}
}
void managerment::Clear()
{
for (auto iter = mstudents.begin(); iter != mstudents.end(); ++iter)
{
delete *iter;
}
mstudents.clear();//清除该数据
}
void managerment::Add(student *pSt)
{
mstudents.push_back(pSt);//链表尾部加入数据
}
student* managerment::Delete(int id)
{
student *pSt = nullptr;
for (auto iter = mstudents.begin(); iter != mstudents.end(); ++iter)//寻找是否有此id
{
if ((*iter)->GetId() == id)
{
pSt = *iter;
break;
}
}
if (pSt != nullptr) mstudents.remove(pSt);//将其删除
return pSt;
}
void managerment::Modify(int id, const char* name, float oop, float math, char sex, int age, const char*adress)
{
student *pSt = nullptr;
for (auto iter = mstudents.begin(); iter != mstudents.end(); ++iter)//寻找id
{
if ((*iter)->GetId() == id)
{
pSt = *iter;
break;
}
}
if (pSt != nullptr)//若能找到对应id
{
pSt->SetName(name);
if (oop >= 0.0) pSt->SetOop(oop);//修改c++成绩
if (math >= 0.0) pSt->SetMath(math);//修改数学成绩
pSt->Setsex(sex);//修改性别
pSt->Setage(age);//修改年龄
pSt->Seadress(adress);//修改地址
}
}
void managerment::oopsort()
{
mstudents.sort(LessOop);//c++成绩排序
}
void managerment::mathsort()
{
mstudents.sort(LessMath);//数学成绩排序
}
bool managerment::Save(const char*filename)
{
ofstream file(filename, ios::out);
if (!file) return false;
file << mstudents.size() << '\n';//文件字符串长度
for (auto iter = mstudents.begin(); iter != mstudents.end(); ++iter)//向文件输入数据
{
file << (**iter) << '\n';
}
file.close();
return true;
}
bool managerment::Open(const char*filename)
{
Clear();
ifstream file(filename, ios::in);
if (!file) return false;
int n = 0;
file >> n;
for (int k = 0; k < n; ++k)//文件内容输入并置于链表后
{
student* pSt = new student();
file >> *pSt;
mstudents.push_back(pSt);
}
file.close();
return true;
}
//Doc.h
#pragma once
#include "managerment.h"
class CMy0601Doc : public CDocument
{
protected: // 仅从序列化创建
CMy0601Doc() noexcept;
DECLARE_DYNCREATE(CMy0601Doc)
managerment mManagerment;
// 特性
public:
managerment *Getmanagerment() { return &mManagerment; }
// 操作
public:
// 重写
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
#ifdef SHARED_HANDLERS
virtual void InitializeSearchContent();
virtual void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds);
#endif // SHARED_HANDLERS
// 实现
public:
virtual ~CMy0601Doc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
#ifdef SHARED_HANDLERS
// 用于为搜索处理程序设置搜索内容的 Helper 函数
void SetSearchContent(const CString& value);
#endif // SHARED_HANDLERS
public:
afx_msg void On32771();//链接对话框
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);//打开文件
virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);//保存文件
};
//Doc.cpp
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMy0601Doc
IMPLEMENT_DYNCREATE(CMy0601Doc, CDocument)
BEGIN_MESSAGE_MAP(CMy0601Doc, CDocument)
ON_COMMAND(ID_32771, &CMy0601Doc::On32771)
END_MESSAGE_MAP()
// CMy0601Doc 构造/析构
CMy0601Doc::CMy0601Doc() noexcept
{
// TODO: 在此添加一次性构造代码
}
CMy0601Doc::~CMy0601Doc()
{
}
BOOL CMy0601Doc::OnNewDocument()//新建文档后初始化
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: 在此添加重新初始化代码
// (SDI 文档将重用该文档)
srand((unsigned int)(time(NULL)));
this->mManagerment.Clear();//先做清除
const int n = 46;
for (int k = 0; k < n; ++k)//利用随机函数对数据初始化
{
int id = 18060000 + rand() % 1000;
char name[7] = { 0 };
char adress[7] = { 0 };
for (int i = 0; i < 6; ++i)
{
name[i] = 'A' + rand() % 26;
adress[i] = 'A' + rand() % 26;
}
char c;
if (k%2==0) c = 'm';
else c = 'w';
auto st = new student(id, name, 40 + rand() % 61, 30 + rand() % 71,c,15+rand()%10,adress);
this->mManagerment.Add(st);//添加进链表
}
this->mManagerment.oopsort();//c++排序
return TRUE;
}
// CMy0601Doc 序列化
void CMy0601Doc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: 在此添加存储代码
}
else
{
// TODO: 在此添加加载代码
}
}
#ifdef SHARED_HANDLERS
// 缩略图的支持
void CMy0601Doc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds)
{
// 修改此代码以绘制文档数据
dc.FillSolidRect(lprcBounds, RGB(255, 255, 255));
CString strText = _T("TODO: implement thumbnail drawing here");
LOGFONT lf;
CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT));
pDefaultGUIFont->GetLogFont(&lf);
lf.lfHeight = 36;
CFont fontDraw;
fontDraw.CreateFontIndirect(&lf);
CFont* pOldFont = dc.SelectObject(&fontDraw);
dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK);
dc.SelectObject(pOldFont);
}
// 搜索处理程序的支持
void CMy0601Doc::InitializeSearchContent()
{
CString strSearchContent;
// 从文档数据设置搜索内容。
// 内容部分应由“;”分隔
// 例如: strSearchContent = _T("point;rectangle;circle;ole object;");
SetSearchContent(strSearchContent);
}
void CMy0601Doc::SetSearchContent(const CString& value)
{
if (value.IsEmpty())
{
RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid);
}
else
{
CMFCFilterChunkValueImpl *pChunk = nullptr;
ATLTRY(pChunk = new CMFCFilterChunkValueImpl);
if (pChunk != nullptr)
{
pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT);
SetChunkValue(pChunk);
}
}
}
#endif // SHARED_HANDLERS
// CMy0601Doc 诊断
#ifdef _DEBUG
void CMy0601Doc::AssertValid() const
{
CDocument::AssertValid();
}
void CMy0601Doc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
// CMy0601Doc 命令
void CMy0601Doc::On32771()//对话框响应
{
// TODO: 在此添加命令处理程序代码
Dlg dlg;
dlg.pDoc = this;
dlg.DoModal();//显示对话框,关闭后返回程序
}
BOOL CMy0601Doc::OnOpenDocument(LPCTSTR lpszPathName)
{
// if (!CDocument::OnOpenDocument(lpszPathName))
// return FALSE;
// TODO: 在此添加您专用的创建代码
return this->mManagerment.Open(lpszPathName);
// return TRUE;
}
BOOL CMy0601Doc::OnSaveDocument(LPCTSTR lpszPathName)
{
// TODO: 在此添加专用代码和/或调用基类
return this->mManagerment.Save(lpszPathName);
// return CDocument::OnSaveDocument(lpszPathName);
}
//View.h
#pragma once
#define IDC_HIGGER_MATH 130
#define IDC_C_PROGRAM 131
#define IDC_HIGGER_MATH_LINE 132
#define IDC_C_PROGRAM_LINE 133
class CMy0601View : public CView
{
protected: // 仅从序列化创建
CMy0601View() noexcept;
DECLARE_DYNCREATE(CMy0601View)
LOGFONT font;
// 特性
public:
CMy0601Doc* GetDocument() const;
CButton m_button1;//数学直方图按钮
CButton m_button2;//数学折线图按钮
CButton m_button3;//c++直方图按钮
CButton m_button4;//c++折线图按钮
// 操作
public:
// 重写
public:
virtual void OnDraw(CDC* pDC); // 重写以绘制该视图
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
void Draw(CDC* pDC,int i);//绘画直方图和折线图
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
void OnClickbutton1();//点击绘画数学成绩直方图
void OnClickbutton2();//点击绘画c++成绩直方图
void OnClickbutton3();//点击绘画数学成绩折线图
void OnClickbutton4();//点击绘画c++成绩折线图
// 实现
public:
virtual ~CMy0601View();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
afx_msg void OnFilePrintPreview();
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);//创建按钮
};
#ifndef _DEBUG // 06 01View.cpp 中的调试版本
inline CMy0601Doc* CMy0601View::GetDocument() const
{ return reinterpret_cast<CMy0601Doc*>(m_pDocument); }
#endif
//View.cpp
#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "06 01.h"
#endif
#include "06 01Doc.h"
#include "06 01View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMy0601View
IMPLEMENT_DYNCREATE(CMy0601View, CView)
BEGIN_MESSAGE_MAP(CMy0601View, CView)
// 标准打印命令
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
ON_WM_CREATE()
ON_WM_RBUTTONUP()
ON_BN_CLICKED(IDC_HIGGER_MATH,OnClickbutton1)
ON_BN_CLICKED(IDC_C_PROGRAM, OnClickbutton2)
ON_BN_CLICKED(IDC_HIGGER_MATH_LINE, OnClickbutton3)
ON_BN_CLICKED(IDC_C_PROGRAM_LINE, OnClickbutton4)
END_MESSAGE_MAP()
// CMy0601View 构造/析构
CMy0601View::CMy0601View() noexcept//初始化字体
{
// TODO: 在此处添加构造代码
//逻辑设备单位高度,>0—上高+下高,<0—上高+下高-内部Leading.
font.lfHeight = 18;
//逻辑设备单位的宽度,等于零选择方形。
font.lfWidth = 0;
//指定文本的基线与设备x轴间的角度,十分之一度为单位。
font.lfEscapement = 0;
//字体的黑体度(0-1000)FW_NORMAL=400,FW_BOLD=700
font.lfWeight = FW_BOLD;
//是否斜体
font.lfItalic = 0;
//是否绘制下划线
font.lfUnderline = 0;
//是否划删除线
font.lfStrikeOut = 0;
//指定每个字符的基线与设备x轴间的角度,十分之一度为单位(NT/2000)。
font.lfOrientation = 0;
//字体的字符集 GB2312_CHARSET
font.lfCharSet = DEFAULT_CHARSET;
//指定匹配字体时的一些偏好。
font.lfOutPrecision = OUT_DEFAULT_PRECIS;
//字符被裁剪时,指定如何裁剪。
font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
//指定图元输出质量。
font.lfQuality = DEFAULT_QUALITY;
//字体间距和族
font.lfPitchAndFamily = DEFAULT_PITCH;
//字体名称
strcpy_s(font.lfFaceName, _T("隶书"));
}
CMy0601View::~CMy0601View()
{
}
BOOL CMy0601View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
return CView::PreCreateWindow(cs);
}
// CMy0601View 绘图
void CMy0601View::OnDraw(CDC* pDC)
{
CMy0601Doc * pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
}
// CMy0601View 打印
BOOL CMy0601View::OnPreparePrinting(CPrintInfo* pInfo)
{
// 默认准备
return DoPreparePrinting(pInfo);
}
void CMy0601View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加额外的打印前进行的初始化过程
}
void CMy0601View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加打印后进行的清理过程
}
// CMy0601View 诊断
#ifdef _DEBUG
void CMy0601View::AssertValid() const
{
CView::AssertValid();
}
void CMy0601View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMy0601Doc* CMy0601View::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy0601Doc)));
return (CMy0601Doc*)m_pDocument;
}
#endif //_DEBUG
// CMy0601View 消息处理程序
int CMy0601View::OnCreate(LPCREATESTRUCT lpCreateStruct)//创建按钮
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
m_button1.Create((CString)"高数直方图",//按钮标题
WS_CHILD | WS_VISIBLE | WS_BORDER,//按钮风格
CRect(10, 10, 120, 50), //按钮大小
this, //按钮父指针
IDC_HIGGER_MATH); //该按钮对应的ID号
m_button1.ShowWindow(SW_SHOWNORMAL);
m_button2.Create((CString)"c++直方图",//按钮标题
WS_CHILD | WS_VISIBLE | WS_BORDER,//按钮风格
CRect(10, 110, 120, 150), //按钮大小
this, //按钮父指针
IDC_C_PROGRAM); //该按钮对应的ID号
m_button2.ShowWindow(SW_SHOWNORMAL);
m_button3.Create((CString)"(折线)",//按钮标题
WS_CHILD | WS_VISIBLE | WS_BORDER,//按钮风格
CRect(120, 10, 180, 50), //按钮大小
this, //按钮父指针
IDC_HIGGER_MATH_LINE); //该按钮对应的ID号
m_button3.ShowWindow(SW_SHOWNORMAL);
m_button4.Create((CString)"(折线)",//按钮标题
WS_CHILD | WS_VISIBLE | WS_BORDER,//按钮风格
CRect(120, 110, 180, 150), //按钮大小
this, //按钮父指针
IDC_C_PROGRAM_LINE); //该按钮对应的ID号
m_button4.ShowWindow(SW_SHOWNORMAL);
// TODO: 在此添加您专用的创建代码
return 0;
}
void CMy0601View::Draw(CDC* pDC ,int i)//绘画直方图和折线图
{
CMy0601Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
int count[2][5] = { {0},{0} };
auto sts = pDoc->Getmanagerment()->GetStudents();
int k = 0;
for (auto iter = sts->begin(); iter != sts->end(); ++iter)//得到各分组的人数
{
auto st = *iter;
float m = st->GetMath();
if (m < 60.0f) ++count[0][0];
else if (m < 70.0f) ++count[0][1];
else if (m < 80.0f) ++count[0][2];
else if (m < 90.0f) ++count[0][3];
else ++count[0][4];
float c = st->GetOop();
if (c < 60.0f) ++count[1][0];
else if (c < 70.0f) ++count[1][1];
else if (c < 80.0f) ++count[1][2];
else if (c < 90.0f) ++count[1][3];
else ++count[1][4];
}
CString msg[2][5];
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 5; ++j)
{
msg[i][j].Format(_T("%d人"), count[i][j]);
}
}
CString s[5] = { _T("<60"),_T("60-69"),_T("70-79"),_T("80-89"),_T("90-100") };//设定添加字符
CFont f;
f.CreateFontIndirect(&font);//设置环境字体
auto oldFont = pDC->SelectObject(&f);
auto color = pDC->SetTextColor(RGB(0, 0, 255));
CRect rect;
this->GetClientRect(&rect);//获取客户区大小
int w = rect.Width(), h = rect.Height();//宽高
int nw = (w -200)/ 5;
int nh = 20;//单位宽度和长度
if (i == 0)//数学直方图
{
pDC->SetBkMode(TRANSPARENT);//设置文字透明背景
CPen pen;
pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
auto oldPen = pDC->SelectObject(&pen);
for (int k = 0; k < 5; ++k)
{
CBrush brush;
if (k % 2 == 0) brush.CreateHatchBrush(2, RGB(0, 0, 255));
else brush.CreateHatchBrush(3, RGB(0, 0, 255));//设置两种填充斜线
auto oldBrush = pDC->SelectObject(&brush);
CRect rt(180 + k * nw,h-50-count[i][k]*nh, 180 + (k+1) * nw, h-50);
pDC->Rectangle(rt);//画条形图
pDC->DrawText(msg[i][k], rt, DT_SINGLELINE | DT_CENTER | DT_VCENTER);//矩形中心写入文字
CRect r(180 + k * nw, h - 50 - count[i][k] * nh, 180 + (k + 1) * nw, h - 50);
pDC->DrawText(s[k], r, DT_SINGLELINE | DT_CENTER);//矩形底部写入文字
}
pDC->TextOutA(140, 50, "数学直方图");//上方显示“数学直方图”
pDC->SelectObject(oldPen);
pDC->SelectObject(oldFont);
}
else if (i == 1)//c++直方图
{
pDC->SetBkMode(TRANSPARENT);//设置文字透明背景
CPen pen;
pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
auto oldPen = pDC->SelectObject(&pen);
for (int k = 0; k < 5; ++k)
{
CBrush brush;
if (k % 2 == 0) brush.CreateHatchBrush(2, RGB(0, 0, 255));
else brush.CreateHatchBrush(3, RGB(0, 0, 255));//设置两种填充斜线
auto oldBrush = pDC->SelectObject(&brush);
CRect rt(180 + k * nw, h - 50 - count[i][k] * nh, 180 + (k + 1) * nw, h - 50);
pDC->Rectangle(rt);//画条形图
pDC->DrawText(msg[i][k], rt, DT_SINGLELINE | DT_CENTER | DT_VCENTER);//矩形中心写入文字
CRect r(180 + k * nw, h - 50 - count[i][k] * nh, 180 + (k + 1) * nw, h - 50);
pDC->DrawText(s[k], r, DT_SINGLELINE | DT_CENTER);//矩形底部写入文字
}
pDC->TextOutA(140, 50, "c++直方图");//上方显示“c++直方图”
pDC->SelectObject(oldPen);
pDC->SelectObject(oldFont);
}
else//折线图
{
pDC->MoveTo(120,h-50);
pDC->LineTo(120,50);//画y轴
pDC->MoveTo(120,h-50);
pDC->LineTo(w - 50, h - 50);//画x轴
if (i == 2)//数学折线图
{
pDC->MoveTo(120,h-50);//原点开始
for (int k = 0; k < 5; k++)
{
pDC->LineTo(120 + (k + 1) * nw, h - 50 - count[i - 2][k] * nh);//起点和终点连接
if (k != 4)
{
pDC->MoveTo(120 + (k + 1)* nw, h - 50 - count[i - 2][k] * nh);//将终点设置为起点
}
pDC->TextOutA(140 + (k + 1)* nw, h - 70 - count[i - 2][k] * nh, msg[i - 2][k]);//显示人数
pDC->TextOutA(140 + (k + 1)* nw, h - 30, s[k]);//显示分数间断
}
pDC->TextOutA(140, 50, "数学折线图");
}
else if (i == 3)//c++折线图
{
pDC->MoveTo(120, h - 50);
for (int k = 0; k < 5; k++)
{
pDC->LineTo(120 + (k + 1) * nw, h - 50 - count[i - 2][k] * nh);//起点和终点连接
if (k != 4)
{
pDC->MoveTo(120 + (k + 1) * nw, h - 50 - count[i - 2][k] * nh);//将终点设置为起点
}
pDC->TextOutA(140 + (k + 1)* nw, h - 70 - count[i - 2][k] * nh, msg[i - 2][k]);//显示人数
pDC->TextOutA(140 + (k + 1)* nw, h - 30, s[k]);//显示分数间断
}
pDC->TextOutA(140, 50, "c++折线图"); //上方显示“c++折线图”
}
}
}
void CMy0601View::OnClickbutton1()
{
InvalidateRect(NULL);//加入线程
UpdateWindow();//立即显示
Draw(GetDC(), 0);//画图
}
void CMy0601View::OnClickbutton2()
{
InvalidateRect(NULL);//加入线程
UpdateWindow();//立即显示
Draw(GetDC(), 1);//画图
}
void CMy0601View::OnClickbutton3()
{
InvalidateRect(NULL);//加入线程
UpdateWindow();//立即显示
Draw(GetDC(), 2);//画图
}
void CMy0601View::OnClickbutton4()
{
InvalidateRect(NULL);//加入线程
UpdateWindow();//立即显示
Draw(GetDC(), 3);//画图
}
//Dlg.h
class CMy0601Doc;
class Dlg : public CDialogEx
{
DECLARE_DYNAMIC(Dlg)
public:
Dlg(CWnd* pParent = nullptr); // 标准构造函数
virtual ~Dlg();
CMy0601Doc *pDoc;
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
int m_id;
CString m_name;
float m_math;
float m_oop;
afx_msg void OnClickedAdd(); //增加响应
afx_msg void OnClickedDelete();//删除响应
afx_msg void OnClickedModify();//修改响应
afx_msg void OnSelchangeList2();//添加后链表响应
virtual BOOL OnInitDialog();//初始化链表
CListBox m_listBox;//列表
int m_age;//年龄
CString m_adress;//地址
BOOL m_sex;//性别
//BOOL m_sex1;
};
//Dlg.cpp
#include "stdafx.h"
#include "06 01.h"
#include "Dlg.h"
#include "afxdialogex.h"
#include"student.h"
#include"06 01Doc.h"
#include<vector>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// Dlg 对话框
IMPLEMENT_DYNAMIC(Dlg, CDialogEx)
Dlg::Dlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIALOG1, pParent)
, m_id(0)
, m_name(_T(""))
, m_math(0)
, m_oop(0)
, m_age(0)
, m_adress(_T(""))
, m_sex(FALSE)
// , m_sex1(FALSE)
{
}
Dlg::~Dlg()
{
}
void Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT2, m_id);
DDX_Text(pDX, IDC_EDIT1, m_name);
DDX_Text(pDX, IDC_EDIT4, m_math);
DDX_Text(pDX, IDC_EDIT6, m_oop);
DDX_Control(pDX, IDC_LIST2, m_listBox);
DDX_Text(pDX, IDC_EDIT3, m_age);
DDX_Text(pDX, IDC_EDIT5, m_adress);
DDX_Radio(pDX, IDC_RADIO1, m_sex);
//DDX_Radio(pDX, IDC_RADIO2, m_sex1);
}
BEGIN_MESSAGE_MAP(Dlg, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON1, &Dlg::OnClickedAdd)
ON_BN_CLICKED(IDC_BUTTON2, &Dlg::OnClickedDelete)
ON_BN_CLICKED(IDC_BUTTON3, &Dlg::OnClickedModify)
ON_LBN_SELCHANGE(IDC_LIST2, &Dlg::OnSelchangeList2)
END_MESSAGE_MAP()
// Dlg 消息处理程序
void Dlg::OnClickedAdd()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);//更新框中数据
char m_sex2;//性别
if (m_sex==TRUE) m_sex2 = 'm';
else m_sex2 = 'w';
student* pSt = new student(m_id, m_name, m_oop, m_math,m_sex2,m_age,m_adress);//创建对象初始化
pDoc->Getmanagerment()->Add(pSt);//添加数据
CString msg;
msg.Format("%d %s %f,%f %c %d %s", m_id, m_name,m_oop, m_math, m_sex2, m_age, m_adress);//将数据转化为CString
m_listBox.AddString(msg);//添加进链表框
m_listBox.SetItemDataPtr(m_listBox.GetCount() - 1, pSt); //将序号与内容关联
}
void Dlg::OnClickedDelete()
{
// TODO: 在此添加控件通知处理程序代码
int index = m_listBox.GetCurSel();//获取鼠标选中项下标
if (index == LB_ERR) return;
student* pSt = (student*)m_listBox.GetItemDataPtr(index);//获取下标成功后返回该指针
pDoc->Getmanagerment()->Delete(pSt->GetId());//删除数据
delete pSt;//释放该内存
m_listBox.DeleteString(index);//删除链表字符
}
void Dlg::OnClickedModify()
{
// TODO: 在此添加控件通知处理程序代码
int index = m_listBox.GetCurSel();//获取鼠标选中项下标
if (index == LB_ERR) return;
student* pSt = (student*)m_listBox.GetItemDataPtr(index);//获取下标成功后返回该指针
UpdateData(TRUE);//更新数据
char m_sex2;//性别
if (m_sex == TRUE) m_sex2 = 'm';
else m_sex2 = 'w';
pSt->SetId(m_id);
pSt->SetName(m_name);
pSt->SetOop(m_oop);
pSt->SetMath(m_math);
pSt->Setage(m_age);
pSt->Setsex(m_sex2);
pSt->Seadress(m_adress);//写入数据
m_listBox.DeleteString(index);//删除原数据
CString msg;
msg.Format("%d %s %f %f %c %d %s", m_id, m_name, m_oop, m_math, m_sex2, m_age, m_adress);
m_listBox.InsertString(index, msg);//链表指定位置插入数据
m_listBox.SetItemDataPtr(index, pSt);//将序号与内容关联
}
void Dlg::OnSelchangeList2()
{
// TODO: 在此添加控件通知处理程序代码
int index = m_listBox.GetCurSel();//获取鼠标选中项下标
if (index == LB_ERR) return;
student* pSt = (student*)m_listBox.GetItemDataPtr(index);
m_id = pSt->GetId();
m_name = pSt->GetName();
m_oop = pSt->GetOop();
m_math = pSt->GetMath();
m_age = pSt->Getage();
m_adress = pSt->Getadress();//获取数据
UpdateData(FALSE);//更新到各个框中
}
BOOL Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
auto sts = pDoc->Getmanagerment()->GetStudents();
for (auto iter = sts->begin(); iter != sts->end(); ++iter)
{
auto st = *iter;
CString temp;
char m_sex2;//性别
if (m_sex == TRUE) m_sex2 = 'm';
else m_sex2 = 'w';
temp.Format("%d %s %f %f %c %d %s", st->GetId(), st->GetName(), st->GetOop(), st->GetMath(),st->Getsex(), st->Getage(), st->Getadress());//转化为字符串
m_listBox.AddString(temp);
m_listBox.SetItemDataPtr(m_listBox.GetCount() - 1, st);//将序号与内容关联
}
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}