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

 我来答
育知同创教育
2016-06-13 · 百度知道合伙人官方认证企业
育知同创教育
1【专注:Python+人工智能|Java大数据|HTML5培训】 2【免费提供名师直播课堂、公开课及视频教程】 3【地址:北京市昌平区三旗百汇物美大卖场2层,微信公众号:yuzhitc】
向TA提问
展开全部

用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=0;i

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=0;i

m_strLable[i] = choose[index][i];

}

//无此选项,置空

for(;i<5;i++)

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=0;i<20;i++){

m_listtopic.AddString(topics[i]);

}

//index初始化为0,直接刷新

updateInfo();

m_listtopic.SetCurSel(index);

运行结果如下:

天堂梦丶鹉囹
推荐于2016-04-25 · 超过73用户采纳过TA的回答
知道答主
回答量:145
采纳率:87%
帮助的人:56.7万
展开全部
在对话框界面上画出统计后的柱状图。 提示:在OnPaint()函数中加入画线代码: CDC* pDC = GetDC(); //利用MFC的CDC类实现画线 CPoint pt1,pt2; //定义起点、终点 pt1.x = 100; pt1.y = 100; pt2.x = 200; pt2.y = 200; pDC->MoveTo(pt1); //线的起点 pDC->LineTo(pt2); //线的终点 ReleaseDC(pDC); //释放CDC 满意答案 网友回答 来自太平洋电脑网 - 第一专业IT门户网站2013-07-29读文件: int nData[20]; FILE *fpTxt; if( ( fpTxt = fopen ("C:\\1.txt","r")) == NULL ) { MessageBox("打开文件失败","系统警告",MB_OK); return; } for(int i=0;i>
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
flower
2015-10-23 · 爱生活,爱分享
flower
采纳数:94 获赞数:262

向TA提问 私信TA
展开全部
可以用MSChart。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式