- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
GDI双缓冲
GDI+的双缓冲问题
??? 我想有很多搞图形方面的朋友都会用到双缓冲技术的时候,而且有的时候她的确是个头疼的问题。最近我也要用双缓冲技术,程序怎么调试都不合适,当要对图形进行移动时,总是会出现闪烁抖动。在网上找了些资料,说得都不清不楚的,折腾了一晚上也没弄出来。第二天觉定自己研究一下。现在把自己的一些想法拿出来跟大家分享一下。
双缓冲的基本原理:(转)
??? 一直以来的误区:.net1.1 和 .net 2.0 在处理控件双缓冲上是有区别的。??? .net 1.1中,使用:this.SetStyle(ControlStyles.DoubleBuffer, true);??? .net 2.0中,使用:this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);怪不说老是提示参数无效,一直也不知道是这个问题,呵呵???? 要知道,图元无闪烁的实现和图元的绘制方法没有多少关系,只是绘制方法可以控制图元的刷新区域,使双缓冲性能更优!?导致画面闪烁的关键原因分析:
????? 一、绘制窗口由于大小位置状态改变进行重绘操作时
???? 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面重新刷新一次以维持窗口正常显示。刷新过程中会导致所有图元重新绘制,而各个图元的重绘操作并不会导致Paint事件发生,因此窗口的每一次刷新只会调用Paint事件一次。窗口刷新一次的过程中,每一个图元的重绘都会立即显示到窗口,因此整个窗口中,只要是图元所在的位置,都在刷新,而刷新的时间是有差别的,闪烁现象自然会出现。所以说,此时导致窗口闪烁现象的关键因素并不在于Paint事件调用的次数多少,而在于各个图元的重绘。
???? 根据以上分析可知,当图元数目不多时,窗口刷新的位置也不多,窗口闪烁效果并不严重;当图元数目较多时,绘图窗口进行重绘的图元数量增加,绘图窗口每一次刷新都会导致较多的图元重新绘制,窗口的较多位置都在刷新,闪烁现象自然就会越来越严重。特别是图元比较大绘制时间比较长时,闪烁问题会更加严重,因为时间延迟会更长。
???? 解决上述问题的关键在于:窗口刷新一次的过程中,让所有图元同时显示到窗口。????? 二、进行鼠标跟踪绘制操作或者对图元进行变形操作时
???? 当进行鼠标跟踪绘制操作或者对图元进行变形操作时,Paint事件会频繁发生,这会使窗口的刷新次数大大增加。虽然窗口刷新一次的过程中所有图元同时显示到窗口,但也会有时间延迟,因为此时窗口刷新的时间间隔远小于图元每一次显示到窗口所用的时间。因此闪烁现象并不能完全消除!所以说,此时导致窗口闪烁现象的关键因素在于Paint事件发生的次数多少。???? 解决此问题的关键在于:设置窗体或控件的几个关键属性。
下面讲具体的实现方法:(转)
??? 1、在内存中建立一块“虚拟画布”:Bitmap bmp = new Bitmap(600, 600); 2、获取这块内存画布的Graphics引用:Graphics g = Graphics.FromImage(bmp);
3、在这块内存画布上绘图:如画线g.DrawLine(添加参数);
4、将内存画布画到窗口中:this.CreateGraphics().DrawImage(bmp, 0, 0);
在构造函数中加如下代码
代码一:????? SetStyle(ControlStyles.UserPaint, true);????? SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.????? SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
或代码二:?? this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint, true);?? this.UpdateStyles();(转载结束)
?
??? 上述方式适合直接在窗体上绘制图形,并且很容易做到。但有时我们需要在某个控件上绘制图形,那该怎么办呢?原理跟直接在窗体上绘制图形采用双缓冲是一样的,也要在控件的构造函数里设置上述代码一或代码二。那么又怎么设置呢?我是通过阅读MSDN,找到自定义控件的方法,并在控件的构造函数里设置。在后面的附录里,我会说明怎么做。
?
??? 在Microsoft Visual Studio 2005环境下的,用的C#语言,并采用GDI+。目标是实现简单的鼠标拖动画线,并且要把之前画过
文档评论(0)