WhyCan Forum

人过留名,雁过留声,感谢各位朋友不离不弃地支持。 QQ: 516333132, 微信: whycan_cn (哇酷网/挖坑网/填坑网) admin@whycan.cn

您尚未登录。

#1 2019-11-28 14:04:09

呵哈呵哈
会员
注册时间: 2019-11-23
累计积分: 20

公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

以前客户使用的时候,上面元素不多, 只有一些线段/圆弧

现在由于业务拓展到别的领地,

有些客户画几千个元素, 生成几万个点, CxxxView OnDraw() 的时候已经不堪重负,

随便重画一个什么, 或者放缩一下, 只要电脑性能差一点,

就卡成狗了。

离线

#2 2019-11-28 14:10:00

天马行空
会员
注册时间: 2019-11-12
累计积分: 28

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

用 mfc 的 mem dc 会不会改善一些?

离线

#3 2019-11-28 14:12:36

异乡是故乡
会员
注册时间: 2019-11-15
累计积分: 6

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

天马行空 说:

用 mfc 的 mem dc 会不会改善一些?

MEM DC 是用双缓冲解决的是闪烁问题, 你现在的问题不是闪烁, 而是计算占了太多cpu时间,导致GUI卡屎了。

离线

#4 2019-11-28 14:13:59

呵哈呵哈
会员
注册时间: 2019-11-23
累计积分: 20

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

异乡是故乡 说:

MEM DC 是用双缓冲解决的是闪烁问题, 你现在的问题不是闪烁, 而是计算占了太多cpu时间,导致GUI卡屎了。

对, 就是双缓冲这个问题我和同事讨论过, 已经pass了。

离线

#5 2019-11-28 14:16:52

xgui
会员
注册时间: 2019-09-07
累计积分: 196

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

这里有一个差不多的问题: http://xcx1024.com/ArtInfo/705422.html

4、如何提高绘图的效率
我主要做的是电力系统的网络图形的CAD软件,在一个窗口中往往要显示成千上万个电力元件,
而每个元件又是由点、线、圆等基本图形构成。如果真要在一次重绘过程重画这么多元件,
可想而知这个过程是非常漫长的。如果加上了图形的浏览功能,鼠标拖动图形滚动时需要进行
大量的重绘,速度会慢得让用户将无法忍受。怎么办?只有再研究研究MFC的绘图过程了。

实际上,在OnDraw(CDC *pDC)中绘制的图并不是所有都显示了的,例如:你在OnDraw中
画了两个矩形,在一次重绘中虽然两个矩形的绘制函数都有执行,但是很有可能只有一个显示了,
这是因为MFC本身为了提高重绘的效率设置了裁剪区。裁剪区的作用就是:只有在这个区内的
绘图过程才会真正有效,在区外的是无效的,即使在区外执行了绘图函数也是不会显示的。

因为多数情况下窗口重绘的产生大多是因为窗口部分被遮挡或者窗口有滚动发生,改变的
区域并不是整个图形而只有一小部分,这一部分需要改变的就是pDC中的裁剪区了。

因为显示(往内存或者显存都叫显示)比绘图过程的计算要费时得多,有了裁剪区后显示
的就只是应该显示的部分,大大提高了显示效率。但是这个裁剪区是MFC设置的,它已经
为我们提高了显示效率,在进行复杂图形的绘制时如何进一步提高效率呢?那就只有
去掉在裁剪区外的绘图过程了。可以先用pDC->GetClipBox()得到裁剪区,
然后在绘图时判断你的图形是否在这个区内,如果在就画,不在就不画。

如果你的绘图过程不复杂,这样做可能对你的绘图效率不会有提高。

离线

#6 2019-11-28 14:47:23

超级萌新
会员
注册时间: 2018-05-04
累计积分: 342

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

我感觉这个问题单靠GetClipBox解决不了,

因为如果所有元素都在可视区域,

还是得全部重新计算并重绘。

离线

#7 2019-11-28 14:51:29

xgui
会员
注册时间: 2019-09-07
累计积分: 196

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

超级萌新 说:

我感觉这个问题单靠GetClipBox解决不了,

因为如果所有元素都在可视区域,

还是得全部重新计算并重绘。

你说的也有道理, 看来用线程在后台画, 画完之后给GUI发个消息,然后把画好的数据粘贴到UI

离线

#8 2019-11-28 14:52:58

呵哈呵哈
会员
注册时间: 2019-11-23
累计积分: 20

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

xgui 说:

你说的也有道理, 看来用线程在后台画, 画完之后给GUI发个消息,然后把画好的数据粘贴到UI

嗯, 谢谢大家, 我考虑一下用线程怎么做比较合适。

离线

#9 2019-11-29 13:21:37

JasonWoo
会员
注册时间: 2019-06-04
累计积分: 11

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

解决了能否分享一下思路

离线

#10 2019-12-04 17:10:38

还能这么玩
会员
注册时间: 2019-04-14
累计积分: 119

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

感觉楼主的问题和这个有点类似: https://bbs.csdn.net/topics/50226141

我在OnDraw()中,有大量的图形计算,所以每次当移动窗口,
或者被窗口覆盖的时候就要重新进行这部分的图形计算,
我觉得很是浪费,有什么办法解决啊???

我在VIEW中画的图很大很大,超过了客户区,因此使用了
CScrollView,所以每次我拖动滚动条时都会重新画一遍整个
计算复杂的图,速度暴慢,请DX出出点子啊~~~~~~~~

一个回答:

不要直接写在OnDraw()里,
至少也要加个条件判断一下是否需要重画

这个回答比较靠谱:

用多线程,启动一个线程单独用于计算,
在OnDraw里面向这个线程PostThreadMessage,
传进一些基本的参数,然后在线程里面计算,计算完,
再把需要的结果用PostMessage传递回来,
在消息处理函数中完成绘图。

比如说,如果你是在客户区显示位图,并要对位图进行一些计算操作,
那么就把位图的数据指针传到计算线程里,计算之后,
再把位图数据指针传递回来,然后简单的调用
Bitblt之类的函数就可以画图了,效率应该会有提高的。

离线

#11 2019-12-06 09:10:14

xgui
会员
注册时间: 2019-09-07
累计积分: 196

Re: 公司的一款用MFC设计行业辅助设计软件(类似CAD)在画面元素太多的时候问题爆发了

楼上这个方案不错, PostThreadMessage 把线程计算完的数据发给GUI线程。

离线

页脚