1、 使用双缓冲的图形可以减少或消除重绘显示图面时产生的闪烁。使用双缓冲时,更新的图形首先被绘制到内存的缓冲区中,然后,此缓冲区的内容被迅速写入某些或所有显示的图面中。显示图形的重写相对简短,这通常可以减少或消除有时在更新图形时出现的闪烁。 使用C# GDI+绘图,实现双缓冲绘图有几种方法,在这篇文章中,将介绍其中的一种——使用BufferedGraphics实现GDI+双缓冲绘图。 下面的代码示例演示如何使用 BufferedGraphics 对象绘制以下图形,这些图形使用几种类型的缓冲实现。单击窗体将启动或停止一个计时器,该计时器将引起绘制更新。绘
2、制更新使您可以观察双缓冲的效果。右击窗体将循环使用下列绘制模式: · 对于 Form,直接绘制到 Handle。 · 对使用 OptimizedDoubleBuffer 控件样式的 OnPaint 方法进行重写,以进行绘制 · 对于不使用 OptimizedDoubleBuffer 控件样式的窗体方法,重写 OnPaint 方法以进行绘制。 在每种模式下都将绘制文本,以标识当前模式并描述按下每个鼠标按钮时发生的行为。 using System; using System.ComponentModel; using System.Drawing; using
3、System.Windows.Forms; namespace BufferingExample { public class BufferingExample : Form { private BufferedGraphicsContext context; private BufferedGraphics grafx; private byte bufferingMode; private string[] bufferingModeStrings =
4、 { "Draw to Form without OptimizedDoubleBufferring control style", "Draw to Form using OptimizedDoubleBuffering control style", "Draw to HDC for form" }; private System.Windows.Forms.Timer timer1; private byte count; public BufferingE
5、xample() : base() { // Configure the Form for this example. this.Text = "User double buffering"; this.MouseDown += new MouseEventHandler(this.MouseDownHandler); this.Resize += new EventHandler(this.OnResize); this.
6、SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true ); // Configure a timer to draw graphics updates. timer1 = new System.Windows.Forms.Timer(); timer1.Interval = 200; timer1.Tick += new EventHandler(this.OnTimer);
7、 bufferingMode = 2; count = 0; // Retrieves the BufferedGraphicsContext for the // current application domain. context = BufferedGraphicsManager.Current; // Sets the maximum size for the primary graphics buffer
8、 // of the buffered graphics context for the application // domain. Any allocation requests for a buffer larger // than this will create a temporary buffered graphics // context to host the graphics buffer. context.MaximumBuff
9、er = new Size(this.Width+1, this.Height+1); // Allocates a graphics buffer the size of this form // using the pixel format of the Graphics created by // the Form.CreateGraphics() method, which returns a // Graphics object that matches
10、 the pixel format of the form. grafx = context.Allocate(this.CreateGraphics(), new Rectangle( 0, 0, this.Width, this.Height )); // Draw the first frame to the buffer. DrawToBuffer(grafx.Graphics); } private void Mous
11、eDownHandler(object sender, MouseEventArgs e) { if( e.Button == MouseButtons.Right ) { // Cycle the buffering mode. if( ++bufferingMode > 2 ) bufferingMode = 0; // If the previous buf
12、fering mode used // the OptimizedDoubleBuffering ControlStyle, // disable the control style. if( bufferingMode == 1 ) this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true ); // If the cur
13、rent buffering mode uses // the OptimizedDoubleBuffering ControlStyle, // enabke the control style. if( bufferingMode == 2 ) this.SetStyle( ControlStyles.OptimizedDoubleBuffer, false ); // Cau
14、se the background to be cleared and redraw. count = 6; DrawToBuffer(grafx.Graphics); this.Refresh(); } else { // Toggle whether the redraw timer is active. if( timer1.E
15、nabled ) timer1.Stop(); else timer1.Start(); } } private void OnTimer(object sender, EventArgs e) { // Draw randomly positioned ellipses to the buffer. DrawToBuffer(grafx.Graphics);
16、 // If in bufferingMode 2, draw to the form's HDC. if( bufferingMode == 2 ) // Render the graphics buffer to the form's HDC. grafx.Render(Graphics.FromHwnd(this.Handle)); // If in bufferingMode 0 or 1, dr
17、aw in the paint method. else this.Refresh(); } private void OnResize(object sender, EventArgs e) { // Re-create the graphics buffer for a new window size. context.MaximumBuffer = new Size(this.Width+1, this.Heig
18、ht+1); if( grafx != null ) { grafx.Dispose(); grafx = null; } grafx = context.Allocate(this.CreateGraphics(), new Rectangle( 0, 0, this.Width, this.Height )); /
19、/ Cause the background to be cleared and redraw. count = 6; DrawToBuffer(grafx.Graphics); this.Refresh(); } private void DrawToBuffer(Graphics g) { // Clear the graphics buffer every five updates.
20、 if( ++count > 5 ) { count = 0; grafx.Graphics.FillRectangle(Brushes.Black, 0, 0, this.Width, this.Height); } // Draw randomly positioned and colored ellipses. Random rnd = new
21、 Random(); for( int i=0; i<20; i++ ) { int px = rnd.Next(20,this.Width-40); int py = rnd.Next(20,this.Height-40); g.DrawEllipse(new Pen(Color.FromArgb(rnd.Next(0, 255), rnd.Next(0,255), rnd.Next(0,255)), 1), px, py, px+rnd.Next(0
22、 this.Width-px-20), py+rnd.Next(0, this.Height-py-20)); } // Draw information strings. g.DrawString("Buffering Mode: "+bufferingModeStrings[bufferingMode], new Font("Arial", 8), Brushes.White, 10, 10); g.DrawString("Right-
23、click to cycle buffering mode", new Font("Arial", 8), Brushes.White, 10, 22); g.DrawString("Left-click to toggle timed display refresh", new Font("Arial", 8), Brushes.White, 10, 34); } protected override void OnPaint(PaintEventArgs e) { grafx.Render(e.Graphics); } [STAThread] public static void Main(string[] args) { Application.Run(new BufferingExample()); } } }
©2010-2025 宁波自信网络信息技术有限公司 版权所有
客服电话:4009-655-100 投诉/维权电话:18658249818