代码改变世界

.net compact framework下的绘图闪烁解决方案

2008-09-24 18:02  cppguy  阅读(1170)  评论(1编辑  收藏  举报

1:缓冲贴图

   //重新绘制的函数  

     void Redraw()
       {

           //直接从窗体取得Graphics
           Graphics g = this.CreateGraphics();
           Redraw(g);
           g.Dispose();
       }

      //缓冲图以及操作缓冲图所需要的设备上下文

       Bitmap tempBitmap;
       Graphics tempGraphics;
       void Redraw(Graphics g)
       {
           if (tempBitmap == null)
           {
               tempBitmap = new Bitmap(this.Width, this.Height);
               tempGraphics = Graphics.FromImage(tempBitmap);
           }

           //在这里对缓冲图进行重新绘制
           DrawTempBitmap(tempGraphics);

          //将缓冲图直接贴到窗体上
           g.DrawImage(tempBitmap, 0, 0);
       }

      可以看到Redraw中的窗体Graphics是从窗体直接获得的,并不是从PaintEvent中得到的,这样的好处是,既可以在系统要求重绘的时候(比如出现窗体的切换,遮挡)在Onpaint中直接调用Redraw,而且在本窗体的业务功能运行中(比如出现图形的变换,擦除等等),要求主动绘制,也可以直接调用。

2:摒弃无效刷新

     一个区域,比如RECT,正常情况下是在活动窗口中的,你可以直接看的到,如果上面有一个窗口把这个区域覆盖了,那么这个区域就不是有效的了.变成无效的区域了.对于WINDOWS操作系统以及WinCE来说,当一个无效区域要面对用户的时候,它就会自动调用OnPaint进行刷新,用内存中的内容重新在界面上显示.使你看到的总是有效区域.   造成无效区域的方法很多,比如窗口覆盖,拖动,等等,如果你项强制你的区域刷新,比如你已经在这个区域更换了一幅图片之类.那么把这个要刷新的区域设置成无效区域,WINDOWS就会自动帮你刷新了。

    实现无效刷新,我们经常用到this.Invalidate(Rectangle),这个函数,可是,在.NETCF下,这个函数的重载实现并不完美,效率也很低,被设定的无效区域Rectangle,会有很明显的闪烁(首先被涂白,然后再绘制),比较起使用1方法的直接重贴缓冲图,后者基本没有闪烁,用户体验更好。

    另外频繁的this.Invalidate或者通过this.refresh,被动的激活系统来进行重新绘制,往往会产生win32501Exception的系统异常,所以对于图形变换比较频繁的系统来说,尽量应该摒弃掉无效刷新这种方式