none
Draw Application, clear drawings? RRS feed

  • Question

  • Hellom ths is my code :)

        Dim Down = False

        Private Sub Form1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
            Down = True
        End Sub



        Private Sub Form1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
            If Down = True Then
                Me.CreateGraphics.FillEllipse(Brushes.Gray, e.X, e.Y, 6, 6)
            End If

        End Sub



        Private Sub Form1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
            Down = False
        End Sub

    I would like to have a button that clears all the graphics (drawings) on click. Is that possible?

    Thanks,

    Andreas.

    Friday, July 20, 2012 7:18 PM

Answers

  • Here is a very simple example that you can study.  This code demonstrates the use of a "buffer image" that the user draws to and is then drawn to the form.  It implements the same line drawing logic as you've posted above (drawing a series of circles), as well as a line-segment routine that uses a pen to draw short lines.  You can see the difference between the two with thick and thin lines.

    The code supports a few simple options through keyboard input:

       ESC = Clear drawing
       +    = Increase Pen Size
       -     = Decrease Pen Size
       L     = Line-style Pen
       D    = Dot-style Pen
       C    = Change Pen Color

    To use this example, start a new Windows Forms project and paste the following code over the default Form1 code:

    Public Class Form1
        Private _BufferImage As Image 'this is the image the user draws on
        Private _BufferContext As Graphics 'this is the graphics instance for drawing to the buffer image
        Private _IsPenDown As Boolean 'this flag tells us when the user wants to draw (is holding down the mouse button)
        Private _MouseDelta As Point 'this variable holds the previous mouse position, used for drawing lines
    
        Public Property PenSize As Single 'this property lets the user specify the thickness of the line being drawn
        Public Property PenColor As Color 'this property lets the user specify the color of the line being drawn
        Public Property PenStyle As PaintPenStyle 'this property lets the user specify the way in which the line is drawn
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            DoubleBuffered = True 'double buffering is required for smooth redrawing of the form (eliminates flicker)
            PenSize = 1 'initialize the pen size
            PenColor = Color.Blue 'initialize the pen color
            PenStyle = PaintPenStyle.Dot 'initialize the pen style
            Size = New Size(640, 480) 'resize the form - this causes the buffers to be created
            Me.Text = String.Format("Pen: Size: {0}, Color: {1}, Style: {2}", PenSize, PenColor, PenStyle) 'update the status text
        End Sub
    
        'handle the KeyUp event to respond to user option changes
        Protected Overrides Sub OnKeyUp(e As System.Windows.Forms.KeyEventArgs)
            MyBase.OnKeyUp(e)
            Select Case e.KeyCode
                Case Keys.Escape 'clear the drawing
                    _BufferContext.Clear(Color.White)
                    Invalidate()
                Case Keys.Oemplus, Keys.Add 'increase the pen size
                    If PenSize < 24 Then PenSize += 1
                Case Keys.OemMinus, Keys.Subtract 'decrease the pen size
                    If PenSize > 1 Then PenSize -= 1
                Case Keys.L 'switch to line style drawing
                    PenStyle = PaintPenStyle.Line
                Case Keys.D 'switch to dot style drawing
                    PenStyle = PaintPenStyle.Dot
                Case Keys.C 'allow the user to select a new color
                    Dim dlg As New ColorDialog
                    dlg.AnyColor = True
                    dlg.Color = PenColor
                    If dlg.ShowDialog = Windows.Forms.DialogResult.OK Then
                        PenColor = dlg.Color
                    End If
                    dlg.Dispose()
            End Select
            Me.Text = String.Format("Pen: Size: {0}, Color: {1}, Style: {2}", PenSize, PenColor, PenStyle) 'update the status text
        End Sub
    
        Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseDown(e)
            _IsPenDown = (e.Button = Windows.Forms.MouseButtons.Left) 'set the flag according to whether or not the left button is pressed
            _MouseDelta = e.Location 'record the current mouse location
        End Sub
    
        'define very simple drawing logic; each pen style has its own weakness with various size pens
        'the results could be improved by calculating intermittent locations when the mouse delta is large,
        'or by tracking mouse locations and calculating curves; a GraphicsPath could potentially be used as well
        Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseMove(e)
            If _IsPenDown Then 'if the drawing flag is set
                If PenStyle = PaintPenStyle.Dot Then 'if the dot style is selected (better for thick lines)
                    Using fillBrush As New SolidBrush(PenColor) 'create a solid brush for painting
                        Dim halfSize As Single = PenSize / 2 'determine half the size of the brush
                        _BufferContext.FillEllipse(fillBrush, e.X - halfSize, e.Y - halfSize, PenSize, PenSize) 'draw a filled circle centered on the mouse position
                    End Using
                ElseIf PenStyle = PaintPenStyle.Line Then 'if the line style is selected (better for thin lines)
                    If Math.Sqrt((e.X - _MouseDelta.X) ^ 2 + (e.Y - _MouseDelta.Y) ^ 2) >= PenSize Then 'ensure the mouse has moved further than the pen size
                        Using linePen As New Pen(PenColor, PenSize) 'create a pen for painting
                            _BufferContext.DrawLine(linePen, _MouseDelta, e.Location) 'draw a line between the previous and current mouse positions
                        End Using
                        _MouseDelta = e.Location 'update the previous mouse position to the current
                    End If
                End If
                Invalidate() 'redraw the form
            End If
        End Sub
    
        Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseUp(e)
            _IsPenDown = False 'clear the drawing flag
        End Sub
    
        Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            If _BufferImage IsNot Nothing Then 'if there is currently a buffer image
                e.Graphics.DrawImage(_BufferImage, Point.Empty) 'draw the buffer image to the form
            End If
        End Sub
    
        Protected Overrides Sub OnSizeChanged(e As System.EventArgs)
            MyBase.OnSizeChanged(e)
            If _BufferContext IsNot Nothing Then _BufferContext.Dispose() 'destroy the old graphics object, if any
            Dim newBuffer As New Bitmap(ClientSize.Width, ClientSize.Height) 'create a new buffer the size of the form's client area
            _BufferContext = Graphics.FromImage(newBuffer)  'set the buffer context graphics object to the new buffer image
            _BufferContext.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias 'improve quality of drawing
            _BufferContext.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality 'improve quality of drawing
    
            _BufferContext.Clear(Color.White) 'clear the new buffer image
            If _BufferImage IsNot Nothing Then 'if there is an old buffer image, draw it to the new one
                _BufferContext.DrawImage(_BufferImage, Point.Empty)
                _BufferImage.Dispose() 'destroy the old buffer image
            End If
            _BufferImage = newBuffer 'set the new buffer image
        End Sub
    
        'Define two different pen styles for drawing
        Public Enum PaintPenStyle
            Dot 'lines are drawn as a series of circles
            Line 'lines are draw as a segment between two points
        End Enum
    End Class
     


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Andreas98cool Sunday, July 22, 2012 8:46 PM
    Friday, July 20, 2012 10:42 PM
    Moderator
  • "Is there a way that you can make it work when the Form, has a Picture as background?"

    Paint that picture onto _BufferImage as the first step after creating it. EDIT: ....and it's created in the line

       Dim newBuffer As New Bitmap(ClientSize.Width, ClientSize.Height)


    Armin


    Saturday, July 21, 2012 2:08 PM

All replies

  •  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.Refresh()
        End Sub


    You've taught me everything I know but not everything you know.

    Friday, July 20, 2012 8:15 PM
  • You are using the wrong way to draw on your form.

    If you noticed: minimize the form with the drawing and get it back to normal ... Oups, the drawing has disappeared !!! :(

    You need to draw in the paint event, using e.Graphics

    (Also, use Option Strict On) ... way better to avoid some hard to debug bugs

    Friday, July 20, 2012 8:30 PM
  •  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Me.Refresh()
        End Sub


    You've taught me everything I know but not everything you know.

    Thank you so much :)
    Friday, July 20, 2012 9:38 PM
  • You are using the wrong way to draw on your form.

    If you noticed: minimize the form with the drawing and get it back to normal ... Oups, the drawing has disappeared !!! :(

    You need to draw in the paint event, using e.Graphics

    (Also, use Option Strict On) ... way better to avoid some hard to debug bugs

    Thank you :)
    Friday, July 20, 2012 9:38 PM
  • Here is a very simple example that you can study.  This code demonstrates the use of a "buffer image" that the user draws to and is then drawn to the form.  It implements the same line drawing logic as you've posted above (drawing a series of circles), as well as a line-segment routine that uses a pen to draw short lines.  You can see the difference between the two with thick and thin lines.

    The code supports a few simple options through keyboard input:

       ESC = Clear drawing
       +    = Increase Pen Size
       -     = Decrease Pen Size
       L     = Line-style Pen
       D    = Dot-style Pen
       C    = Change Pen Color

    To use this example, start a new Windows Forms project and paste the following code over the default Form1 code:

    Public Class Form1
        Private _BufferImage As Image 'this is the image the user draws on
        Private _BufferContext As Graphics 'this is the graphics instance for drawing to the buffer image
        Private _IsPenDown As Boolean 'this flag tells us when the user wants to draw (is holding down the mouse button)
        Private _MouseDelta As Point 'this variable holds the previous mouse position, used for drawing lines
    
        Public Property PenSize As Single 'this property lets the user specify the thickness of the line being drawn
        Public Property PenColor As Color 'this property lets the user specify the color of the line being drawn
        Public Property PenStyle As PaintPenStyle 'this property lets the user specify the way in which the line is drawn
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            DoubleBuffered = True 'double buffering is required for smooth redrawing of the form (eliminates flicker)
            PenSize = 1 'initialize the pen size
            PenColor = Color.Blue 'initialize the pen color
            PenStyle = PaintPenStyle.Dot 'initialize the pen style
            Size = New Size(640, 480) 'resize the form - this causes the buffers to be created
            Me.Text = String.Format("Pen: Size: {0}, Color: {1}, Style: {2}", PenSize, PenColor, PenStyle) 'update the status text
        End Sub
    
        'handle the KeyUp event to respond to user option changes
        Protected Overrides Sub OnKeyUp(e As System.Windows.Forms.KeyEventArgs)
            MyBase.OnKeyUp(e)
            Select Case e.KeyCode
                Case Keys.Escape 'clear the drawing
                    _BufferContext.Clear(Color.White)
                    Invalidate()
                Case Keys.Oemplus, Keys.Add 'increase the pen size
                    If PenSize < 24 Then PenSize += 1
                Case Keys.OemMinus, Keys.Subtract 'decrease the pen size
                    If PenSize > 1 Then PenSize -= 1
                Case Keys.L 'switch to line style drawing
                    PenStyle = PaintPenStyle.Line
                Case Keys.D 'switch to dot style drawing
                    PenStyle = PaintPenStyle.Dot
                Case Keys.C 'allow the user to select a new color
                    Dim dlg As New ColorDialog
                    dlg.AnyColor = True
                    dlg.Color = PenColor
                    If dlg.ShowDialog = Windows.Forms.DialogResult.OK Then
                        PenColor = dlg.Color
                    End If
                    dlg.Dispose()
            End Select
            Me.Text = String.Format("Pen: Size: {0}, Color: {1}, Style: {2}", PenSize, PenColor, PenStyle) 'update the status text
        End Sub
    
        Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseDown(e)
            _IsPenDown = (e.Button = Windows.Forms.MouseButtons.Left) 'set the flag according to whether or not the left button is pressed
            _MouseDelta = e.Location 'record the current mouse location
        End Sub
    
        'define very simple drawing logic; each pen style has its own weakness with various size pens
        'the results could be improved by calculating intermittent locations when the mouse delta is large,
        'or by tracking mouse locations and calculating curves; a GraphicsPath could potentially be used as well
        Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseMove(e)
            If _IsPenDown Then 'if the drawing flag is set
                If PenStyle = PaintPenStyle.Dot Then 'if the dot style is selected (better for thick lines)
                    Using fillBrush As New SolidBrush(PenColor) 'create a solid brush for painting
                        Dim halfSize As Single = PenSize / 2 'determine half the size of the brush
                        _BufferContext.FillEllipse(fillBrush, e.X - halfSize, e.Y - halfSize, PenSize, PenSize) 'draw a filled circle centered on the mouse position
                    End Using
                ElseIf PenStyle = PaintPenStyle.Line Then 'if the line style is selected (better for thin lines)
                    If Math.Sqrt((e.X - _MouseDelta.X) ^ 2 + (e.Y - _MouseDelta.Y) ^ 2) >= PenSize Then 'ensure the mouse has moved further than the pen size
                        Using linePen As New Pen(PenColor, PenSize) 'create a pen for painting
                            _BufferContext.DrawLine(linePen, _MouseDelta, e.Location) 'draw a line between the previous and current mouse positions
                        End Using
                        _MouseDelta = e.Location 'update the previous mouse position to the current
                    End If
                End If
                Invalidate() 'redraw the form
            End If
        End Sub
    
        Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseUp(e)
            _IsPenDown = False 'clear the drawing flag
        End Sub
    
        Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            If _BufferImage IsNot Nothing Then 'if there is currently a buffer image
                e.Graphics.DrawImage(_BufferImage, Point.Empty) 'draw the buffer image to the form
            End If
        End Sub
    
        Protected Overrides Sub OnSizeChanged(e As System.EventArgs)
            MyBase.OnSizeChanged(e)
            If _BufferContext IsNot Nothing Then _BufferContext.Dispose() 'destroy the old graphics object, if any
            Dim newBuffer As New Bitmap(ClientSize.Width, ClientSize.Height) 'create a new buffer the size of the form's client area
            _BufferContext = Graphics.FromImage(newBuffer)  'set the buffer context graphics object to the new buffer image
            _BufferContext.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias 'improve quality of drawing
            _BufferContext.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality 'improve quality of drawing
    
            _BufferContext.Clear(Color.White) 'clear the new buffer image
            If _BufferImage IsNot Nothing Then 'if there is an old buffer image, draw it to the new one
                _BufferContext.DrawImage(_BufferImage, Point.Empty)
                _BufferImage.Dispose() 'destroy the old buffer image
            End If
            _BufferImage = newBuffer 'set the new buffer image
        End Sub
    
        'Define two different pen styles for drawing
        Public Enum PaintPenStyle
            Dot 'lines are drawn as a series of circles
            Line 'lines are draw as a segment between two points
        End Enum
    End Class
     


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Andreas98cool Sunday, July 22, 2012 8:46 PM
    Friday, July 20, 2012 10:42 PM
    Moderator
  • Here is a very simple example that you can study.  This code demonstrates the use of a "buffer image" that the user draws to and is then drawn to the form.  It implements the same line drawing logic as you've posted above (drawing a series of circles), as well as a line-segment routine that uses a pen to draw short lines.  You can see the difference between the two with thick and thin lines.

    The code supports a few simple options through keyboard input:

       ESC = Clear drawing
       +    = Increase Pen Size
       -     = Decrease Pen Size
       L     = Line-style Pen
       D    = Dot-style Pen
       C    = Change Pen Color

    To use this example, start a new Windows Forms project and paste the following code over the default Form1 code:

    Public Class Form1
        Private _BufferImage As Image 'this is the image the user draws on
        Private _BufferContext As Graphics 'this is the graphics instance for drawing to the buffer image
        Private _IsPenDown As Boolean 'this flag tells us when the user wants to draw (is holding down the mouse button)
        Private _MouseDelta As Point 'this variable holds the previous mouse position, used for drawing lines
    
        Public Property PenSize As Single 'this property lets the user specify the thickness of the line being drawn
        Public Property PenColor As Color 'this property lets the user specify the color of the line being drawn
        Public Property PenStyle As PaintPenStyle 'this property lets the user specify the way in which the line is drawn
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            DoubleBuffered = True 'double buffering is required for smooth redrawing of the form (eliminates flicker)
            PenSize = 1 'initialize the pen size
            PenColor = Color.Blue 'initialize the pen color
            PenStyle = PaintPenStyle.Dot 'initialize the pen style
            Size = New Size(640, 480) 'resize the form - this causes the buffers to be created
            Me.Text = String.Format("Pen: Size: {0}, Color: {1}, Style: {2}", PenSize, PenColor, PenStyle) 'update the status text
        End Sub
    
        'handle the KeyUp event to respond to user option changes
        Protected Overrides Sub OnKeyUp(e As System.Windows.Forms.KeyEventArgs)
            MyBase.OnKeyUp(e)
            Select Case e.KeyCode
                Case Keys.Escape 'clear the drawing
                    _BufferContext.Clear(Color.White)
                    Invalidate()
                Case Keys.Oemplus, Keys.Add 'increase the pen size
                    If PenSize < 24 Then PenSize += 1
                Case Keys.OemMinus, Keys.Subtract 'decrease the pen size
                    If PenSize > 1 Then PenSize -= 1
                Case Keys.L 'switch to line style drawing
                    PenStyle = PaintPenStyle.Line
                Case Keys.D 'switch to dot style drawing
                    PenStyle = PaintPenStyle.Dot
                Case Keys.C 'allow the user to select a new color
                    Dim dlg As New ColorDialog
                    dlg.AnyColor = True
                    dlg.Color = PenColor
                    If dlg.ShowDialog = Windows.Forms.DialogResult.OK Then
                        PenColor = dlg.Color
                    End If
                    dlg.Dispose()
            End Select
            Me.Text = String.Format("Pen: Size: {0}, Color: {1}, Style: {2}", PenSize, PenColor, PenStyle) 'update the status text
        End Sub
    
        Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseDown(e)
            _IsPenDown = (e.Button = Windows.Forms.MouseButtons.Left) 'set the flag according to whether or not the left button is pressed
            _MouseDelta = e.Location 'record the current mouse location
        End Sub
    
        'define very simple drawing logic; each pen style has its own weakness with various size pens
        'the results could be improved by calculating intermittent locations when the mouse delta is large,
        'or by tracking mouse locations and calculating curves; a GraphicsPath could potentially be used as well
        Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseMove(e)
            If _IsPenDown Then 'if the drawing flag is set
                If PenStyle = PaintPenStyle.Dot Then 'if the dot style is selected (better for thick lines)
                    Using fillBrush As New SolidBrush(PenColor) 'create a solid brush for painting
                        Dim halfSize As Single = PenSize / 2 'determine half the size of the brush
                        _BufferContext.FillEllipse(fillBrush, e.X - halfSize, e.Y - halfSize, PenSize, PenSize) 'draw a filled circle centered on the mouse position
                    End Using
                ElseIf PenStyle = PaintPenStyle.Line Then 'if the line style is selected (better for thin lines)
                    If Math.Sqrt((e.X - _MouseDelta.X) ^ 2 + (e.Y - _MouseDelta.Y) ^ 2) >= PenSize Then 'ensure the mouse has moved further than the pen size
                        Using linePen As New Pen(PenColor, PenSize) 'create a pen for painting
                            _BufferContext.DrawLine(linePen, _MouseDelta, e.Location) 'draw a line between the previous and current mouse positions
                        End Using
                        _MouseDelta = e.Location 'update the previous mouse position to the current
                    End If
                End If
                Invalidate() 'redraw the form
            End If
        End Sub
    
        Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseUp(e)
            _IsPenDown = False 'clear the drawing flag
        End Sub
    
        Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
            MyBase.OnPaint(e)
            If _BufferImage IsNot Nothing Then 'if there is currently a buffer image
                e.Graphics.DrawImage(_BufferImage, Point.Empty) 'draw the buffer image to the form
            End If
        End Sub
    
        Protected Overrides Sub OnSizeChanged(e As System.EventArgs)
            MyBase.OnSizeChanged(e)
            If _BufferContext IsNot Nothing Then _BufferContext.Dispose() 'destroy the old graphics object, if any
            Dim newBuffer As New Bitmap(ClientSize.Width, ClientSize.Height) 'create a new buffer the size of the form's client area
            _BufferContext = Graphics.FromImage(newBuffer)  'set the buffer context graphics object to the new buffer image
            _BufferContext.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias 'improve quality of drawing
            _BufferContext.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality 'improve quality of drawing
    
            _BufferContext.Clear(Color.White) 'clear the new buffer image
            If _BufferImage IsNot Nothing Then 'if there is an old buffer image, draw it to the new one
                _BufferContext.DrawImage(_BufferImage, Point.Empty)
                _BufferImage.Dispose() 'destroy the old buffer image
            End If
            _BufferImage = newBuffer 'set the new buffer image
        End Sub
    
        'Define two different pen styles for drawing
        Public Enum PaintPenStyle
            Dot 'lines are drawn as a series of circles
            Line 'lines are draw as a segment between two points
        End Enum
    End Class
     


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Thank you :) Is there a way that you can make it work when the Form, has a Picture as background? I know this is a lot to ask for, and if you don't have the time, then it's okay :)

    Is it possible that the hotkeys won't work if the form has no border?, because the hotkeys won't work on my "older" project, and there is no error messages.

    Saturday, July 21, 2012 9:20 AM
  • "Is there a way that you can make it work when the Form, has a Picture as background?"

    Paint that picture onto _BufferImage as the first step after creating it. EDIT: ....and it's created in the line

       Dim newBuffer As New Bitmap(ClientSize.Width, ClientSize.Height)


    Armin


    Saturday, July 21, 2012 2:08 PM
  • When you say Picture, did you mean a PictureBox or just a BackgroundImage?

    If your form has a PictureBox then it is likely the focused control and the form would need its KeyPreview property set to True to make the key press code work.  When another control has focus (such as a PictureBox), the form does not see any key events unless you tell it to watch for them.

    If you were just referring to having an Image assigned to the BackgroundImage property of the form, then do as Armin suggested and use the _BufferContext to draw this background image to the _BufferImage whenever it is recreated (right after the line _BufferContext.Clear(Color.White)).

    If you want to do this with a PictureBox, then you would refactor the code to move the mouse and paint routines into the PictureBox event handlers, remove the form doublebuffering, and set the form's KeyPreview.  The adjusted code might be something like:

    Public Class Form1
        Friend WithEvents CanvasPictureBox As New PictureBox With {.Dock = DockStyle.Fill, .SizeMode = PictureBoxSizeMode.Normal}
    
        Private _BufferImage As Image 'this is the image the user draws on
        Private _BufferContext As Graphics 'this is the graphics instance for drawing to the buffer image
        Private _IsPenDown As Boolean 'this flag tells us when the user wants to draw (is holding down the mouse button)
        Private _MouseDelta As Point 'this variable holds the previous mouse position, used for drawing lines
    
        Public Property PenSize As Single 'this property lets the user specify the thickness of the line being drawn
        Public Property PenColor As Color 'this property lets the user specify the color of the line being drawn
        Public Property PenStyle As PaintPenStyle 'this property lets the user specify the way in which the line is drawn
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            Controls.Add(CanvasPictureBox)
            KeyPreview = True 'The form needs to preview the key events because the picture box will have focus
            PenSize = 1 'initialize the pen size
            PenColor = Color.Blue 'initialize the pen color
            PenStyle = PaintPenStyle.Dot 'initialize the pen style
            Size = New Size(640, 480) 'resize the form - this causes the buffers to be created
            Me.Text = String.Format("Pen: Size: {0}, Color: {1}, Style: {2}", PenSize, PenColor, PenStyle) 'update the status text
        End Sub
    
        'handle the KeyUp event to respond to user option changes
        Protected Overrides Sub OnKeyUp(e As System.Windows.Forms.KeyEventArgs)
            MyBase.OnKeyUp(e)
            Select Case e.KeyCode
                Case Keys.Escape 'clear the drawing
                    _BufferContext.Clear(Color.White)
                    Invalidate()
                Case Keys.Oemplus, Keys.Add 'increase the pen size
                    If PenSize < 24 Then PenSize += 1
                Case Keys.OemMinus, Keys.Subtract 'decrease the pen size
                    If PenSize > 1 Then PenSize -= 1
                Case Keys.L 'switch to line style drawing
                    PenStyle = PaintPenStyle.Line
                Case Keys.D 'switch to dot style drawing
                    PenStyle = PaintPenStyle.Dot
                Case Keys.C 'allow the user to select a new color
                    Dim dlg As New ColorDialog
                    dlg.AnyColor = True
                    dlg.Color = PenColor
                    If dlg.ShowDialog = Windows.Forms.DialogResult.OK Then
                        PenColor = dlg.Color
                    End If
                    dlg.Dispose()
            End Select
            Me.Text = String.Format("Pen: Size: {0}, Color: {1}, Style: {2}", PenSize, PenColor, PenStyle) 'update the status text
        End Sub
    
        Protected Overrides Sub OnSizeChanged(e As System.EventArgs)
            MyBase.OnSizeChanged(e)
            If _BufferContext IsNot Nothing Then _BufferContext.Dispose() 'destroy the old graphics object, if any
            Dim newBuffer As New Bitmap(ClientSize.Width, ClientSize.Height) 'create a new buffer the size of the form's client area
            _BufferContext = Graphics.FromImage(newBuffer)  'set the buffer context graphics object to the new buffer image
            _BufferContext.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias 'improve quality of drawing
            _BufferContext.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality 'improve quality of drawing
    
            _BufferContext.Clear(Color.White) 'clear the new buffer image
            If _BufferImage IsNot Nothing Then 'if there is an old buffer image, draw it to the new one
                _BufferContext.DrawImage(_BufferImage, Point.Empty)
                _BufferImage.Dispose() 'destroy the old buffer image
            End If
            _BufferImage = newBuffer 'set the new buffer image
        End Sub
    
        Private Sub CanvasPictureBox_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles CanvasPictureBox.MouseDown
            _IsPenDown = (e.Button = Windows.Forms.MouseButtons.Left) 'set the flag according to whether or not the left button is pressed
            _MouseDelta = e.Location 'record the current mouse location
        End Sub
    
        Private Sub CanvasPictureBox_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles CanvasPictureBox.MouseMove
            If _IsPenDown Then 'if the drawing flag is set
                If PenStyle = PaintPenStyle.Dot Then 'if the dot style is selected (better for thick lines)
                    Using fillBrush As New SolidBrush(PenColor) 'create a solid brush for painting
                        Dim halfSize As Single = PenSize / 2 'determine half the size of the brush
                        _BufferContext.FillEllipse(fillBrush, e.X - halfSize, e.Y - halfSize, PenSize, PenSize) 'draw a filled circle centered on the mouse position
                    End Using
                ElseIf PenStyle = PaintPenStyle.Line Then 'if the line style is selected (better for thin lines)
                    If Math.Sqrt((e.X - _MouseDelta.X) ^ 2 + (e.Y - _MouseDelta.Y) ^ 2) >= PenSize Then 'ensure the mouse has moved further than the pen size
                        Using linePen As New Pen(PenColor, PenSize) 'create a pen for painting
                            _BufferContext.DrawLine(linePen, _MouseDelta, e.Location) 'draw a line between the previous and current mouse positions
                        End Using
                        _MouseDelta = e.Location 'update the previous mouse position to the current
                    End If
                End If
                CanvasPictureBox.Invalidate() 'redraw the form
            End If
        End Sub
    
        Private Sub CanvasPictureBox_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles CanvasPictureBox.MouseUp
            _IsPenDown = False 'clear the drawing flag
        End Sub
    
        Private Sub CanvasPictureBox_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles CanvasPictureBox.Paint
            If _BufferImage IsNot Nothing Then 'if there is currently a buffer image
                e.Graphics.DrawImage(_BufferImage, Point.Empty) 'draw the buffer image to the form
            End If
        End Sub
    
        'Define two different pen styles for drawing
        Public Enum PaintPenStyle
            Dot 'lines are drawn as a series of circles
            Line 'lines are draw as a segment between two points
        End Enum
    
    End Class
    


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Saturday, July 21, 2012 4:23 PM
    Moderator
  • Thanks to all :)
    Sunday, July 22, 2012 8:46 PM