マウスを動かしながら直線を引きたい

タグの編集
投稿者 JUN  (社会人) 投稿日時 2009/2/6 01:47:27
はじめまして、JUNと申します。VB超初心者です。
趣味でペイントソフトをつくろうと思い、インターネットや本で勉強して以下のコードまでは理解できるようになりました。

Public Class Form1
    Private startX, starty, endx, endy As Integer
   
Private Sub paint_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles paint.MouseDown
        
     If e.Button = Windows.Forms.MouseButtons.Left Then
            startX = e.X
            startY = e.Y
      
        End If
    End Sub

  Private Sub paint_Mousemove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles paint.Mousemove
        
     If e.Button = Windows.Forms.MouseButtons.Left Then
       endx = e.X
            endy = e.Y
            paint.Invalidate()
        End If

    End Sub

    Private Sub paint_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles paint.Paint

        e.Graphics.DrawLine(Pens.Red, startX, starty, endx, endy)
    End Sub

注:PaintはPicturebox1です。

このコードだとマウスを動かしながら自由に視覚化した線を引くことはできるのですが、もう一回線を引くと前引いた線が消えてしまうのです。

いろんなサイトを見ましたがどこにも自分が求めている答えが見つからず困っています。(もしかしたら答えが載ってるサイトがあったかもしれませんが、自分のレベルでは理解できなかった可能性が大きいです;)

自分の考えではmauseupを追加し、mouseupしたときに描いた線をpaintに残しておく…みたいな風にやるのかなと考えていますが、やりかたがわかりません。


このような掲示板を利用するのは初めてなので聞き方や、マナーなどよくわからないのですが、ご回答、もしくはヒントでも教えていただけたら幸いです。

よろしくお願いします。



投稿者 JUN  (社会人) 投稿日時 2009/2/6 02:02:00
追記:XPでVB2005を使用しています。
投稿者 ヴァン  (社会人) 投稿日時 2009/2/6 02:19:08
MouseDownで始点を覚えて、MouseUpで始点と終点を配列に代入していけばいいと思います。
あとはPaintで配列からデータを取り出して描画すればいいはずです。
投稿者 太郎冠者  (社会人) 投稿日時 2009/2/6 02:30:44
描画領域と同サイズのSystem.Drawing.Bitmapオブジェクトを用意して、そこに描く様にしましょう。

[参考]
http://dobon.net/vb/dotnet/graphics/drawimage.html
投稿者 ヴァン  (社会人) 投稿日時 2009/2/6 02:59:52
まあ、お遊び程度ならこんな感じでどうですか。

Public Class Form1
    Private startX, starty, endx, endy As Integer
    Private axisList As List(Of Axis) = New List(Of Axis)

    Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            startX = e.X
            startY = e.Y

        End If

    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
        Dim lineAxis As Axis = New Axis
        lineAxis.StartPoint.X = startX
        lineAxis.StartPoint.Y = starty
        lineAxis.EndPoint.X = endx
        lineAxis.EndPoint.Y = endy
        axisList.Add(lineAxis)
        PictureBox1.Invalidate()
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            endx = e.X
            endy = e.Y
            PictureBox1.Invalidate()
        End If
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        e.Graphics.DrawLine(Pens.Red, startX, starty, endx, endy)
        For Each lineAxis As Axis In axisList
            e.Graphics.DrawLine(Pens.Blue, lineAxis.StartPoint, lineAxis.EndPoint)
        Next
    End Sub
End Class

Public Class Axis
    Public StartPoint As Point
    Public EndPoint As Point
End Class
投稿者 あにす  (社会人) 投稿日時 2009/2/6 03:19:26
こんな感じで。
描画するだけだと消えてしまうので、描画する内容は常に自分で管理しないといけないんですよね。
WPFだとそこら辺はかなり楽になってるんですけどねー。
Public Class Form1
    Dim sp, ep As Point
    Dim lines As New List(Of Point())

    Private Sub paint_MouseDown(ByVal sender As ObjectByVal e As MouseEventArgs) Handles paint.MouseDown
        sp = e.Location
        paint.Invalidate()
    End Sub

    Private Sub paint_MouseMove(ByVal sender As ObjectByVal e As MouseEventArgs) Handles paint.MouseMove
        ep = e.Location
        paint.Invalidate()
    End Sub

    Private Sub paint_MouseUp(ByVal sender As ObjectByVal e As MouseEventArgs) Handles paint.MouseUp
        lines.Add(New Point() {sp, e.Location})
        paint.Invalidate()
    End Sub

    Private Sub paint_Paint(ByVal sender As ObjectByVal e As PaintEventArgs) Handles paint.Paint
        If Control.MouseButtons = Windows.Forms.MouseButtons.Left Then
            e.Graphics.DrawLine(Pens.Red, sp, ep)
        End If
        For Each line As Point() In lines
            e.Graphics.DrawLine(Pens.Red, line(0), line(1))
        Next
    End Sub
End Class
投稿者   (社会人) 投稿日時 2009/2/6 12:35:36
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard2.htm
の発展学習を参考にすると、こんな感じかな。

Public Class Form1
    Private bmp As Bitmap = Nothing
    Private sP, ep As Point

    Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load
        bmp = New Bitmap(PictureBox1.ClientRectangle.Width, PictureBox1.ClientRectangle.Height)
        PictureBox1.Image = bmp
    End Sub

    Private Sub PictureBox1_MouseDown(ByVal sender As System.ObjectByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            sP = e.Location
        End If
    End Sub

    Private Sub PictureBox1_MouseMove(ByVal sender As System.ObjectByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left Then
            eP = e.Location
            PictureBox1.Invalidate()
        End If
    End Sub

    Private Sub PictureBox1_MouseUp(ByVal sender As System.ObjectByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Left Then
            ep = e.Location
            Using g As Graphics = Graphics.FromImage(bmp)
                g.DrawLine(Pens.Blue, sP, ep)
            End Using
        End If
    End Sub

    Private Sub PictureBox1_Paint(ByVal sender As System.ObjectByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        e.Graphics.DrawLine(Pens.Blue, sP, ep)
    End Sub
End Class
投稿者 JUN  (社会人) 投稿日時 2009/2/6 18:23:19
すごいです!!みなさんの教えていただいたとおりにやったら自分が思い描いていた通りにできました。

一週間ずっと一人で悩んでいたのでできてとても感動しています。

まだ、何故できたのか?は理解しきれていないですが、これから勉強して理解していきたいと思います。

本当にありがとうございました。