转自:http://blog.csdn.net/Knight94/archive/2006/08/18/1094078.aspx
//
--------------------------- A Demo using Double-Buffer in GDI+ -------------------------------
// ----------------------------------------------------------------------------------------------
// ---File: frmGraphView
// ---Description: A demo using double-buffer in GDI+
// ---Author: Knight
// ---Date: Jul.3, 2006
// ----------------------------------------------------------------------------------------------
// ---------------------------{A Demo using Double-Buffer in GDI+}-------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace GraphView
{
using System.Threading;
/// <summary>
/// Summary description for Form1.
/// </summary>
public class frmGraphView : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox picGraph;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null ;
private clsDrawThread myDrawThread = null ;
private Thread thdDraw = null ;
public frmGraphView()
{
//
// 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 .picGraph = new System.Windows.Forms.PictureBox();
this .SuspendLayout();
//
// picGraph
//
this .picGraph.BackColor = System.Drawing.Color.Black;
this .picGraph.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this .picGraph.Dock = System.Windows.Forms.DockStyle.Fill;
this .picGraph.Location = new System.Drawing.Point( 0 , 0 );
this .picGraph.Name = " picGraph " ;
this .picGraph.Size = new System.Drawing.Size( 498 , 375 );
this .picGraph.TabIndex = 0 ;
this .picGraph.TabStop = false ;
this .picGraph.Paint += new System.Windows.Forms.PaintEventHandler( this .picGraph_Paint);
//
// frmGraphView
//
this .AutoScaleBaseSize = new System.Drawing.Size( 5 , 13 );
this .ClientSize = new System.Drawing.Size( 498 , 375 );
this .Controls.Add( this .picGraph);
this .FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this .MaximizeBox = false ;
this .Name = " frmGraphView " ;
this .StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this .Text = " Graph View " ;
this .Closing += new System.ComponentModel.CancelEventHandler( this .frmGraphView_Closing);
this .Load += new System.EventHandler( this .frmGraphView_Load);
this .ResumeLayout( false );
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run( new frmGraphView());
}
private void frmGraphView_Load( object sender, System.EventArgs e)
{
// Create thread class
myDrawThread = new clsDrawThread( this , new DrawHandler( RefreshPictureBox ),
picGraph.ClientSize.Width, picGraph.ClientSize.Height );
// Start sub thread to draw
thdDraw = new Thread( new ThreadStart( myDrawThread.DrawGraph ) );
thdDraw.Start();
}
private void RefreshPictureBox()
{
// Refresh picturebox
picGraph.Invalidate( picGraph.Region );
}
private void frmGraphView_Closing( object sender, System.ComponentModel.CancelEventArgs e)
{
// Close thread
myDrawThread.IsStop = true ;
thdDraw.Join( 1 );
}
private void picGraph_Paint( object sender, System.Windows.Forms.PaintEventArgs e)
{
// Draw image
e.Graphics.DrawImage( myDrawThread.DrawImage,
picGraph.ClientRectangle,
picGraph.ClientRectangle,
GraphicsUnit.Pixel );
}
}
public delegate void DrawHandler();
public class clsDrawThread
{
private Bitmap bitGraph = null ;
private bool blnStop = false ;
private int nStartY = - 1 ;
private int nEndY = - 1 ;
private Random ranPoint = null ;
private int nWidth = 0 ;
private int nHeight = 0 ;
private Form frmParent;
private DrawHandler pHandler = null ;
/// <summary>
/// Constructor
/// </summary>
/// <param name="pParent"></param>
/// <param name="Handler"></param>
/// <param name="Width"></param>
/// <param name="Height"></param>
public clsDrawThread( Form pParent, DrawHandler Handler, int Width, int Height )
{
// Init class member
nWidth = Width;
nHeight = Height;
frmParent = pParent; // Parent form
pHandler = Handler; // Call back delegate
// Create double buffer
bitGraph = new Bitmap( nWidth, nHeight );
ranPoint = new Random( nHeight ); // Create random
}
public bool IsStop
{
set { blnStop = value;}
}
public Image DrawImage
{
get { return bitGraph;}
}
/// <summary>
/// Sub thread entry function
/// </summary>
public void DrawGraph()
{
while ( ! blnStop )
{
Thread.Sleep( 400 );
if ( blnStop ) break ;
// Redraw bitmap
RedrawImage();
// Refresh pictorebox
try
{
frmParent.Invoke( pHandler );
}
catch { break ;}
}
}
/// <summary>
/// Re-draw image
/// </summary>
private void RedrawImage()
{
const int CLIP_WIDTH = 10 ;
Bitmap bitNew = new Bitmap( nWidth, nHeight );
Graphics gImage = Graphics.FromImage( bitNew );
// Use black color to fill the entire rectangle
gImage.FillRectangle( new SolidBrush( Color.Black ),
new Rectangle( new Point( 0 , 0 ),
new Size( nWidth, nHeight ) ) );
// Copy image from source image
gImage.DrawImage( bitGraph,
new Rectangle( 0 , 0 , nWidth - CLIP_WIDTH, nHeight ),
new Rectangle( CLIP_WIDTH, 0 , nWidth - CLIP_WIDTH, nHeight ),
GraphicsUnit.Pixel );
// Draw new clip image
if ( nStartY < 0 )
nStartY = ranPoint.Next() % nHeight;
else
nStartY = nEndY;
nEndY = ranPoint.Next() % nHeight;
// Draw new line
gImage.DrawLine( new Pen( Color.Red, 1.5f ),
new Point( nWidth - CLIP_WIDTH, nStartY ),
new Point( nWidth - 1 , nEndY ) );
// Set new image and release old image
Bitmap bitOld = bitGraph;
bitGraph = bitNew;
bitOld.Dispose();
}
}
}
// ----------------------------------------------------------------------------------------------
// ---File: frmGraphView
// ---Description: A demo using double-buffer in GDI+
// ---Author: Knight
// ---Date: Jul.3, 2006
// ----------------------------------------------------------------------------------------------
// ---------------------------{A Demo using Double-Buffer in GDI+}-------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace GraphView
{
using System.Threading;
/// <summary>
/// Summary description for Form1.
/// </summary>
public class frmGraphView : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox picGraph;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null ;
private clsDrawThread myDrawThread = null ;
private Thread thdDraw = null ;
public frmGraphView()
{
//
// 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 .picGraph = new System.Windows.Forms.PictureBox();
this .SuspendLayout();
//
// picGraph
//
this .picGraph.BackColor = System.Drawing.Color.Black;
this .picGraph.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this .picGraph.Dock = System.Windows.Forms.DockStyle.Fill;
this .picGraph.Location = new System.Drawing.Point( 0 , 0 );
this .picGraph.Name = " picGraph " ;
this .picGraph.Size = new System.Drawing.Size( 498 , 375 );
this .picGraph.TabIndex = 0 ;
this .picGraph.TabStop = false ;
this .picGraph.Paint += new System.Windows.Forms.PaintEventHandler( this .picGraph_Paint);
//
// frmGraphView
//
this .AutoScaleBaseSize = new System.Drawing.Size( 5 , 13 );
this .ClientSize = new System.Drawing.Size( 498 , 375 );
this .Controls.Add( this .picGraph);
this .FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this .MaximizeBox = false ;
this .Name = " frmGraphView " ;
this .StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this .Text = " Graph View " ;
this .Closing += new System.ComponentModel.CancelEventHandler( this .frmGraphView_Closing);
this .Load += new System.EventHandler( this .frmGraphView_Load);
this .ResumeLayout( false );
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run( new frmGraphView());
}
private void frmGraphView_Load( object sender, System.EventArgs e)
{
// Create thread class
myDrawThread = new clsDrawThread( this , new DrawHandler( RefreshPictureBox ),
picGraph.ClientSize.Width, picGraph.ClientSize.Height );
// Start sub thread to draw
thdDraw = new Thread( new ThreadStart( myDrawThread.DrawGraph ) );
thdDraw.Start();
}
private void RefreshPictureBox()
{
// Refresh picturebox
picGraph.Invalidate( picGraph.Region );
}
private void frmGraphView_Closing( object sender, System.ComponentModel.CancelEventArgs e)
{
// Close thread
myDrawThread.IsStop = true ;
thdDraw.Join( 1 );
}
private void picGraph_Paint( object sender, System.Windows.Forms.PaintEventArgs e)
{
// Draw image
e.Graphics.DrawImage( myDrawThread.DrawImage,
picGraph.ClientRectangle,
picGraph.ClientRectangle,
GraphicsUnit.Pixel );
}
}
public delegate void DrawHandler();
public class clsDrawThread
{
private Bitmap bitGraph = null ;
private bool blnStop = false ;
private int nStartY = - 1 ;
private int nEndY = - 1 ;
private Random ranPoint = null ;
private int nWidth = 0 ;
private int nHeight = 0 ;
private Form frmParent;
private DrawHandler pHandler = null ;
/// <summary>
/// Constructor
/// </summary>
/// <param name="pParent"></param>
/// <param name="Handler"></param>
/// <param name="Width"></param>
/// <param name="Height"></param>
public clsDrawThread( Form pParent, DrawHandler Handler, int Width, int Height )
{
// Init class member
nWidth = Width;
nHeight = Height;
frmParent = pParent; // Parent form
pHandler = Handler; // Call back delegate
// Create double buffer
bitGraph = new Bitmap( nWidth, nHeight );
ranPoint = new Random( nHeight ); // Create random
}
public bool IsStop
{
set { blnStop = value;}
}
public Image DrawImage
{
get { return bitGraph;}
}
/// <summary>
/// Sub thread entry function
/// </summary>
public void DrawGraph()
{
while ( ! blnStop )
{
Thread.Sleep( 400 );
if ( blnStop ) break ;
// Redraw bitmap
RedrawImage();
// Refresh pictorebox
try
{
frmParent.Invoke( pHandler );
}
catch { break ;}
}
}
/// <summary>
/// Re-draw image
/// </summary>
private void RedrawImage()
{
const int CLIP_WIDTH = 10 ;
Bitmap bitNew = new Bitmap( nWidth, nHeight );
Graphics gImage = Graphics.FromImage( bitNew );
// Use black color to fill the entire rectangle
gImage.FillRectangle( new SolidBrush( Color.Black ),
new Rectangle( new Point( 0 , 0 ),
new Size( nWidth, nHeight ) ) );
// Copy image from source image
gImage.DrawImage( bitGraph,
new Rectangle( 0 , 0 , nWidth - CLIP_WIDTH, nHeight ),
new Rectangle( CLIP_WIDTH, 0 , nWidth - CLIP_WIDTH, nHeight ),
GraphicsUnit.Pixel );
// Draw new clip image
if ( nStartY < 0 )
nStartY = ranPoint.Next() % nHeight;
else
nStartY = nEndY;
nEndY = ranPoint.Next() % nHeight;
// Draw new line
gImage.DrawLine( new Pen( Color.Red, 1.5f ),
new Point( nWidth - CLIP_WIDTH, nStartY ),
new Point( nWidth - 1 , nEndY ) );
// Set new image and release old image
Bitmap bitOld = bitGraph;
bitGraph = bitNew;
bitOld.Dispose();
}
}
}