MFC中画动态图的CPU过高问题

lulu23260 2014-08-18 09:50:57
又要做个画图的桌面程序,………………

用MFC做画图过,CPU利用率总是很高。
我做法是:OnPaint()中调用函数在picture control获得DC画背景格加前景曲线,或者在内存DC上直接放个bitmap文件做背景,画数据曲线,并拷贝到DC上,

定时或者每收到一定数量数据 就更新图就是Invalidate(); UpdateWindow(); 都会引发OnPaint(),

更新的频率是依照人眼可接受的频率

方法太蠢吗?有什么建议可改进的?还是MFC本身做这事就有缺陷??
...全文
529 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2014-09-22
  • 打赏
  • 举报
回复
您好 我是本版版主 此帖已多日无人关注 请您及时结帖 如您认为问题没有解决可按无满意结帖处理 另外本版设置了疑难问题汇总帖 并已在版面置顶 相关规定其帖子中有说明 您可以根据规定提交您帖子的链接 如您目前不想结帖只需回帖说明 我们会删除此结帖通知 见此回复三日内无回应 我们将强制结帖 相关规定详见界面界面版关于版主结帖工作的具体办法
夫人的泡泡鱼 2014-08-22
  • 打赏
  • 举报
回复
路过学习了,我采用的是在OnPaint中使用双缓冲进行贴图,其他地方Invalid实现的,同时,重载OnEraseBgd将使用空的背景画刷,可以防止屏幕闪烁。
lulu23260 2014-08-21
  • 打赏
  • 举报
回复
引用 14 楼 fangjl9 的回复:
你只要在内存里画好不在屏幕内显示,速度不会太慢,显示出来才慢,所以你可以再内存里画好背景,然后再画波形,画好在用CDC->bitbit函数一张张贴出来看起来就是动态的,比起Onpaint一直画,这种只贴图CPU开销小得多。我觉得你CPU过高的问题是在于把画图程序放到了Onpaint里。你可以弄一个定时器,定时器响应函数中调用画图函数,画图函数单独定义,给个CDC就可以了。不需要Onpaint
以前那么程序就跑着跑着很高,一直找不到原因。。 新做的测试了,无论是直接画图,还是双缓冲方式,都不怎么高,,我都还是在Onpaint里画的图。 不在Onpaint里画,移动窗口的时候图就没了,或者最小化窗口之后,图还是没了,不爽! 您怎么解决的这个问题??
lulu23260 2014-08-21
  • 打赏
  • 举报
回复
引用 7 楼 cvbtvbwu 的回复:
能发工程给我看一下吗
我弄好了,没解决问题的话,发一份,谢谢!!
lulu23260 2014-08-21
  • 打赏
  • 举报
回复
引用 9 楼 VisualEleven 的回复:
CPU比较高,是不是你的程序中有循环复杂的运算?确定是绘图影响的?
目前测试:采用定时器60hz的频率,发送ON_PAINT消息,onPaint()函数中调用画图的部分,(目前画图没有加点连接的曲线,只是些坐标线,更新的坐标值) 若采用在设备上直接画图 cpu在百分之十几,屏幕有闪的现象, 若采用内存画图,拷贝到设备,cpu在30%左右,屏幕不闪烁, 明天加上曲线,测试一下,
fangjl9 2014-08-21
  • 打赏
  • 举报
回复
引用 11 楼 lulu23260 的回复:
[quote=引用 10 楼 fangjl9 的回复:]指定更新矩形用InvalidateRect(CRect,BOOL(是否擦除原背景))
哦,很感谢,一直有个问题:波形和自己做的方格坐标什么的,怎么定义那个坐标格是背景,波形是前景,只更新前景呢? [/quote] 这个不会了,MFC中有分层吗?我只见过PS软件里有,动态显示画线我也做过,是带坐标的波形图,不过是动态显示,线出来是动的,之后不动了,我就用的双缓冲,感觉速度可以。 你只要在内存里画好不在屏幕内显示,速度不会太慢,显示出来才慢,所以你可以再内存里画好背景,然后再画波形,画好在用CDC->bitbit函数一张张贴出来看起来就是动态的,比起Onpaint一直画,这种只贴图CPU开销小得多。我觉得你CPU过高的问题是在于把画图程序放到了Onpaint里。你可以弄一个定时器,定时器响应函数中调用画图函数,画图函数单独定义,给个CDC就可以了。不需要Onpaint
lulu23260 2014-08-21
  • 打赏
  • 举报
回复
引用 16 楼 happyparrot 的回复:
将要绘制的内容封装为一个函数。OnPaint中调用,其它需要主要更新的地方,只需要调用该函数,不需要去激发WM_PAINT
恩,好方法,谢谢
快乐鹦鹉 2014-08-21
  • 打赏
  • 举报
回复
将要绘制的内容封装为一个函数。OnPaint中调用,其它需要主要更新的地方,只需要调用该函数,不需要去激发WM_PAINT
lulu23260 2014-08-20
  • 打赏
  • 举报
回复
引用 10 楼 fangjl9 的回复:
指定更新矩形用InvalidateRect(CRect,BOOL(是否擦除原背景))
哦,很感谢,一直有个问题:波形和自己做的方格坐标什么的,怎么定义那个坐标格是背景,波形是前景,只更新前景呢?
fangjl9 2014-08-19
  • 打赏
  • 举报
回复
我们头说,onpaint里面不要放东西,因为它很容易被系统调用影响效率,自己放别处然后自己调用吧,onpanit里尽量别放东西。更新视图的时候,最好指定更新矩形,不要变动一点就全屏幕刷新,很浪费时间和资源的。指定更新矩形用InvalidateRect(CRect,BOOL(是否擦除原背景))
Eleven 2014-08-19
  • 打赏
  • 举报
回复
CPU比较高,是不是你的程序中有循环复杂的运算?确定是绘图影响的?
向立天 2014-08-18
  • 打赏
  • 举报
回复
我一般的做法是把所有绘图工作都放到OnPaint中 使用CPaintDC 然后在程序其它位置更新绘制数据通过Invalidate函数激活OnPaint 你如果要在控件上绘图可以考虑自定义控件 参考http://blog.csdn.net/xianglitian/article/details/6100767
快乐鹦鹉 2014-08-18
  • 打赏
  • 举报
回复
没事别Invalidate......直接覆盖就可以了。
hurryboylqs 2014-08-18
  • 打赏
  • 举报
回复
可以用异或方式,把上次的图用异或画一次 相当于擦除上次的,然后再画当前的图形,无需Invalidate.
叶恭介叶恭介 2014-08-18
  • 打赏
  • 举报
回复
缺陷?没这回事,只有菜的人。 优化一下绘图的方法吧。例如CDC可以先创建先,曲线绘制不要一个点一个点的相连这种费时方法等。 用getticketcount一个一个的放到程序,看哪步费时的,仔细测试,很麻烦但没办法,能省则省,看到绘制时间 一点一滴的减少很开心的哟。
叶恭介叶恭介 2014-08-18
  • 打赏
  • 举报
回复
能发工程给我看一下吗
快乐鹦鹉 2014-08-18
  • 打赏
  • 举报
回复
首先要确定高CPU一定是画图引起的吗?那画完后Sleep(0)试试,短暂的把时间片还给内核。
lulu23260 2014-08-18
  • 打赏
  • 举报
回复
引用 1 楼 cvbtvbwu 的回复:
曲线绘制不要一个点一个点的相连这种费时方法等。
那怎么做的,请指导啊?? 我要把采样点都体现在图中,不能下采样,减少点数
lulu23260 2014-08-18
  • 打赏
  • 举报
回复
引用 2 楼 happyparrot 的回复:
没事别Invalidate......直接覆盖就可以了。
以前有做过一个就是收到收数据线程的消息,就直接画图,无关Onpaint(),还是高CPU……

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧