用c++的mfc绘制柱状图的方法如下:
1:取GroupBox的区域,并保存四个值 左,上,右,下
//获取屏幕坐标
((CWnd*)GetDlgItem(IDC_STATIC_CHART))->GetWindowRect(rect)
//计算x轴y轴基本单位
int dx = (rect.right-rect.left)/50
int dy = (rect.bottom-rect.top)/80
//转换成对话框坐标
ScreenToClient(rect)
//保存4个值
int L = rect.left,R = rect.right,T = rect.top,B = rect.bottom
GroupBox的区域我忘记标出来了,就在上面图中柱状图那一块
2:获取DC,这一步没什么好说的
CPaintDC dc(this)
3:画X轴,Y轴
//X
dc.MoveTo(L+dx*2,B-dy*3)
dc.LineTo(L+dx*49,B-dy*3)
//最后的那个箭头
dc.MoveTo(L+dx*49,B-dy*3)
dc.LineTo(L+dx*48,B-dy*2)
dc.MoveTo(L+dx*49,B-dy*3)
dc.LineTo(L+dx*48,B-dy*4)
Y轴同理,但是考虑到dx,dy的值不一样,当画Y轴的箭头时,需要交换dx和虚肆dy的位置棚誉差
//纵坐标线 dc.MoveTo(L+dx*2,B-dy*3)
dc.LineTo(L+dx*2,B-dy*77)
dc.MoveTo(L+dx*2,B-dy*77)
//交换了dx,dy的位置
dc.LineTo(L+dx*2-dy,B-dy*77+dx)
dc.MoveTo(L+dx*2,B-dy*77)
//交换了dx,dy的位置
dc.LineTo(L+dx*2+dy,B-dy*77+dx)
绘制完结果如图:
4:画柱状图,这里主要根据前面计算dx,dy时,划分的数量来计算每个柱的宽度,以及柱间的间隔
//第一个柱状体的左下坐标
int x = L+dx*3
int y = B-dy*3
for(int i=0i
CRect rc
rc.left=x+i*dx*9
rc.right=rc.left+dx*7
rc.bottom=y
rc.top=rc.bottom-dy*answer[index][i+1]
//这里把柱状图的信息输出,这里输出的是一个数字,因为要转换成字符串,比较麻烦
//处理了一下,肯定有简洁的处理方式,但是我也懒得去想了,我很懒的
dc.SetBkMode(TRANSPARENT)//设置透明背景,要不然输出文字之后会有一块白,难看
char num[10]
sprintf(num,"%d",answer[index][i+1])
CString strnum(num)
dc.TextOutW((rc.left+rc.right)/2-dx,rc.bottom-dy*(answer[index][i+1]+3),strnum)
//画刷是我之前就定义好的,链皮直接拿来用
dc.FillRect(&rc,brushs+i)
}
维护一个全局变量index来保存当前题号,创建重绘函数updateInfo
void CEnglishReportDlg::updateInfo(){
int count = choose_c[index]
int i
//选项存在,赋值,L是宏命令与TEXT()相同功能
for(i=0i
m_strLable[i] = choose[index][i]
}
//无此选项,置空
for(i<5i++)
m_strLable[i] = L""
m_strTopic = topics[index]
//获取GroupBox区域,并转换成对话框坐标
CRect rect
((CWnd*)GetDlgItem(IDC_STATIC_CHART))->GetWindowRect(rect)
ScreenToClient(rect)
//重绘此区域
InvalidateRect(rect)
//将控件变量更新到前台
UpdateData(FALSE)
}
函数1:响应ListBox的SelChange事件
void CEnglishReportDlg::OnLbnSelchangeListTopic()
{
// TODO: 在此添加控件通知处理程序代码
index = m_listtopic.GetCurSel()
updateInfo()
}
函数2:上一页按钮的Click事件
void CEnglishReportDlg::OnBnClickedButtonPre()
{
// TODO: 在此添加控件通知处理程序代码
if(index>0)
index--
updateInfo()
m_listtopic.SetCurSel(index)
}
函数3:下一页按钮的Clicl事件
void CEnglishReportDlg::OnBnClickedButtonNext()
{
// TODO: 在此添加控件通知处理程序代码
if(index<19)
index++
updateInfo()
m_listtopic.SetCurSel(index)
}
至此基本的功能都已经实现了,还差最后一步:
6:初始化对话框
for(int i=0i<20i++){
m_listtopic.AddString(topics[i])
}
//index初始化为0,直接刷新
updateInfo()
m_listtopic.SetCurSel(index)
运行结果如下:
首先,打开IDE,本人用的是VS2005(英文版),然后点file,new一个project,选VisualC++目录下面的MFC,然后选中散行旁边Templates里的MFC
Application,再在下面的name栏里给你的工程取个名字,比如叫Test,最枝亮后点OK。
进入下一界面后会有一些关于当前工程的设置,在Application type中选dialog based,直接finish.
这样一个基于对话框的MFC简单工程就建成了。
然后再TestDlg.cpp里找到void CtestDlg::OnPaint(),在else里的CDialog::OnPaint()后面写
CClientDC dc(this)//选定当前画图环境
CPen pen(PS_SOLID,1,#ff0000)//做一支红色粗细为1的笔
dc.SelectObject(&pen)//将猛掘宽pen放到dc上
dc.Rectangle(100,100,200,200)//画一个矩形
完成!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)