0

A snippet of my code:

    Dim G As Graphics
    Dim BBG As Graphics
    Dim BB As Bitmap

    Dim R As Rectangle

..................................................................

            picMainScreen.Visible = True
            G = picMainScreen.CreateGraphics
            BB = New Bitmap(picMainScreen.Width, picMainScreen.Height)
            For x = 0 To 256 * 3 - 1 Step 24
                For y = 0 To 240 * 3 - 1 Step 24
                    R = New Rectangle(New Point(x, y), New Point(24, 24))

                    G.DrawRectangle(Pens.Black, R)
                Next
            Next

In this snippet of code, picMainScreen was a PictureBox that was originally not supposed to be visible. Then through some conditions, picMainScreen was SUPPOSED to TURN Visible. And THEN, the code draws all the rectangles onto the picture.

However, that isn't the case: the rectangles are first drawn onto the picture, and THEN the picture becomes visible.

Why does this happen? And what's the remedy?

Mary
  • 14,926
  • 3
  • 18
  • 27
Darp mosh
  • 1
  • 3
  • 2
    Do not EVER call `CreateGraphics`. If you want to draw on a control then do so in its `Paint` event handler. As a control is never painted when it's not visible, your code will only be executed when the control is visible and it will be executed when the control becomes visible. The proper way to use GDI+ is to store the data the represents the drawing in one or more fields and then read those fields in the `Paint` event handler. Whenever the data changes, you call `Invalidate` on the control to prompt a `Paint` event. – jmcilhinney Jan 25 '21 at 02:26
  • Huh? As you can tell from my code, I'm DYNAMICALLY trying to create squares every 27 pixels in width and height. About the Graphics stuff.......I.......do NOT understand ANYTHING when it comes to graphics. What are the prerequisites? And what's the solution to my problem? – Darp mosh Jan 25 '21 at 02:28
  • 1
    *"I.......do NOT understand ANYTHING when it comes to graphics"*. Then take the time and make the effort to learn. This is not a tutorial site, nor is it a code-writing service. I have told you that you need to use the `Paint` event. That means that you need to stop what you are doing and go and learn about the `Paint` event, which you have clearly made no effort to do. There are lots of examples around of GDI+ using the `Paint` event. If you haven't tried to find them, let alone understand them, then you haven't done your part yet. – jmcilhinney Jan 25 '21 at 02:31
  • Ok man, so I learned about the Paint Event. It's an event that's called every time the control is redrawn or is changed. But here's the real kicker: you said that I can't EVER use CreateGraphics. But without it, how am I supposed to draw dynamically? I need the program to create a bunch of squares dynamically and that's something humans CAN'T do. And I did use the Paint control as well, but it never remedied the problem mentioned above. – Darp mosh Jan 25 '21 at 03:13
  • There is no "Paint control". Maybe you mean a `PictureBox` control. That's not magic though. It is better for GDI+ because it is optimised to prevent flicker but you still need to use the same code on the same event. – jmcilhinney Jan 25 '21 at 03:47
  • 1
    GDI+ is pretty simple. You store the data that represents your drawing in one or more fields. In your case, if you want to draw squares then a `List(Of Rectangle)` would be appropriate. In the `Paint` event handler, you read that data and draw what it represents. Any time you make a change to that data, you call `Invalidate` on the control to prompt a `Paint` event event. Ideally you would calculate the smallest area that has or may have changed and pass that as an argument to `Invalidate`. It's the painting of pixels that is the slow part so that's what you want to minimise. – jmcilhinney Jan 25 '21 at 03:50
  • [Here](https://www.vbforums.com/showthread.php?890262-Need-help-with-DrawEllipse()-and-Me-Refresh()-and-Label1-text&p=5508086&viewfull=1#post5508086) is an example I posted elsewhere just this morning. If you follow the CodeBank link in the signature of that post, you'll find a number of other Drawing threads that also exemplify drawing in the `Paint` event handler. In fact, here are direct links to [1](https://www.vbforums.com/showthread.php?426684), [2](https://www.vbforums.com/showthread.php?531022) and [3](https://www.vbforums.com/showthread.php?588199) of them. – jmcilhinney Jan 25 '21 at 03:51
  • You do not need CreateGraphics when you use the Paint event. One of the arguments provides the Graphics object. `Dim g As Graphics = e.Graphics` where e is the PaintEventArgs provided by the event. I don't see how you could have studied and understood the Paint event and missed that. – Mary Jan 25 '21 at 16:16

1 Answers1

-1

Your rectangle instantiation is interesting since you are using two parameters of type Point. R = New Rectangle(New Point(x, y), New Point(24, 24))

The Microsoft Docs show these parameter types; Rectangle(Point, Size) Initializes a new instance of the Rectangle class with the specified location and size.

https://learn.microsoft.com/en-us/dotnet/api/system.drawing.rectangle.-ctor?view=netframework-4.7.2

I'm not sure if the parameter types are the problem; however you are mixing drawing graphics with a picture control and they might not cohabitate in the same space well.

You could try calling DoEvents() after making the picture control visible to force it to be displayed first.

  • Thank you. I'm currently now learning about what DoEvents() are. It's strange. I don't know of a forum to discuss questions like this. It seems like this isn't a forum to discuss questions like this, yet I can't find a better forum. That being said, I've tested it by first actually setting the picbox to be visible and the program worked perfectly; the rectangles were drawn onto the picbox without being overwritten. Thank you. – Darp mosh Jan 25 '21 at 02:41
  • Glad I could help! I love your Avatar image :) – Bruce B Wilson Jan 25 '21 at 02:57
  • 1
    Re DoEvents, really shouldn't be used now days unless there is absolutly no other option (Hint, I've not used it in near 20years) and advising people to use it now is really is ill advised. – Hursey Jan 25 '21 at 02:58
  • @Hursey Oh? Then what is your solution to my problem? Not even DoEvents seems to do the trick to me. – Darp mosh Jan 25 '21 at 03:23
  • @Darpmosh well, as hash as what jmcilhinney has suggested, using the paint events would be they way to go. – Hursey Jan 25 '21 at 03:25
  • Huh? Then how do I go about using it? Every single time when the screen loads the paint event also loads as well. After that, when this snippet of the code runs, my original problem occurs anyways; the drawing occurs BEFORE the picturebox becomes visible, which overwrites the entire drawing. What should I do then? – Darp mosh Jan 25 '21 at 03:29
  • @Darpmosh Well, I would suggest another question with the details of your reworked solution – Hursey Jan 25 '21 at 03:52