Click here to Skip to main content
15,919,749 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am writing a small screen saver program to draw lines on screen using a timer.
For this, two data points A & B are read from a file and the (x,y) coordinates in pixels for A & B computed.
The line from point A to B is drawn using graphics.drawline method. So far it works fine.
The next line from point B to C is drawn similarly.
The problem is that when line BC is drawn, the line AB is not retained onscreen.
How can I draw line segments BC, CD, DE and so on using a timer while retaining the previous ones ?
I am using VB 2010.

Essentially, I'm drawing a line made up of numerous segments, where each segment is to to be drawn using timer tick event.

What I have tried:

I've tried without using 'refresh' in the timer.tick sub.

here's the code

Imports Microsoft.Win32
Imports Microsoft.VisualBasic
Imports System.Math
Imports System.Drawing.Drawing2D

Public Class frmscr
    Dim greenPen2 As New Pen(Color.Green, 5)
    Dim grayPen1 As New Pen(Color.Gray, 1)

    Dim WithEvents tmrClock As New Timer

    Public point1 As New Point
    Public point2 As New Point

    Private Sub frmscr_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        'Read input data file,reads array of GR
        Call ReadTxtInputFile()

        'Get screen size in pixels
        scrW = Screen.PrimaryScreen.Bounds.Width.ToString
        scrH = Screen.PrimaryScreen.Bounds.Height.ToString
        Windows.Forms.Cursor.Hide()

        'initialize variable i
        i = 1

        'Compute screen x,y of start point in pixels
        'where xo1p is x offset in pixels
        'gr(0) is 1st point of array
        't1Wp is width of 1st vertical track
        'grmax & grmin are max & min values of parameter array value gr(i)
        xGR0 = xo1p + t1Wp * (GR(0) - GRmin) / (GRmax - GRmin)
        yGR0 = 0

        'set initial values of second point & its backup value
        xGR1 = xGR0
        xGR2 = xGR0
        yGR1 = yGR0
        yGR2 = yGR0


        ' Set Pen Styles
        greenPen2.DashStyle = Drawing2D.DashStyle.Solid
        grayPen1.DashStyle = Drawing2D.DashStyle.DashDotDot

        'timer
        tmrClock.Enabled = True
        tmrClock.Interval = 50
        tmrClock.Start()


    End Sub

    Private Sub frmscr_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Windows.Forms.Cursor.Show()
    End Sub

    Private Sub frmscr_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        Me.Close()
    End Sub

    Private Sub frmscr_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
        Me.Close()
    End Sub

    Private Sub frmscr_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
        Me.Close()
    End Sub

    Private Sub frmscr_MouseDoubleClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDoubleClick
        Me.Close()
    End Sub

    Private Sub frmscr_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        Static OldX As Integer
        Static OldY As Integer
        'Determines whether the mouse was moved and whetherthe movement was large.
        ''If so, the screen saver is ended.
        If (OldX > 0 And OldY > 0) And (Math.Abs(e.X - OldX) > 3 Or Math.Abs(e.Y - OldY) > 3) Then
            Me.Close()
        End If
        ''Assigns the current X and Y locations to OldX and OldY.
        OldX = e.X
        OldY = e.Y
    End Sub
    Private Sub DrawGrids(ByVal e As PaintEventArgs)

        ' Define Vertical grid points : track width in % : default values
        t1W = 15

        'track width in pixels
        t1Wp = t1W * scrW / 100

        'track x offset in pixels
        xo1p = 0


        ' Create points that define line.
        'vertical grid
        Dim ii As Integer

        For ii = 1 To 4 Step 1
            Dim point1 As New Point(t1Wp / 10 * ii, 0)
            Dim point2 As New Point(t1Wp / 10 * ii, scrH)
            e.Graphics.DrawLine(grayPen1, point1, point2)
        Next ii
        For ii = 6 To 9 Step 1
            Dim point1 As New Point(t1Wp / 10 * ii, 0)
            Dim point2 As New Point(t1Wp / 10 * ii, scrH)
            e.Graphics.DrawLine(grayPen1, point1, point2)
        Next ii

        For ii = 0 To 10 Step 5
            Dim point1 As New Point(t1Wp / 10 * ii, 0)
            Dim point2 As New Point(t1Wp / 10 * ii, scrH)
            e.Graphics.DrawLine(Pens.Blue, point1, point2)
        Next ii


        'horizontal grid
        nhThk = scrH / 75


        For ii = 1 To nhThk Step 1
            Dim point1 As New Point(0, 75 * ii)
            Dim point2 As New Point(t1Wp, 75 * ii)

            e.Graphics.DrawLine(grayPen1, point1, point2)
        Next ii

    End Sub


    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

        e.Graphics.SmoothingMode = SmoothingMode.HighQuality

        'routine to draw the grid
        DrawGrids(e)

        'routine to draw the curve
        DrawCurve(e)

    End Sub

    Private Sub DrawCurve(ByVal e As PaintEventArgs)

        e.Graphics.DrawLine(greenPen2, xGR1, yGR1, xGR2, yGR2)

        'stores 
        xGR1 = xGR2
        yGR1 = yGR2

        'clear screen after line reaches screen bottom
        If i >= (scrH / 3.75) - 1 Then
            i = 1

            ClearForm(e)

            yGR1 = 0

        End If
    End Sub

    Private Sub ClearForm(ByVal e As PaintEventArgs)
        'To clear the screen before continuing drawing
        e.Graphics.Clear(Color.Black)
    End Sub

    Private Sub tmrClock_Tick(ByVal sender As System.Object,
     ByVal e As System.EventArgs) Handles tmrClock.Tick

        'increment variable i to compute screen location of next point
        i = i + 1

        'computes screen location (x,y) of next point 
        xGR2 = xo1p + t1Wp * (GR(i) - GRmin) / (GRmax - GRmin)
        yGR2 = (DEPT(i) - DepthFirst) * 25

        Refresh()
    End Sub

End Class
Posted
Updated 28-Feb-17 14:13pm
v3
Comments
Graeme_Grant 21-Feb-17 3:42am    
We are not here to write your code for you. How can we can help you if you don't show us what you have tried...
Richard MacCutchan 21-Feb-17 3:55am    
Ensure that you draw all lines within the same iteration of the paint routine.
Ralf Meier 27-Feb-17 5:39am    
I have seen your code.
My Question : where are all your Variables definded ?
Have you tried to work without the method "ClearForm" in DrawCurve ?
Member 10118655 27-Feb-17 12:38pm    
All my variables are defined as public in a separate module.
Yes, I've tried it without 'ClearForm' method.
Ralf Meier 27-Feb-17 14:37pm    
OK ... then provide this code-part too ...
Then I could simulate what is going on ...

Here is a working mock:
VB
Imports System.Drawing.Text

Public Class Form1
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Refresh()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        DrawLines(e.Graphics)
    End Sub

    Dim r As Random = New Random()
    Dim pens As Pen() = New Pen(4) _
        {
            New Pen(Brushes.Blue),
            New Pen(Brushes.Red),
            New Pen(Brushes.Green),
            New Pen(Brushes.Cyan),
            New Pen(Brushes.Purple)
        }

    Private Sub DrawLines(ByVal gr As Graphics)

        gr.TextRenderingHint = TextRenderingHint.AntiAlias

        For i As Integer = 1 To 5
            gr.DrawLine(pens(r.Next(0, 4)), r.Next(0, 200), r.Next(0, 200), r.Next(0, 200), r.Next(0, 200))
        Next

    End Sub

End Class

I suggest that there is an issue with your code.
 
Share this answer
 
Comments
Member 10118655 28-Feb-17 12:42pm    
Thanks, but this is not what I want to do. Essentially, I'm drawing a line made up of numerous segments, where each segment is to to be drawn using timer tick event. The previous segments must stay.
Graeme_Grant 1-Mar-17 20:49pm    
Check out Solution 2 - It does fix your problem.
Graeme_Grant 28-Feb-17 13:50pm    
Then your problem is that you're not retaining a snapshot of the graphics object and adding to it but drawing on a new graphics object each time. This is why you don't see any drawing history.
"where each segment is to to be drawn using timer tick event" - The issue is that you're not retaining a snapshot of the graphics object and adding to it but drawing on a new graphics object each time. This is why you don't see any drawing history. (copy of answer from Solution 1 comments).

Here is a modified version of Solution 1:
VB
Imports System.Drawing.Imaging
Imports System.Drawing.Text

Public Class Form1



    Private myBitmap As Bitmap

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Refresh()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        DrawLines(e.Graphics)
    End Sub

    Dim r As Random = New Random()
    Dim pens As Pen() = New Pen(4) _
        {
            New Pen(Brushes.Blue),
            New Pen(Brushes.Red),
            New Pen(Brushes.Green),
            New Pen(Brushes.Cyan),
            New Pen(Brushes.Purple)
        }

    Private Sub DrawLines(ByVal gr As Graphics)

        Dim myG As Graphics

        If myBitmap Is Nothing Then
            myBitmap = New Bitmap(ClientRectangle.Width, ClientRectangle.Height, PixelFormat.Format24bppRgb)
            myG = Graphics.FromImage(myBitmap)
            myG.Clear(Color.Black)
        Else
            myG = Graphics.FromImage(myBitmap)
        End If

        myG.TextRenderingHint = TextRenderingHint.AntiAlias
        myG.DrawLine(pens(r.Next(0, 4)), r.Next(0, 200), r.Next(0, 200), r.Next(0, 200), r.Next(0, 200))

        gr.DrawImage(myBitmap, 0, 0, myBitmap.Width, myBitmap.Height)

        myG.Dispose()

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        BackColor = Color.Black
    End Sub
End Class
 
Share this answer
 
Comments
Member 10118655 2-Mar-17 12:07pm    
Thanks. I'll try your solution methodology in my code and let you know the result.
Graeme_Grant 2-Mar-17 12:11pm    
You are welcome...
Graeme_Grant 4-Mar-17 22:28pm    
How did you go?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900