Dynamically change pen color and color when pressed

Program

I am playing and learning graphics with a visual basic (from C ++). I made a program and I want to do two things: draw when the left mouse button is pressed and stop when released, and also I want to change the color of the pen using a colordialog.After a few hours of frustration, I still have not dealt with these two problems.

Code (snippet)

Private obj As Graphics
Dim rect As Rectangle

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    obj = RichTextBox1.CreateGraphics
End Sub

Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
    obj.Dispose()
End Sub

 Private Sub RichTextBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RichTextBox1.MouseMove

    With rect
        .X = e.X
        .Y = e.Y
        .Width = TrackBar1.Value
        .Height = TrackBar1.Value
    End With

    If ToolStripButton1.Checked = True Then
        obj.DrawEllipse(Pens.Black, rect)
    ElseIf ToolStripButton2.Checked = True Then
        obj.DrawRectangle(Pens.Black, rect)
    End If

    ToolStripStatusLabel2.Text = (e.X & ", " & e.Y)

End Sub

      

Past attempts (and frustrations)

My idea originally was to do this:

Dim myPen = New Pen(ButtonWithDC1.BackColor)

      

But it gave me an error message. I looked at the Microsoft documentation, but it wasn't helpful for what I am trying to do. I can create the handle just fine, but I would like the user to be able to change the color while the application is running.

GUI layout

enter image description here

I have no attempt to solve another problem (drawing on mouse down, not just moving the mouse - like a normal paint program), I don't even have a starting point for this solution. Thanks everyone in advance.

+3


source to share


2 answers


Your question is a little more in demand than you think and SO is not fond of multiple questions per post (not in your interest in nest - someone might know A, not B, so don't bother answering).

To draw a Mousemove when the mouse is down, you need to track when the mouse is down (question A):

Private _mouseDown As Boolean
Private _mouseLoc As Point 
Private _mouseNewLoc As Point

sub Ctl_MouseDown(sender...
  ' ToDo: add logic to check which button....
   _mouseDown = True 
   _mouseLoc = New Point(e.X, e.Y)
End Sub

sub Ctl_MouseUp(sender...
   _mouseDown = False
End Sub

      

Then mousemove can be used to grab the current location



Sub Ctl_MouseMove(sender....
     If _mouseDn Then
          _mouseNewLoc = New Point(e.X, e.Y)
          Ctl.invalidate    ' call to paint
     End If
End Sub

' selected color from dialog or whereever
Private myColor As Color
Sub Ctl_Paint(sender....

    If _mouseDn Then
        ' Pen ctor is overloaded...(Question B)
        Using p As New Pen(myColor)
            e.Graphics.DrawLine(p, _mouseLoc, _mouseNewLoc)
           ' plus more....
        End Using
    End If

      

This only applies to the questions posed; the big problem you face is keeping track of what has already been drawn. This will only draw the line when the mouse is not working, but for a polygon or shape, you need to add code to redraw those parts. Either a list of points that make up the polygon, or maybe save what you have for the bitmap and add to it. This is a bit outside the scope of the question and depends on application factors. You also need to start / stop drawing, or indicate when to stop adding lines or ovals or something (ovals are simple: one at a time, the lines in the shape of a shape will take some work).

In any case, all painting must happen in the Paint (or OnPaint) event if you want to see the shape / drawing / image being rendered.

+2


source


Place a button (Button1) and an image (PictureBox1) on the form, also add a colordialog (ColorDialog1).

This code will allow you to draw an image and select a color using the color you pick from the colordialog. The MouseDown event records the flag of the mouse button and saves the last location. MouseUp does a similar thing. MouseMove is actually drawing. Use string and last location.



Public Class Form1

    Private myColor As Color = Color.Black
    Private mouseIsDown As Boolean = False
    Private previousLocation As System.Nullable(Of System.Drawing.Point) = Nothing

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        myColor = If(ColorDialog1.ShowDialog() = Windows.Forms.DialogResult.OK, ColorDialog1.Color, myColor)
    End Sub

    Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
        mouseIsDown = True
        previousLocation = e.Location
    End Sub

    Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
        If mouseIsDown Then
            If previousLocation IsNot Nothing Then
                Using g As Graphics = Graphics.FromImage(PictureBox1.Image)
                    g.DrawLine(New Pen(myColor), previousLocation.Value, e.Location)
                End Using
                PictureBox1.Invalidate()
            End If
            previousLocation = e.Location
        End If
    End Sub

    Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
        mouseIsDown = False
        previousLocation = Nothing
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
    End Sub
End Class

      

+2


source







All Articles