使用Double-Buffer来实现无闪烁动态折线图
2011-07-01 10:00
316 查看
//--------------------------- 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+}-------------------------------
///////////////////////////////////////////////FORM窗体
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 partial class frmGraphView : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox picGraph;
/// <summary>
/// Required designer variable.
/// </summary>
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>
/// <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();
}
}
}
//////////////////////////////////////////////////////////设计窗体CS
namespace GraphView
{
partial class frmGraphView
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
private void InitializeComponent()
{
this.picGraph = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.picGraph)).BeginInit();
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(6, 14);
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);
((System.ComponentModel.ISupportInitialize)(this.picGraph)).EndInit();
this.ResumeLayout(false);
}
}
}
//----------------------------------------------------------------------------------------------
//---File: frmGraphView
//---Description: A demo using double-buffer in GDI+
//---Author: Knight
//---Date: Jul.3, 2006
//----------------------------------------------------------------------------------------------
//---------------------------{A Demo using Double-Buffer in GDI+}-------------------------------
///////////////////////////////////////////////FORM窗体
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 partial class frmGraphView : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox picGraph;
/// <summary>
/// Required designer variable.
/// </summary>
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>
/// <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();
}
}
}
//////////////////////////////////////////////////////////设计窗体CS
namespace GraphView
{
partial class frmGraphView
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
private void InitializeComponent()
{
this.picGraph = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.picGraph)).BeginInit();
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(6, 14);
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);
((System.ComponentModel.ISupportInitialize)(this.picGraph)).EndInit();
this.ResumeLayout(false);
}
}
}
相关文章推荐
- 使用Double-Buffer来实现无闪烁动态折线图
- 使用Double-Buffer来实现无闪烁动态折线图
- Android使用自定义View继承SurfaceView实现动态折线图的绘制
- Android使用自定义View继承SurfaceView实现动态折线图的绘制
- 使用achartengine 实现简单静态、动态折线图
- IOS-使用framework实现功能模块动态更新
- 使用spring的动态路由实现数据库负载均衡
- 使用boost::circular_buffer_space_optimized实现OTL数据库连接池
- QBC常用限定方法,使用QBC实现动态查询 ,Restrictions
- leetcode 140:Word Break II 采用很巧妙的动态规划和DFS联合使用 JAVA源代码实现
- Android_Loader_使用LoaderManager管理Loader实现异步动态加载数据
- 使用Autolayout实现UITableView的Cell动态布局和高度动态改变
- 使用placeholder实现动态配置persistence.xml
- Java JDK 动态代理(AOP)使用及实现原理分析
- Spring_AOP_XML使用Aspect实现动态代理(常用) .
- 使用Visifire+ArcGIS API for Silverlight实现Graphic信息的动态图表显示
- 使用Autolayout xib实现动态高度的TableViewCell
- 使用JavaScript动态设置样式实现代码及演示动画
- JSP中使用JavaScript动态插入删除输入框实现代码
- Easyui笔记4:实现表格内combobox数据的动态切换(getEditor的使用)