Drawing lines in a picturebox
Drawing lines in a picturebox
Drawing lines in a picturebox
Drawing lines in a picturebox
Drawing lines in a picturebox
Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox
Drawing lines in a picturebox Drawing lines in a picturebox
Drawing lines in a picturebox
Go Back  Xtreme Visual Basic Talk > > > Drawing lines in a picturebox


Reply
 
Thread Tools Display Modes
  #1  
Old 10-25-2008, 07:41 AM
Success_Machine Success_Machine is offline
Regular
 
Join Date: Oct 2003
Posts: 64
Default Drawing lines in a picturebox


Hello, I'm making the transition from VB6 to VB2008 and I'm having difficulty finding the equivalent to:

public sub form_load()
' Perform some calculations to determine x1,y1.....x4,y4
' Draw lines in two different picturebox controls
Picture1.Line (x1, y1) - (x2, y2), vbRed
Picture2.Line (x3, y3) - (x4, y4), vbBlack
end sub


It seems in VB2008 I can only use pens inside a picturebox1_onpaint() subroutine, I can't tell a picturebox what to do from a button_click subroutine or form_load subroutine first and then send the results to a picturebox. I have no control over when the graphics are drawn and from which subroutine. How do I solve this in VB2008 ?
Reply With Quote
  #2  
Old 10-25-2008, 08:06 AM
AtmaWeapon's Avatar
AtmaWeaponDrawing lines in a picturebox AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

You can do it, but it might not persist. Every time the Paint event is raised, the entire control is erased and redrawn. If you don't have code to draw your lines in response to the Paint event, they will be erased.

One way to handle this might be to store information about where to draw the lines, then draw them when the Paint event is raised. In this case, it's a lot of overhead to use a picture box and you'd be better off using a simpler control like Panel, or even better encapsulating the functionality in a custom control. It would look something like this:

Code:
Class Line
    ' We'll pretend these are fully implemented properties for brevity
    Public StartPoint As Point
    Public EndPoint As Point
    Public Color As Color
End Class

Class YourForm
    Private _lines As New List(Of Line)()
    
    Sub Button1_Click(...) Handles Button1.Click
        Dim line As New Line()
        line.StartPoint = new Point(x1, y1)
        line.EndPoint = new Point(x2, y2)
        line.Color = GetColor() ' implement this how you please
        _lines.Add(line)
        PictureBox1.Invalidate()
    End Sub

    Sub PicBoxPaint(...) Handles PictureBox1.Paint
        Dim g As Graphics = e.Graphics

        For Each line As Line in _lines
            Dim p As New Pen(line.Color, 1)
            g.DrawLine(p, line.StartPoint, line.EndPoint)
            p.Dispose()
        Next
    End Sub
End Class
The alternative involves drawing directly to the picturebox image:
Code:
' Line class as above

Class YourForm

    Sub Button1_Click(...) Handles Button1.Click
        Using g As Graphics = Graphics.FromImage(PictureBox1.Image)
            For Each line As Line in _lines
                Dim p As New Pen(line.Color, 1)
                g.DrawLine(pen, line.StartPoint, line.EndPoint)
                p.Dispose()
            Next
        End Using
        PictureBox1.Invalidate()
    End Sub
End Class
In this case, since you are drawing to the image and the image is painted by the picture box, then you don't have to do things from the Paint event. The downside is that the creation of a Graphics object is fairly expensive; it's better to use the one provided to you by the Paint event.

I really recommend encapsulating the first way into a custom control to keep the logic of managing the lines out of your form.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #3  
Old 10-25-2008, 08:38 AM
Success_Machine Success_Machine is offline
Regular
 
Join Date: Oct 2003
Posts: 64
Default

No offense, but I don't see how that could possibly be an improvement on VB6. Your code is four-times longer than mine. I don't understand the _Paint event. It's not like a mouseclick event which is something I physically do. When does the paint event happen? Is it always happening? Does it do it when the form loads, or after all other subroutines are finished?

The problem is I can't use VB6 for the next 20 years since at some point the operating system won't support it. Perhaps there is a better alternative? Maybe matlab? MacIntosh? Obviously I don't understand VB2008.
Reply With Quote
  #4  
Old 10-25-2008, 11:48 AM
AtmaWeapon's Avatar
AtmaWeaponDrawing lines in a picturebox AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Quote:
Originally Posted by Success_Machine View Post
No offense, but I don't see how that could possibly be an improvement on VB6. Your code is four-times longer than mine. I don't understand the _Paint event. It's not like a mouseclick event which is something I physically do. When does the paint event happen? Is it always happening? Does it do it when the form loads, or after all other subroutines are finished?

The problem is I can't use VB6 for the next 20 years since at some point the operating system won't support it. Perhaps there is a better alternative? Maybe matlab? MacIntosh? Obviously I don't understand VB2008.
No offense, but your "lines of code = complexity" view is outdated. It all depends on how you count lines of code. The lines that do the drawing in my code are here:
Code:
        For Each line As Line in _lines
            Dim p As New Pen(line.Color, 1)
            g.DrawLine(p, line.StartPoint, line.EndPoint)
            p.Dispose()
        Next
I count 4 lines here: 1 for the loop, 1 to instantiate the pen, 1 to draw a line, and 1 to dispose of the line. Adding a line takes a few lines, but let's showcase why LOC (lines of code) is a poor metric for judging complexity. These two code blocks are functionally equivalent in VB 2008:

Code:
        Dim line As New Line()
        line.StartPoint = new Point(x1, y1)
        line.EndPoint = new Point(x2, y2)
        line.Color = GetColor() ' implement this how you please
        _lines.Add(line)
        PictureBox1.Invalidate()
Code:
_lines.Add(New Line() { .StartPoint = New Point(x1, y1), .EndPoint = new Point(x2, 72), .Color = GetColor() } )
PictureBox1.Invalidate
Would you argue that the 2-line version is easier to follow than the 6-line version? This ends my discussion of LOC as a complexity metric; it's bogus.

To understand how to draw to a Windows Form, you have to understand how Windows draws. The Paint event corresponds directly to the WM_PAINT message in the Windows API.

In traditional GDI programming, Windows doesn't store any information about how your form should be displayed. When something covers part of your form, whatever was there is lost. When the form is uncovered, Windows sends a WM_PAINT message to the form so that it knows it needs to redraw at least the part that was erased.

In VB6, from what I understand, you had no access to this without subclassing and setting up your own message pump. The PictureBox control abstraction made the control seem more like an image than a control, so you could draw directly to it. In .NET, the PictureBox control is a control that displays an image; if you want to draw on it you either need to handle the Paint event or draw to the image manually. If you draw to the image, it's a single extra step compared to VB6.

So, when you are responding to the Paint event, you need to know how to redraw everything that's been drawn so far. The code I posted responds to a mouse click by adding a line to a list of lines to be drawn, then invalidates the control. When the control is invalidated, its Paint event is raised, and it draws every line that's in its list.

In the alternative method, you draw directly to the image inside of the PictureBox. Since the PictureBox is programmed to display this image, all you have to do is draw, then call Invalidate. The PictureBox then gets a WM_PAINT message, and it responds by redrawing its image.

Using the image of the picture box is generally a poor practice compared to manually redrawing in response to the Paint event. Let's say you have 50 lines to draw. If your control is a 640x480 picture viewer, it takes 32 bits per pixel of memory to store the image data; that's 9.37 MB of data. It doesn't matter if there's 0 lines or 100, the bitmap image will take that much memory. If, instead, you just store the lines that need to be drawn, you are storing 4 integers (the 2 points) and a color (32-bit integer) per line. For 100 lines, that's 160 bytes per line; 100 lines only uses 15.6 KB of memory; that's 9,000 times less memory!

Would you rather do things the VB6 way and waste memory, or write about 6 extra lines of code? VB6's crutches come at a cost.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #5  
Old 10-25-2008, 05:22 PM
Success_Machine Success_Machine is offline
Regular
 
Join Date: Oct 2003
Posts: 64
Default

Well, I can see the similarities between the 2-line and the 6-line examples, so I might be inclined to use the 2-line version. The reason is that I would be able to see more code on my screen, maybe even see a whole subroutine, without having to scroll up and down to find something. But I'm going to partially agree with you because the 6-line version looks a bit cleaner.

Unfortunately I've never been able to learn programming from disconnected snippets of code. I have almost always needed complete, working programs to learn from. I would copy and paste, move things around, make modifications. Starting with a program that works allows me to learn by trial & error what variations of that program also work, and later to write my own custom programs.

Assume I am starting with a form, a picturebox, and a button. You wouldn't happen to have an example of a complete program that defines the line endpoints coordinates in the button subroutine and then somehow draws it in the picturebox?
Reply With Quote
  #6  
Old 10-25-2008, 07:53 PM
AtmaWeapon's Avatar
AtmaWeaponDrawing lines in a picturebox AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Honestly if you search the forums, even restricting it to just me examples, you'll find a few samples of simple drawing programs. In fact, I think I've made the same "shape drawing" program three or four times over. It's mainly because this type of custom drawing was my hobby in my early days, and I enjoy it.

I do not like putting everything in the form. It's a bad habit that tends to make your programs more complicated and discourages code reuse. The example will have a control that is like a canvas on which we draw; incidentally, I will call it "DrawingCanvas". When you click the button, a line with random start points and end points is drawn on the canvas. I tried to comment it fairly well, as I don't like my current trend of long explanations + overcommented source.
Attached Files
File Type: zip DrawingDemo.zip (12.5 KB, 76 views)
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #7  
Old 10-25-2008, 08:48 PM
Targe Targe is offline
Contributor
 
Join Date: Nov 2006
Posts: 615
Default

Also, take a look at:

http://www.bobpowell.net/

That's the site that taught me GDI. Still, though, you say you're using 2008? WPF or WinForms? In my experience with WPF there's no need to handle the paint event because it handles it for you. If you draw something in WPF it will remain there. Whether that's good or bad I'm not sure. It's good to know how things are being done on forms but if you want simplicity (and it looks like you do), you may think about using WPF. It's also slightly easier to learn than GDI, more powerful, and hardware accelerated. All plusses to me!
Reply With Quote
  #8  
Old 10-25-2008, 10:56 PM
Success_Machine Success_Machine is offline
Regular
 
Join Date: Oct 2003
Posts: 64
Default

Thanks for the link. Looks good. I did some looking around myself and discovered that author Rod Stephens (superman) has published a new "Visual Basic Graphics Programming" book in March 2008. The Wrox website is giving away free code from the book. Probably why the pdf book is only 66 pages long. I learned nearly everything I know from the 2nd edition of this book about ten years ago. This new edition is timed perfectly. I hope it is as good as the 2nd edition. That book was easy to follow, and it ramped to serious graphics programming level - I'm talking parametric surfaces, and I aint kidding. Currently the Wiley publishing website seems to be down. I'll try to purchase it later. Rod Stephens also has a tutorial website. Here are the links:

http://www.wrox.com/WileyCDA/WroxTit...470343486.html

http://www.vb-helper.com/online_articles.html
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Drawing lines in a picturebox
Drawing lines in a picturebox
Drawing lines in a picturebox Drawing lines in a picturebox
Drawing lines in a picturebox
Drawing lines in a picturebox
Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox Drawing lines in a picturebox
Drawing lines in a picturebox
Drawing lines in a picturebox
 
Drawing lines in a picturebox
Drawing lines in a picturebox
 
-->