반응형

윈폼 프로그래밍을 하다보면, 폼 이동시에 잔상이 남게 되는데요. 개발자의 입장에서 상당히 거슬리는 부분이 아닐 수 없습니다.

 

이럴때 Windows Form 2.0의 경우에는 EnableDoubleBuffering속성을 True로 변경하여 어느정도 효과를 볼 수 있다고 하네요. 또한 Windows Form 1.0의 경우는 아래 UI와 샘플 코드를 참고하여 DoubleBuffering을 구현할 수 있습니다.

 

 

 

 

 

using System;

using System.Drawing;

using System.Drawing.Drawing2D;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

 

namespace DoubleBuffer

{

  /// <summary>

  /// Summary description for Form1.

  /// </summary>

  public class Form1 : System.Windows.Forms.Form

  {

 

    private System.Windows.Forms.Timer timer1;

    private System.ComponentModel.IContainer components;

    private System.Windows.Forms.CheckBox checkBox1;

 

    float _angle;

    bool _doBuffer;

 

    public Form1()

    {

      //

      // Required for Windows Form Designer support

      //

      InitializeComponent();

 

      //

      // TODO: Add any constructor code after InitializeComponent call

      //

    }

 

    /// <summary>

    /// Clean up any resources being used.

    /// </summary>

    protected override void Dispose( bool disposing )

    {

      if( disposing )

      {

        if (components != null)

        {

          components.Dispose();

        }

      }

      base.Dispose( disposing );

    }

 

    #region Windows Form Designer generated code

    /// <summary>

    /// Required method for Designer support - do not modify

    /// the contents of this method with the code editor.

    /// </summary>

    private void InitializeComponent()

    {

      this.components = new System.ComponentModel.Container();

      this.timer1 = new System.Windows.Forms.Timer(this.components);

      this.checkBox1 = new System.Windows.Forms.CheckBox();

      this.SuspendLayout();

      //

      // timer1

      //

      this.timer1.Enabled = true;

      this.timer1.Tick += new System.EventHandler(this.timer1_Tick);

      //

      // checkBox1

      //

      this.checkBox1.Location = new System.Drawing.Point(8, 8);

      this.checkBox1.Name = "checkBox1";

      this.checkBox1.TabIndex = 0;

      this.checkBox1.Text = "Double Buffer";

      this.checkBox1.CheckedChanged += newSystem.EventHandler(this.checkBox1_CheckedChanged);

      //

      // Form1

      //

      this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

      this.ClientSize = new System.Drawing.Size(292, 273);

      this.Controls.Add(this.checkBox1);

      this.Name = "Form1";

      this.Text = "Form1";

      this.ResumeLayout(false);

 

    }

    #endregion

 

    /// <summary>

    /// The main entry point for the application.

    /// </summary>

    [STAThread]

    static void Main()

    {

      Application.Run(new Form1());

    }

 

    private void timer1_Tick(object sender, System.EventArgs e)

    {

      _angle+=3;

      if(_angle>359)

        _angle=0;

      Invalidate();

    }

 

    private Bitmap _backBuffer;

    

    protected override void OnPaint(PaintEventArgs e)

    {

      if(_backBuffer==null)

      {

        _backBuffer=new Bitmap(this.ClientSize.Width,this.ClientSize.Height);

      }

      

      Graphics g=null;

      if(_doBuffer)

        g=Graphics.FromImage(_backBuffer);

      else

        g=e.Graphics;

 

            g.Clear(Color.White);      

 

      g.SmoothingMode=SmoothingMode.AntiAlias;

 

      Matrix mx=new Matrix();

      mx.Rotate(_angle,MatrixOrder.Append);

      mx.Translate(this.ClientSize.Width/2,this.ClientSize.Height/2,MatrixOrder.Append);

      g.Transform=mx;

      g.FillRectangle(Brushes.Red,-100,-100,200,200);

 

      mx=new Matrix();

      mx.Rotate(-_angle,MatrixOrder.Append);

      mx.Translate(this.ClientSize.Width/2,this.ClientSize.Height/2,MatrixOrder.Append);

      g.Transform=mx;

      g.FillRectangle(Brushes.Green,-75,-75,149,149);

    

      mx=new Matrix();

      mx.Rotate(_angle*2,MatrixOrder.Append);

      mx.Translate(this.ClientSize.Width/2,this.ClientSize.Height/2,MatrixOrder.Append);

      g.Transform=mx;

      g.FillRectangle(Brushes.Blue,-50,-50,100,100);

 

      if(_doBuffer)

      {

        g.Dispose();

 

        //Copy the back buffer to the screen

 

        e.Graphics.DrawImageUnscaled(_backBuffer,0,0);

      }

 

      //base.OnPaint (e); //optional but not recommended

    }

 

    protected override void OnPaintBackground(PaintEventArgs pevent)

    {

      //Don't allow the background to paint

    }

 

    protected override void OnSizeChanged(EventArgs e)

    {

      if(_backBuffer!=null)

      {

        _backBuffer.Dispose();

        _backBuffer=null;

      }

      base.OnSizeChanged (e);

    }

 

    private void checkBox1_CheckedChanged(object sender, System.EventArgs e)

    {

      _doBuffer=this.checkBox1.Checked;

    }

  }

}

반응형

'Program > C#' 카테고리의 다른 글

.NET CF에서 WndProc 사용법  (0) 2010.03.19
프로세스 정보 가져오기  (0) 2010.03.19
PictureBox에서 Image 깜빡이는 효과주기.  (0) 2010.03.19
타임 서버에서 데이터 받아오기  (0) 2010.03.19
C#에서 ActiveX 사용하기  (0) 2010.03.19

+ Recent posts