Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. How to draw lines then undo ???

How to draw lines then undo ???

Scheduled Pinned Locked Moved Visual Basic
winformsgraphicsdebuggingtutorialquestion
20 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Ray Guan

    hi, all i am going to implement a WinForm Control which contain a picturebox control , i want to draw lines on the picturebox , when i drags the mouse(left button) , a straight line will be drawn, and whenever i right clicked on one of the lines , it will disappear, how to implement this by GDI+ , can anybody post some sample code here or some URL may helpful. any suggestion would be appreciated! thanks a lot best regards, nick kong debug.writeline("am i sexy"):laugh:

    A Offline
    A Offline
    Anonymous
    wrote on last edited by
    #2

    the only way I know of to get rid on lines is to refresh the control. This will get rid of all the lines though. I would use an array to either save the line draw info.

    R 1 Reply Last reply
    0
    • R Ray Guan

      hi, all i am going to implement a WinForm Control which contain a picturebox control , i want to draw lines on the picturebox , when i drags the mouse(left button) , a straight line will be drawn, and whenever i right clicked on one of the lines , it will disappear, how to implement this by GDI+ , can anybody post some sample code here or some URL may helpful. any suggestion would be appreciated! thanks a lot best regards, nick kong debug.writeline("am i sexy"):laugh:

      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #3

      GDI+ is responsible for drawing lines. I'd ditch the picturebox and just draw your image on screen. I can't imagine it will add anything and could be a pain. Undo works one of two ways. 1. Keep copies of all your bitmaps every time a drawing event occurs, so you can go back through them 2. Keep all your actions in a list, so you can remove one, and apply the rest to the original image, resulting in an undo 1. is easier to write, 2. is more memory friendly and flexible. Christian Graus - Microsoft MVP - C++

      L R 2 Replies Last reply
      0
      • A Anonymous

        the only way I know of to get rid on lines is to refresh the control. This will get rid of all the lines though. I would use an array to either save the line draw info.

        R Offline
        R Offline
        Ray Guan
        wrote on last edited by
        #4

        thank you, Mr.anonymous, you mentioned use array to save line draw info, can you show me some sample code ? i made some pseudo code like this i define a structure to store information of the line cooridanites , like this : structure LineInfo strartPoint as point endPoint as point myColor as color paintORnot as boolean end structure but i think it's useless, base on these infomation , i can not find the line i want to erase, and when i drew thourands of lines, the search procedure would cost huge system resource, i think , right? what u think of this ? thanks , nick debug.Writeline("am i sexy"):laugh:

        1 Reply Last reply
        0
        • C Christian Graus

          GDI+ is responsible for drawing lines. I'd ditch the picturebox and just draw your image on screen. I can't imagine it will add anything and could be a pain. Undo works one of two ways. 1. Keep copies of all your bitmaps every time a drawing event occurs, so you can go back through them 2. Keep all your actions in a list, so you can remove one, and apply the rest to the original image, resulting in an undo 1. is easier to write, 2. is more memory friendly and flexible. Christian Graus - Microsoft MVP - C++

          L Offline
          L Offline
          lespaul36
          wrote on last edited by
          #5

          As for what I was thinking with the array is sort of what the last answer says. I would make a structure or class that holds the start position and the end position. Then create a new instance of it and add it to the array on the mouseup event. The hard part would be getting the correct line when a right click is done. Are the lines just verticle/horizontal, or will they go diagonal?

          C R 2 Replies Last reply
          0
          • C Christian Graus

            GDI+ is responsible for drawing lines. I'd ditch the picturebox and just draw your image on screen. I can't imagine it will add anything and could be a pain. Undo works one of two ways. 1. Keep copies of all your bitmaps every time a drawing event occurs, so you can go back through them 2. Keep all your actions in a list, so you can remove one, and apply the rest to the original image, resulting in an undo 1. is easier to write, 2. is more memory friendly and flexible. Christian Graus - Microsoft MVP - C++

            R Offline
            R Offline
            Ray Guan
            wrote on last edited by
            #6

            thank you very much, Mr. Graus , you said ditch the pictureBox , i think your news was too bad for me, most of my work i have already done was base on the picturebox, because i need a scrollable area to display my data . but now, i think it was a mistake. i am looking for other way to implement this. can u post some sample code to implement "UNDO" here,i need some reference. both C++ or C# are welcome, best in VB.NET, thanks a lot. best regards, nick debug.writeline("am i sexy"):laugh:

            C 1 Reply Last reply
            0
            • L lespaul36

              As for what I was thinking with the array is sort of what the last answer says. I would make a structure or class that holds the start position and the end position. Then create a new instance of it and add it to the array on the mouseup event. The hard part would be getting the correct line when a right click is done. Are the lines just verticle/horizontal, or will they go diagonal?

              C Offline
              C Offline
              Christian Graus
              wrote on last edited by
              #7

              lespaul36 wrote: The hard part would be getting the correct line when a right click is done. No, that's pretty easy, just basic trig. Assuming it would be a drawing package, and not straight undo/redo stuff. Christian Graus - Microsoft MVP - C++

              R L 2 Replies Last reply
              0
              • R Ray Guan

                thank you very much, Mr. Graus , you said ditch the pictureBox , i think your news was too bad for me, most of my work i have already done was base on the picturebox, because i need a scrollable area to display my data . but now, i think it was a mistake. i am looking for other way to implement this. can u post some sample code to implement "UNDO" here,i need some reference. both C++ or C# are welcome, best in VB.NET, thanks a lot. best regards, nick debug.writeline("am i sexy"):laugh:

                C Offline
                C Offline
                Christian Graus
                wrote on last edited by
                #8

                nickong wrote: i am looking for other way to implement this. Easy - put a scroll bar on the screen and use it's position in your OnPaint. Then Invalidate the screen in your event handler for scroll events. nickong wrote: can u post some sample code to implement "UNDO" here,i need some reference. both C++ or C# are welcome, best in VB.NET, thanks a lot. Not really, sorry. All of my undo/redo code is under NDAs. But the basic idea is either for each draw event to first copy the current image into an array using Clone, or for drawing lines to be encapsulated into a class which you can make an array of. Christian Graus - Microsoft MVP - C++

                R 1 Reply Last reply
                0
                • L lespaul36

                  As for what I was thinking with the array is sort of what the last answer says. I would make a structure or class that holds the start position and the end position. Then create a new instance of it and add it to the array on the mouseup event. The hard part would be getting the correct line when a right click is done. Are the lines just verticle/horizontal, or will they go diagonal?

                  R Offline
                  R Offline
                  Ray Guan
                  wrote on last edited by
                  #9

                  ye, u r correct, Mr.lespaul36, the hard part gonna be the erasing of the selected line . all lines go diagonal , i cannot find a good data structure to store the info of a line. i cannot capture which point i right clicked on the line. i cannot stroe all points of a line. then loop to find them,oh, i am confused X|

                  C 1 Reply Last reply
                  0
                  • C Christian Graus

                    lespaul36 wrote: The hard part would be getting the correct line when a right click is done. No, that's pretty easy, just basic trig. Assuming it would be a drawing package, and not straight undo/redo stuff. Christian Graus - Microsoft MVP - C++

                    R Offline
                    R Offline
                    Ray Guan
                    wrote on last edited by
                    #10

                    "Assuming it would be a drawing package,and not straight undo/redo stuff." in another words , it means ....??:doh:

                    C 1 Reply Last reply
                    0
                    • R Ray Guan

                      "Assuming it would be a drawing package,and not straight undo/redo stuff." in another words , it means ....??:doh:

                      C Offline
                      C Offline
                      Christian Graus
                      wrote on last edited by
                      #11

                      In other words, a drawing package would allow you to select a line by clicking on it, so you could move/undo any line you like. A paint package would not allow this, it would allow you to simply undo the lines, with a stack so that you could only undo the most recent line first. Christian Graus - Microsoft MVP - C++

                      R 1 Reply Last reply
                      0
                      • C Christian Graus

                        nickong wrote: i am looking for other way to implement this. Easy - put a scroll bar on the screen and use it's position in your OnPaint. Then Invalidate the screen in your event handler for scroll events. nickong wrote: can u post some sample code to implement "UNDO" here,i need some reference. both C++ or C# are welcome, best in VB.NET, thanks a lot. Not really, sorry. All of my undo/redo code is under NDAs. But the basic idea is either for each draw event to first copy the current image into an array using Clone, or for drawing lines to be encapsulated into a class which you can make an array of. Christian Graus - Microsoft MVP - C++

                        R Offline
                        R Offline
                        Ray Guan
                        wrote on last edited by
                        #12

                        thank you anyway, i'll try to do that follow the basic idea.:cool: thank you, nick kong

                        C L 2 Replies Last reply
                        0
                        • R Ray Guan

                          ye, u r correct, Mr.lespaul36, the hard part gonna be the erasing of the selected line . all lines go diagonal , i cannot find a good data structure to store the info of a line. i cannot capture which point i right clicked on the line. i cannot stroe all points of a line. then loop to find them,oh, i am confused X|

                          C Offline
                          C Offline
                          Christian Graus
                          wrote on last edited by
                          #13

                          nickong wrote: the hard part gonna be the erasing of the selected line That's not what he said, and you DON'T erase any lines. You either redraw all the lines except that one, on the starting image, or you simply replace the entire bitmap ( or a section of it), so that the line is just not there. You NEVER take the image with the line and try to replace it with the pixels that were there before. nickong wrote: cannot capture which point i right clicked on the line Do you want to ? You never mentioned this. Oh damn, I think you did. The picture box is the first thing that needs to go. Beyond that, you need to keep an array of the points for each line. This means you can't use the bitmap undo idea, you need to build an action list of lines, which would just contain the two points, and if the colour changes, the colour you use. It's a simple struct. nickong wrote: cannot stroe all points of a line. You don't need to. You just need a little trigonometry. You step through the lines in your array and for each, call a function to see if the point your mouse is at is on the line formed by the triangle created by the two points you've got for your line, and the point you make by drawing straight lines that intersect from the x and y directions. Christian Graus - Microsoft MVP - C++

                          1 Reply Last reply
                          0
                          • R Ray Guan

                            thank you anyway, i'll try to do that follow the basic idea.:cool: thank you, nick kong

                            C Offline
                            C Offline
                            Christian Graus
                            wrote on last edited by
                            #14

                            See my other comments, I didn't realise you wanted to undo any line by clicking on it. Christian Graus - Microsoft MVP - C++

                            1 Reply Last reply
                            0
                            • C Christian Graus

                              In other words, a drawing package would allow you to select a line by clicking on it, so you could move/undo any line you like. A paint package would not allow this, it would allow you to simply undo the lines, with a stack so that you could only undo the most recent line first. Christian Graus - Microsoft MVP - C++

                              R Offline
                              R Offline
                              Ray Guan
                              wrote on last edited by
                              #15

                              do u have any tech document about drawing package , can u show me some URL ? i think i should take some basic ideal about that first,thanks :^)

                              C 1 Reply Last reply
                              0
                              • R Ray Guan

                                do u have any tech document about drawing package , can u show me some URL ? i think i should take some basic ideal about that first,thanks :^)

                                C Offline
                                C Offline
                                Christian Graus
                                wrote on last edited by
                                #16

                                Microsoft has a demo VB.NET program called 'Fotovision' It impliments an undo/redo action list. As for the maths, if you have a line from 8, 20 to 47, 100, then the triangle is 8, 20 to 8, 100 to 47, 100. Actually, if you work out the ratio for x and y, which is width/height ( (47-8)/(100-20), or 39/80 ( basically .5 ). Then, if your point goes across from 8,20 by half as much as it goes down, the point is on the line. I'm sure there are plenty of resources online for finding if a point is on a line. There may even be a method in the GDI+ libraries. There is certainly a method for pointinrect, which I'd use first before walking the line myself to see if it's a hit. Christian Graus - Microsoft MVP - C++

                                1 Reply Last reply
                                0
                                • C Christian Graus

                                  lespaul36 wrote: The hard part would be getting the correct line when a right click is done. No, that's pretty easy, just basic trig. Assuming it would be a drawing package, and not straight undo/redo stuff. Christian Graus - Microsoft MVP - C++

                                  L Offline
                                  L Offline
                                  lespaul36
                                  wrote on last edited by
                                  #17

                                  Haven' had to do much more that d += 1 lately. :-D

                                  1 Reply Last reply
                                  0
                                  • R Ray Guan

                                    thank you anyway, i'll try to do that follow the basic idea.:cool: thank you, nick kong

                                    L Offline
                                    L Offline
                                    lespaul36
                                    wrote on last edited by
                                    #18

                                    I did something like this before, without the selection of a line to remove it. I wish I had the code, but I lost it when I had a hard drive crash (back up every week now :) ) I used GetChildAtPoint for some of the info. I also used an array of bitmaps, however it was for icon info (never did get it to make actual ico files instead of png files), so it was fast and didn't use too much resources. You could probably still pull it off, but might have to do some playing. I would be interested to see if there is a hittest or something for a drawn line...please let me know back. Other wise you would probably want to write the routine to check if it is a hit in its own thread and you would need to give a little distance for ease of click...be hard if it had to be a certain pixel). Good Luck

                                    T 1 Reply Last reply
                                    0
                                    • L lespaul36

                                      I did something like this before, without the selection of a line to remove it. I wish I had the code, but I lost it when I had a hard drive crash (back up every week now :) ) I used GetChildAtPoint for some of the info. I also used an array of bitmaps, however it was for icon info (never did get it to make actual ico files instead of png files), so it was fast and didn't use too much resources. You could probably still pull it off, but might have to do some playing. I would be interested to see if there is a hittest or something for a drawn line...please let me know back. Other wise you would probably want to write the routine to check if it is a hit in its own thread and you would need to give a little distance for ease of click...be hard if it had to be a certain pixel). Good Luck

                                      T Offline
                                      T Offline
                                      T Smooth
                                      wrote on last edited by
                                      #19

                                      I think what you are looking for is the GraphicsPath object from GDI+. I just recently had to use this and read up on it but I am by no means an expert with it. I did however throw together a quick example in a couple min. to show you how you can use this to draw lines, select them, and then get rid of them. A quick disclaimer first: Being that i did this quick at work, the collection of GraphicsPath objects continously grows... the current implementation never gets rid of the objects, just resets their points to basically have them draw nothing. This should definitely be changed. For additional information, read up on GraphicsPath on MSDN. Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown Dim oGP As GraphicsPath ' Loop through the collection of lines to see if we clicked on one. For Each oGP In LineCollection ' The following IF returns true if the line was clicked on, the trigonometry is done for you :) If oGP.IsOutlineVisible(e.X, e.Y, New Pen(Color.Black)) Then oGP.Reset() ' Should remove the line from the collection or do something different here! Me.Invalidate() Exit Sub End If Next Drawing = True GP = New GraphicsPath ' Create a new GP object to hold the line. pt1 = New Point(e.X, e.Y) ' Set the start point of the line. LineCollection.Add(GP) ' Add this graphics path object to the collection End Sub Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp Drawing = False ' Not drawing a line anymore End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove If Drawing = True Then GP.Reset() ' Clear the current graphics path object. GP.AddLine(pt1.X, pt1.Y, e.X, e.Y) ' Add the line Me.Invalidate() ' Force paint End If End Sub You'll have to make sure you declare LineCollection As a New System.Collections.ArrayList somewhere as well as GP as a GraphicsPath and pt1 as a Point. Hope this helps. Should let you draw lines on the form and then to "erase" them, just click on them.

                                      L 1 Reply Last reply
                                      0
                                      • T T Smooth

                                        I think what you are looking for is the GraphicsPath object from GDI+. I just recently had to use this and read up on it but I am by no means an expert with it. I did however throw together a quick example in a couple min. to show you how you can use this to draw lines, select them, and then get rid of them. A quick disclaimer first: Being that i did this quick at work, the collection of GraphicsPath objects continously grows... the current implementation never gets rid of the objects, just resets their points to basically have them draw nothing. This should definitely be changed. For additional information, read up on GraphicsPath on MSDN. Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown Dim oGP As GraphicsPath ' Loop through the collection of lines to see if we clicked on one. For Each oGP In LineCollection ' The following IF returns true if the line was clicked on, the trigonometry is done for you :) If oGP.IsOutlineVisible(e.X, e.Y, New Pen(Color.Black)) Then oGP.Reset() ' Should remove the line from the collection or do something different here! Me.Invalidate() Exit Sub End If Next Drawing = True GP = New GraphicsPath ' Create a new GP object to hold the line. pt1 = New Point(e.X, e.Y) ' Set the start point of the line. LineCollection.Add(GP) ' Add this graphics path object to the collection End Sub Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp Drawing = False ' Not drawing a line anymore End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove If Drawing = True Then GP.Reset() ' Clear the current graphics path object. GP.AddLine(pt1.X, pt1.Y, e.X, e.Y) ' Add the line Me.Invalidate() ' Force paint End If End Sub You'll have to make sure you declare LineCollection As a New System.Collections.ArrayList somewhere as well as GP as a GraphicsPath and pt1 as a Point. Hope this helps. Should let you draw lines on the form and then to "erase" them, just click on them.

                                        L Offline
                                        L Offline
                                        lespaul36
                                        wrote on last edited by
                                        #20

                                        Have to tuck this away for the next time I am messing with GDI+. Thanks T-Smooth.

                                        1 Reply Last reply
                                        0
                                        Reply
                                        • Reply as topic
                                        Log in to reply
                                        • Oldest to Newest
                                        • Newest to Oldest
                                        • Most Votes


                                        • Login

                                        • Don't have an account? Register

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • World
                                        • Users
                                        • Groups