generic error occured in GDI+ (drawline)

I've just converted my program from VB 6 to VB 2005. There is a lot of graphics involved, drawing lots of lines to make models. The lines were all formerly drawn with the Line command on the forms, but now that that is gone i have run into problems switching to the new commands. My program is fairly large with many forms and modules so I was unsure about some of the things i did.

I declared all the graphics in one module as follows:

"Public Graph3d_yz As Graphics = frmDraw3d_yz.CreateGraphics()

Public Graph3d_xz As Graphics = frmDraw3d_xz.CreateGraphics()

Public Graph3d_xy As Graphics = frmDraw3d_xy.CreateGraphics()

Public Graph2d As Graphics = frmDraw2d.CreateGraphics()

Public GraphOGL As Graphics = Opengl3d.CreateGraphics()

Public LinePen As Pen"


I'm now encountering a problem with this following line saying that a generic error occured in GDI+:

Graph3d_xz.DrawLine(LinePen, x1srl(Indx(j)), x3srl(Indx(j)), (x1srr(Indx(j)) - x1srl(Indx(j))), (x3srr(Indx(j)) - x3srl(Indx(j))))


Any advice on what i may have not done or what i should check
thanks,
Gareth



Answer this question

generic error occured in GDI+ (drawline)

  • gaorellana

    Although I am still having problems with the lines only flickering and going away, I fixed the generic GDI error. I had to declare the Graphics in the module so that the Graphics members would be declared before their use, but I needed to declare the "graph3d_yz = Me.CreateGraphics()" in the Load function of the respective forms.

    BEFORE:
    (in a Module)
    Public Graph3d_xy As Graphics = frmDraw3d_xy.CreateGraphics()

    AFTER:
    (in a Module)
    Public Graph3d_xy As Graphics

    (in respective Form_Load)

    Graph3d_xy = Me.CreateGraphics()




    Now I am trying to make it so the graphics will not disappear and i believe I need to use Bitmap.

  • Ray Cochrane

    The lines are because gdi isn't that great for making smooth graphics refreshed frequently.
    As for the graphics disapearing, that's normal.  It's not your setup.  You can save to a bitmap  after all your painting is done, but if you refresh quickly, then you'll be caching alot to your hard drive.

    Generally, you have to .Invalidate() your control in order to call your paint code again.
    I've never tried, but i also think you can use the .Save and .Restore functions from the graphics object.

    If your looking for nice smooth graphics, (if you need to keep a steady framerate), then consider using DirectX or OpenGL.

    Since the painting of objects is all event driven, rarely would you use the graphics object in a do/loop type of code constantly rendering the control. (Which causes the flicker)
    If you move to the OnPaint() event, you can still draw all the things you need from your module.  This way, you can call the .Invalidate, and simply 'render' the picture whenever it's actually needed, rather then over and over.

    Dustin.


  • dansha

    Thanks, I have tried working with a bitmap and have made progress, but also encountered problems. The software is not high refresh rate animation, it is just drawing simple models with rectangles and such so hopefully the caching won't be a big problem.

    The code was already set in VB 6 with Drawlines and such, and there are a lot of lines associated with drawing the models so I would like to avoid going to DirectX or OpenGL.

    My main problem now is that I have created a Picturebox on the 3 forms that i draw on and set the picturebox equal to a bitmap:

    Public Sub Form_Load(...)

    Dim tmp As Bitmap = New Bitmap(PicBox.Width, PicBox.Height)

    PicBox.Image = tmp

    This is fine with drawing the rectangles (they don't disappear), but I am having trouble figuring out how to replace Scalemode that was used in VB 6. I found Sizemode, which seems like it should be appropriate, but I am not able to get it functioning. I need the capability to have the set of rectangles resize depending on whether they fit the screen and i need to be able to have a custom zoom ability for the user. Is there an easy way to do all of this (considering that the functionality was all there before I upgraded from VB 6)

    Thanks,
    gareth


  • Badajoz95

    You shouldn't have to use bitmaps at all in your code.
    When you move the mouse over the picturebox, windows will redraw the picturebox, and the stuff you've drawn gets removed.

    What you should do, is add a handler for the picturebox MouseMove event.  In the sub call your code to repaint the picture.  (no bitmaps needed that way).

    As for scaling,  i don't know any way to do that now in vs2005.  You may have to do your own scaling code.

    Dustin.


  • Elmer Palpan

    Thanks. the problem was not with the linepen, but the .CreateGraphics may be part of it. I saw the 2 ways of doing graphics (CreateGraphics and .Paint or OnPaint), but i wasn't sure if it was possible to use the Form.Paint method because I am creating the lines from multiple other forms and modules. It's not just a standard set of drawlines that are done each time that form loads. Am I right to assume that I have to use .CreateGraphics for this type of setup I thought about the possibility that the placement of where I declare .CreateGraphics could be causing problems. I was hesitant to declare the CreateGraphics in each respective form because I wasn't sure if the form would have already been loaded when the lines were being created. So I declared them in a module thinking that this way I would not have to worry about whether the forms had been loaded. Was I wrong to do this Thanks again,

    gareth

  • mhawb

    Here's a sample for drawing a line.



    Public Class Form1
        Private x1 As Integer = 0, x2 As Integer, y1 As Integer = 0, y2 As Integer

        Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
            x2 = Rnd() * Me.Width
            y2 = Rnd() * Me.Height
            e.Graphics.DrawLine(Pens.Black, x1, y1, x2, y2)
        End Sub

        Private Sub Form1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
            Me.Invalidate()
        End Sub
    End Class

     



    I think the problem with your code, is that the variable LinePen is a null value.
    Try addding the line .. LinePen = Color.Black   (or any color you want)

    Another thing, you shouldn't really use the .CreateGraphics, as i understand it, it's slow to create the graphics object over and over.  Instead, use e.Graphics  from the Paint Event.

    Dustin.


  • generic error occured in GDI+ (drawline)