'Visual Basic 2005 Programmer's Reference
'by Rod Stephens (Author)
'# Publisher: Wrox (October 21, 2005)
'# Language: English
'# ISBN-10: 0764571982
'# ISBN-13: 978-0764571985
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Math
Imports System.Threading
public class ThreadGraph
public Shared Sub Main
Application.Run(New Form1)
End Sub
End class
Public Class Form1
Private m_Ymid As Integer
Private m_Y As Integer
Private Const GRID_STEP As Integer = 40
Private m_GraphThread As Thread
' Get ready.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
m_Ymid = picGraph.ClientSize.Height \ 2
m_Y = m_Ymid
' Make the Bitmap and Graphics objects.
Dim wid As Integer = picGraph.ClientSize.Width
Dim hgt As Integer = picGraph.ClientSize.Height
Dim bm As New Bitmap(wid, hgt)
Dim gr As Graphics = Graphics.FromImage(bm)
' Draw guide lines.
gr.Clear(Color.Blue)
For i As Integer = m_Ymid To picGraph.ClientSize.Height Step GRID_STEP
gr.DrawLine(Pens.LightBlue, 0, i, wid - 1, i)
Next i
For i As Integer = m_Ymid To 0 Step -GRID_STEP
gr.DrawLine(Pens.LightBlue, 0, i, wid - 1, i)
Next i
picGraph.Image = bm
End Sub
' Start drawing the graph.
Private Sub btnGraph_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGraph.Click
If m_GraphThread Is Nothing Then
' The thread isn't running. Start it.
AddStatus("Starting thread")
m_GraphThread = New Thread(AddressOf DrawGraph)
m_GraphThread.Priority = ThreadPriority.BelowNormal
m_GraphThread.IsBackground = True
m_GraphThread.Start()
AddStatus("Thread started")
btnGraph.Text = "Stop"
Else
' The thread is running. Stop it.
AddStatus("Stopping thread")
m_GraphThread.Abort()
' m_GraphThread.Join()
m_GraphThread = Nothing
AddStatus("Thread stopped")
btnGraph.Text = "Start"
End If
End Sub
' Draw a graph until stopped.
Private Sub DrawGraph()
Try
' Generate pseudo-random values.
Dim y As Integer = m_Y
Do
' Generate the next value.
NewValue()
' Plot the new value.
PlotValue(y, m_Y)
y = m_Y
Loop
Catch ex As Exception
AddStatus("[Thread] " & ex.Message)
End Try
End Sub
' Generate the next value.
Private Sub NewValue()
' Delay a bit before calculating the value.
Dim stop_time As Date = Now.AddMilliseconds(20)
Do While Now < stop_time
Loop
' Calculate the next value.
Static rnd As New Random
m_Y += rnd.Next(-4, 5)
If m_Y < 0 Then m_Y = 0
If m_Y >= picGraph.ClientSize.Height - 1 Then m_Y = picGraph.ClientSize.Height - 1
End Sub
' Plot a new value.
Private Delegate Sub PlotValueDelegate(ByVal old_y As Integer, ByVal new_y As Integer)
Private Sub PlotValue(ByVal old_y As Integer, ByVal new_y As Integer)
' See if we're on the worker thread and thus
' need to invoke the main UI thread.
If Me.InvokeRequired Then
' Make arguments for the delegate.
Dim args As Object() = {old_y, new_y}
' Make the delegate.
Dim plot_value_delegate As PlotValueDelegate
plot_value_delegate = AddressOf PlotValue
' Invoke the delegate on the main UI thread.
Me.Invoke(plot_value_delegate, args)
' We're done.
Exit Sub
End If
' Make the Bitmap and Graphics objects.
Dim wid As Integer = picGraph.ClientSize.Width
Dim hgt As Integer = picGraph.ClientSize.Height
Dim bm As New Bitmap(wid, hgt)
Dim gr As Graphics = Graphics.FromImage(bm)
' Move the old data one pixel to the left.
gr.DrawImage(picGraph.Image, -1, 0)
' Erase the right edge and draw guide lines.
gr.DrawLine(Pens.Blue, wid - 1, 0, wid - 1, hgt - 1)
For i As Integer = m_Ymid To picGraph.ClientSize.Height Step GRID_STEP
gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
Next i
For i As Integer = m_Ymid To 0 Step -GRID_STEP
gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
Next i
' Plot a new pixel.
gr.DrawLine(Pens.White, wid - 2, old_y, wid - 1, new_y)
' Display the result.
picGraph.Image = bm
picGraph.Refresh()
gr.Dispose()
End Sub
' Add a status string to txtStatus.
Private Delegate Sub AddStatusDelegate(ByVal txt As String)
Private Sub AddStatus(ByVal txt As String)
' See if we're on the worker thread and thus
' need to invoke the main UI thread.
If Me.InvokeRequired Then
' Make arguments for the delegate.
Dim args As Object() = {txt}
' Make the delegate.
Dim add_status_delegate As AddStatusDelegate
add_status_delegate = AddressOf AddStatus
' Invoke the delegate on the main UI thread.
Me.Invoke(add_status_delegate, args)
' We're done.
Exit Sub
End If
txtStatus.Text &= vbCrLf & txt
txtStatus.Select(txtStatus.Text.Length, 0)
txtStatus.ScrollToCaret()
End Sub
' Display the current time.
Private Sub tmrUpdateClock_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrUpdateClock.Tick
lblTime.Text = Now.ToString("T")
End Sub
End Class
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Public Class Form1
Inherits System.Windows.Forms.Form
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> _
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container
Me.lblTime = New System.Windows.Forms.Label
Me.txtStatus = New System.Windows.Forms.TextBox
Me.picGraph = New System.Windows.Forms.PictureBox
Me.btnGraph = New System.Windows.Forms.Button
Me.tmrUpdateClock = New System.Windows.Forms.Timer(Me.components)
CType(Me.picGraph, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'lblTime
'
Me.lblTime.Location = New System.Drawing.Point(208, 4)
Me.lblTime.Name = "lblTime"
Me.lblTime.Size = New System.Drawing.Size(80, 16)
Me.lblTime.TabIndex = 7
Me.lblTime.Text = "Label1"
Me.lblTime.TextAlign = System.Drawing.ContentAlignment.MiddleRight
'
'txtStatus
'
Me.txtStatus.Dock = System.Windows.Forms.DockStyle.Bottom
Me.txtStatus.Location = New System.Drawing.Point(0, 38)
Me.txtStatus.Multiline = True
Me.txtStatus.Name = "txtStatus"
Me.txtStatus.ReadOnly = True
Me.txtStatus.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
Me.txtStatus.Size = New System.Drawing.Size(292, 85)
Me.txtStatus.TabIndex = 6
Me.txtStatus.Text = "Ready"
'
'picGraph
'
Me.picGraph.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
Me.picGraph.Dock = System.Windows.Forms.DockStyle.Bottom
Me.picGraph.Location = New System.Drawing.Point(0, 123)
Me.picGraph.Name = "picGraph"
Me.picGraph.Size = New System.Drawing.Size(292, 150)
Me.picGraph.TabIndex = 5
Me.picGraph.TabStop = False
'
'btnGraph
'
Me.btnGraph.Location = New System.Drawing.Point(8, 4)
Me.btnGraph.Name = "btnGraph"
Me.btnGraph.Size = New System.Drawing.Size(48, 24)
Me.btnGraph.TabIndex = 4
Me.btnGraph.Text = "Graph"
'
'tmrUpdateClock
'
Me.tmrUpdateClock.Enabled = True
Me.tmrUpdateClock.Interval = 250
'
'Form1
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(292, 273)
Me.Controls.Add(Me.lblTime)
Me.Controls.Add(Me.txtStatus)
Me.Controls.Add(Me.picGraph)
Me.Controls.Add(Me.btnGraph)
Me.Name = "Form1"
Me.Text = "ThreadGraph"
CType(Me.picGraph, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Friend WithEvents lblTime As System.Windows.Forms.Label
Friend WithEvents txtStatus As System.Windows.Forms.TextBox
Friend WithEvents picGraph As System.Windows.Forms.PictureBox
Friend WithEvents btnGraph As System.Windows.Forms.Button
Friend WithEvents tmrUpdateClock As System.Windows.Forms.Timer
End Class
|