zoukankan      html  css  js  c++  java
  • C#使用BufferedGraphics实现GDI+双缓冲绘图 转

    使用双缓冲的图形可以减少或消除重绘显示图面时产生的闪烁。使用双缓冲时,更新的图形首先被绘制到内存的缓冲区中,然后,此缓冲区的内容被迅速写入某些或所有显示的图面中。显示图形的重写相对简短,这通常可以减少或消除有时在更新图形时出现的闪烁。

     

        使用C# GDI+绘图,实现双缓冲绘图有几种方法,在这篇文章中,将介绍其中的一种——使用BufferedGraphics实现GDI+双缓冲绘图。
     

        下面的代码示例演示如何使用 BufferedGraphics 对象绘制以下图形,这些图形使用几种类型的缓冲实现。单击窗体将启动或停止一个计时器,该计时器将引起绘制更新。绘制更新使您可以观察双缓冲的效果。右击窗体将循环使用下列绘制模式:

    • 对于 Form,直接绘制到 Handle

    • 对使用 OptimizedDoubleBuffer 控件样式的 OnPaint 方法进行重写,以进行绘制

    • 对于不使用 OptimizedDoubleBuffer 控件样式的窗体方法,重写 OnPaint 方法以进行绘制。

        在每种模式下都将绘制文本,以标识当前模式并描述按下每个鼠标按钮时发生的行为。

    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Windows.Forms;
    
    namespace DoubleBufferShown
    {
        public partial class BufferingExample : Form
        {
            private BufferedGraphicsContext context;
            private BufferedGraphics grafx;
    
            private byte bufferingMode;
            private string[] bufferingModeStrings =  
            { "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 BufferingExample()
                : 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.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);
    
                bufferingMode = 2;
                count = 0;
    
                // Retrieves the BufferedGraphicsContext for the  
                // current application domain. 
                context = BufferedGraphicsManager.Current;
    
                // Sets the maximum size for the primary graphics buffer 
                // 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.MaximumBuffer = 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 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 MouseDownHandler(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Right)
                {
                    // Cycle the buffering mode. 
                    if (++bufferingMode > 2)
                        bufferingMode = 0;
    
                    // If the previous buffering mode used  
                    // the OptimizedDoubleBuffering ControlStyle, 
                    // disable the control style. 
                    if (bufferingMode == 1)
                        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    
                    // If the current buffering mode uses 
                    // the OptimizedDoubleBuffering ControlStyle, 
                    // enabke the control style. 
                    if (bufferingMode == 2)
                        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
    
                    // Cause the background to be cleared and redraw. 
                    count = 6;
                    DrawToBuffer(grafx.Graphics);
                    this.Refresh();
                }
                else
                {
                    // Toggle whether the redraw timer is active. 
                    if (timer1.Enabled)
                        timer1.Stop();
                    else
                        timer1.Start();
                }
            }
    
            private void OnTimer(object sender, EventArgs e)
            {
                // Draw randomly positioned ellipses to the buffer. 
                DrawToBuffer(grafx.Graphics);
    
                // 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, draw 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.Height + 1);
                if (grafx != null)
                {
                    grafx.Dispose();
                    grafx = null;
                }
                grafx = context.Allocate(this.CreateGraphics(),
                    new Rectangle(0, 0, this.Width, this.Height));
    
                // 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. 
                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 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, 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-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);
            }
    
        }
    }
    

      

  • 相关阅读:
    数据结构基础知识(2)
    ASIHttpRequest异步请求网络崩溃解决
    [置顶] Android仿人人客户端(v5.7.1)——采用ViewGroup做父容器,实现左侧滑动菜单(三)
    Linux中ifcfgeth0配置参数说明
    什么是redis
    CentOS网络接口配置文件ifcfgeth详解
    查看Linux版本
    CentOS7 network.service loaded failed 处理技巧
    如果这都不算爱
    ACL Security In Seam, Part 1
  • 原文地址:https://www.cnblogs.com/YYi_H/p/2153430.html
Copyright © 2011-2022 走看看