GDI画图——我对双缓存防闪烁的理解。

2 篇文章 0 订阅

 

      我遇到的问题是这样的:程序界面是建立在若干张位图图片的基础上,将数据显示在这些位图的某些固定位置上。之所以用位图为框架,是有原因的:如果单纯用GDI绘制界面,在没有扩展GDI开发包的情况下,而且是嵌入式的CE系统中,什么锯齿校正,颜色校正等情况会占用太高的内存,不合算。况且用代码画图远比用手绘图麻烦(至少对于我是这样~),如果日后要想修改界面风格,就得改代码。如果用位图就方便多了,直接换位图就可以了。现在的QQ,游戏之类的界面,不也是为了体现Object-Oriented风格全都是用位图嘛!

 

      但是用实际位图做界面,就会不可避免遇到一个问题:那就是闪屏问题。也许有人会说,这个问题很简单啊,网上这类的解决方法很多啊,什么修改刷屏背景画刷的颜色了,用内存DC绘制然后BitBlt到屏幕上啊。其实没那么简单。修改刷屏背景画刷的方法在PC电脑上挺好使,也很方便,但在WinCE系统上貌似很难修改(至少我修改不了,改完跟没改一样,还是默认的背景画刷)。另外这种方式我个人也觉得技术含量偏低,有点自欺欺人的味道。所以还是得在内存DC的绘制上做文章。

 

      其实现在主流的GDI绘制方式,都是在内存DC上绘制好,然后一下子BitBlt到屏幕上。前提是:你的内存足够大,对程序执行效率要求甚高!但在现如今,即便一个嵌入式的WinCE系统,内存好歹也得上M吧,而且对于一个大型程序来说,这点效率的浪费是很必要的!

 

      现在说一下在内存DC中绘图的原理:首先你要创建一个一个内存DC(兼容DC),然后创建一个兼容位图,然后将这个兼容位图选入内存DC中,这样你就可以用内存DC的句柄进行绘制了(这个过程中在你的显示屏上是看不到的),最后,将你在内存DC中绘制好的图片复制到实际DC中就可以在显示屏上看到了(利用BitBlt函数)。

      这一过程的关键在创建了一个兼容位图。这个东西不是太好理解,可以这样认为:兼容位图只是一个抽象的位图,在你创建好后,它理论上只有1*1的大小。兼容指的是这个位图的像素与实际DC是一致的。在内存DC中绘制可以有效避免闪屏,是因为使用的缓存技术(先在内存中绘制好,再一下子显示出来)我们一般的GDI绘图操作,顶多也就是在这样一个基础上,是不需要加载实际位图的。这也就是有些人会说简单的原因~~~

 

      但说一下例外的情况,也就是我遇到的情况:我的绘制操作是在以一张张实际位图为背景的基础上的。在内存中可以绘制成功的原因是因为加载的是一张兼容位图,然后你就可以利用内存DC绘制了。可是我需要加载的是一张实际位图,这时候你再用内存DC绘制的画,会被实际位图覆盖,相当于屁都没有!这个问题困扰了老子有段时间了,在CSDN也发帖子求助过,结果底下的回答真是五花八门,没一个靠谱的。尤其是看到说“用兼容位图不就得了”这种屁话老子就想骂娘。连问题都没看清楚就瞎J8回答~~~

 

      有时候你花好几个星期解决不了一个问题,往往在不经意间就解决了。昨天下午看了一个人的文章中提到“双缓存技术”让我眼前一亮。是啊!一次缓存不够,那就再加一次怎样呢?花了不到十分钟时间改了下代码,哈哈,果然解决了。

 

      我的具体做法如下:创建两个内存DC(内存DC1,内存DC2),在内存DC1中选入兼容位图,在内存DC2中选入实际位图。这时,关键来了——将内存DC2中的位图复制到内存DC1中,然后就利用这个内存DC1的句柄进行GDI绘图操作,最后将内存DC1中的位图复制到实际DC中,大功告成:)

 

注意:在数据显示区,你需要用一个位图背景色的画刷填充一下,这样保证数据更新时会覆盖旧数据。

具体代码:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值