实现的目标:
由于图形能直观地反映各种数据的变化。某班某课程的学生成绩分布图,它是一个直方图,用来依次反映<60、60~69、70~89 以及>90各分数段中的人数,希望通过编程实现这样的成绩分布直方图。
下面进行操作:启动 VC++6.0 创建一个默认的单文档应用程序 Ex_Draw,找到CEx DrawView::OnDraw,在 CEx DrawView::OnDraw 中添加下列绘制代码。
若在Class View页面双击CEx_DrawView后仍找不到,可尝试下面的方法:
添加的代码如下:
【提醒:在此基础进行修改时要特别注意相关函数字母的大小写,报错主要在这个地方】
void CEx_DrawView::OnDraw(CDC* pDC)
{
CEx_DrawDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int nScore[]={66, 82, 79, 74, 86, 82, 67, 60, 45, 44, 77, 98, 65, 90, 66, 76, 66, 62, 63,
84, 97, 43, 67, 57, 60, 60, 71, 74, 60, 72, 81, 69, 79, 91, 69, 71, 81};//原始成绩int
int nNum[]={0, 0, 0, 0, 0}; //各成绩段的人数的初始值
for(int i=0; i<sizeof(nScore)/sizeof(int); i++)
{
int nSeg = nScore[i]/10; //取数的“十”位上的值
if (nSeg<6)
nSeg=5; //<60 分
if(nSeg==10)
nSeg = 9; //当为 100 分,算为>90 分数段
nNum[nSeg-5]++; //各分数段计算
}
int nSegNum = sizeof (nNum)/sizeof(int); //计算有多少个分数段
//求分数段上最大的数
int nNumMax = nNum[0];
for(i=1; i<nSegNum;i++)
if(nNumMax<nNum[i])nNumMax = nNum[i];
CRect rc;
GetClientRect(rc); //注意大小写
rc.DeflateRect(40, 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);
CRect rcSeg(rc);
rcSeg.right = rcSeg.left+nSegWidth; //使每段的距形宽等于 nSegWidth
for(i = 0; i<nSegNum; i++){
//保证相邻的矩形填充样式不相同
if(i&2)pDC->SelectObject(&brush2);
else pDC->SelectObject(&brush1);
rcSeg.top = rcSeg.bottom-nNum[i]*nSegHeight-2; //计算每段矩形的高度
pDC->Rectangle(rcSeg);
if(nNum[i]>0)
{
CString str;
str.Format("%d人",nNum[i]);
pDC->DrawText(str, rcSeg, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
rcSeg.OffsetRect(nSegWidth, 0); //右移矩形
}
}
pDC->SelectObject(oldBrush); //恢复原来的画刷属性
pDC->SelectObject(oldPen); //恢复原来的画笔属性
}
保存编译无误后,运行即可,运行结果如下:
希望可以帮到你。