.net compact framework下的绘图闪烁解决方案
2008-09-24 18:02 cppguy 阅读(1174) 评论(1) 编辑 收藏 举报1:缓冲贴图
//重新绘制的函数
void Redraw()
{
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的系统异常,所以对于图形变换比较频繁的系统来说,尽量应该摒弃掉无效刷新这种方式