如何用c++的mfc绘制柱状图

如何用c++的mfc绘制柱状图,第1张

用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)

}

5:添加控件消息响应函数

维护一个全局变量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,选Visual

C++目录下面的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)//画一个矩形

完成!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12245099.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存