墙裂建议界面版常驻人士讨论一下GDI/GDI+函数的使用

likang0712 2011-10-16 12:48:30


先贴一部分代码


CRect rect;
GetWindowRect(&rect);
CClientDC dc(this);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
if (1)
{
BITMAPINFO bitmapinfo;
bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapinfo.bmiHeader.biBitCount = 32;
bitmapinfo.bmiHeader.biHeight = rect.Height();
bitmapinfo.bmiHeader.biWidth = rect.Width();
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biCompression = BI_RGB;
bitmapinfo.bmiHeader.biXPelsPerMeter = 0;
bitmapinfo.bmiHeader.biYPelsPerMeter = 0;
bitmapinfo.bmiHeader.biClrUsed = 0;
bitmapinfo.bmiHeader.biClrImportant = 0;
bitmapinfo.bmiHeader.biSizeImage =
bitmapinfo.bmiHeader.biWidth * bitmapinfo.bmiHeader.biHeight * bitmapinfo.bmiHeader.biBitCount / 8;

hBitmap=::CreateDIBSection (dcMem,&bitmapinfo, 0,NULL, 0, 0);
hOldBitmap = (HBITMAP)dcMem.SelectObject(hBitmap);
}
else
{
bmpMem.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
pOldBmpMem = (HBITMAP)dcMem.SelectObject(&bmpMem);
}



新手(比如说我) 都一般使用判断下面的CreateCompatibleBitmap 来使用双缓存做贴图程序
但是这个星期写程序的时候 遇到了一个要常常刷新的窗口 CPU使用在很快刷新的情况下达到 40%~50%
后来无奈 也正好学学用CreateDIBSection 这个函数 结果发现是用CPU 20%~30% 我瞬间无言....
代码这么麻烦的函数居然要优秀这么多....

这不禁让我想起创建字体的函数 别人写的很多代码都使用 CreateFont() 这个复杂的函数 我一般直接CreatePointFont()
我不知道是不是这样速度会更快 但是我代码中的那个例子可是事实...

另外 如果把dcMem 定义成 类的成员变量 和函数的局部变量 CPU的使用差别貌似没区别

所以 墙裂建议界面版常驻人士讨论一下GDI/GDI+函数的使用!!! 有木有!!! 有木有!!!
比如说 您会常常使用什么函数 而不会使用另一种函数 如果有原因就更好了
之类之类的 您认为好的 都可以说说 :)

大家互相学习 希望大家不吝赐教




...全文
214 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2011-10-22
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 echoyin59 的回复:]

引用 22 楼 xianglitian 的回复:
引用 17 楼 xianglitian 的回复:

是不是也就是说,如果绘制比较慢可以考虑把一些计算放到OnPaint()外面
[/Quote]
是的
尤其是使用GDI+的时候
诶呦 2011-10-21
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 xianglitian 的回复:]
引用 17 楼 xianglitian 的回复:
[/Quote]
是不是也就是说,如果绘制比较慢可以考虑把一些计算放到OnPaint()外面
wwzzz 2011-10-21
  • 打赏
  • 举报
回复
楼主好人啊,学习学习
向立天 2011-10-20
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 likang0712 的回复:]

引用 17 楼 xianglitian 的回复:
总体上来说GDI+慢一些吧
其实效率是一个综合问题
解决的途径不是取舍函数而是改变机制
就你的代码来说
你觉得if(1)的代码繁琐
但其实质都是一下赋值语句
但就执行效率来说还是要到汇编级才能考语句数量说话
而且即便是汇编不同语句之间也有执行效率的差别
其实我觉得只要能实现效果,效率怎么样其实不那么重要
有些时候没有必要去苛求……
[/Quote]
比如把所有的绘图函数都放到OnPaint函数中就是比较普遍的一种绘制机制
这样做的好处是绘图操作比较集中容易管理
但是问题是每次调用OnPaint都要重新绘制
调用开销比较大
如果有些绘制比较费时那有的时候代价是不能接受的
所以可以考虑是不是可以省略费时操作
将一些不频繁改变的操作放到别的函数中
在那里准备绘制素材在OnPaint中使用
这就是所谓的改变机制
hsphsphsp 2011-10-19
  • 打赏
  • 举报
回复
好贴。学习了。
newfeitian 2011-10-19
  • 打赏
  • 举报
回复
前来学习,楼主给力呀
「已注销」 2011-10-19
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 xianglitian 的回复:]
总体上来说GDI+慢一些吧
其实效率是一个综合问题
解决的途径不是取舍函数而是改变机制
就你的代码来说
你觉得if(1)的代码繁琐
但其实质都是一下赋值语句
但就执行效率来说还是要到汇编级才能考语句数量说话
而且即便是汇编不同语句之间也有执行效率的差别
其实我觉得只要能实现效果,效率怎么样其实不那么重要
有些时候没有必要去苛求效率问题
[/Quote]

谢谢
"改变机制" 何为改变机制的说?
向立天 2011-10-19
  • 打赏
  • 举报
回复
总体上来说GDI+慢一些吧
其实效率是一个综合问题
解决的途径不是取舍函数而是改变机制
就你的代码来说
你觉得if(1)的代码繁琐
但其实质都是一下赋值语句
但就执行效率来说还是要到汇编级才能考语句数量说话
而且即便是汇编不同语句之间也有执行效率的差别
其实我觉得只要能实现效果,效率怎么样其实不那么重要
有些时候没有必要去苛求效率问题
「已注销」 2011-10-19
  • 打赏
  • 举报
回复
版主一回复 帖子就掉到第二页尾巴了....

恩 自顶一下...

求大家指教
liquanhai 2011-10-17
  • 打赏
  • 举报
回复
我是进来学习的,受教了,本来自认为做的还行,来了才知道差得远
「已注销」 2011-10-17
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 fandh 的回复:]
双缓冲只能解决一些刷新问题,但是,效率问题依旧存在!而且,如果每次刷新都调用:
hBitmap=::CreateDIBSection (dcMem,&bitmapinfo, 0,NULL, 0, 0);
那么,效率反而低了!
可以这样考虑
首先,CreateDIBSection 只在开始、改变大小的时候才创建,程序内部保存着这个句柄,这是一次创建,多次使用,这样,可以避免每次都要创……
[/Quote]
确实我很少见到多缓冲的例子 谢谢 指点

另外
[Quote=引用 4 楼 fandh 的回复:]
"CreateDIBSection 只在开始、改变大小的时候才创建,程序内部保存着这个句柄,这是一次创建,多次使用,这样,可以避免每次都要创建需要的开销"[/Quote]

如果这样 那CDC的内存对象应该也需要定义为类的成员变量了吧 同理CreateDIBSection()的返回对象?
此时 还需要在OnDestory()函数里面做清除工作


cocoabird 2011-10-17
  • 打赏
  • 举报
回复
up~~
弱水垂钓 2011-10-17
  • 打赏
  • 举报
回复
顶起,我还真就没注意过,一般就bitblt,stretchblt,fillregion,fillrect之类的
gold_water 2011-10-17
  • 打赏
  • 举报
回复
学习~~~
康斯坦汀 2011-10-17
  • 打赏
  • 举报
回复
学习。
用户 昵称 2011-10-17
  • 打赏
  • 举报
回复
双缓冲本来就是用cpu来换界面的。
fandh 2011-10-17
  • 打赏
  • 举报
回复
双缓冲只能解决一些刷新问题,但是,效率问题依旧存在!而且,如果每次刷新都调用:
hBitmap=::CreateDIBSection (dcMem,&bitmapinfo, 0,NULL, 0, 0);
那么,效率反而低了!
可以这样考虑
首先,CreateDIBSection 只在开始、改变大小的时候才创建,程序内部保存着这个句柄,这是一次创建,多次使用,这样,可以避免每次都要创建需要的开销。
其次,双缓冲只是个引子,实际上,所有的图形图像处理,大部分都不止双缓冲,可能是3缓冲甚至更多。比如,一个缓冲A画一些画布、色调等基本的基本上不改变的数据。一个画布B画一些具体有改动、可编辑的数据,实际的线什么的,画布B每次在画以前,先拷贝A,再绘画。一个画布C画一些临时数据,像编辑过程,拖动的过程等,当然,画布C在画以前,肯定也要拷贝画布B的。最后,只要将画布C贴出来就成。
最后,一定要将数据分类,每次要刷新那个缓冲,一定也要搞清楚。避免每次都刷新增加开销。
架构师Wu老七 2011-10-17
  • 打赏
  • 举报
回复
mark..
jkj9999 2011-10-17
  • 打赏
  • 举报
回复
mark
yyps 2011-10-17
  • 打赏
  • 举报
回复
其实我是来接分的。O(∩_∩)O~
加载更多回复(4)

15,980

社区成员

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

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