I have written an event handler method and attached it to the Paint event of a Form (just the main window). This event sends a PaintEventArgs containing a property called Graphics, which is an instance of System.Drawing.Graphics.
Here is the code I’m using:
private void Form1_Paint(object sender, PaintEventArgs e) {
Bitmap bm = new Bitmap("fruit-dealer-full.jpg");
Graphics g1 = this.CreateGraphics();
Graphics g2 = e.Graphics;
// g1.DrawImage(bm, 0, 0, this.Width, this.Height);
// g1.DrawRectangle(
// Pens.White, 10.0f, 10.0f, this.Width - 200, this.Height - 200);
g2.DrawImage(bm, 0, 0, this.Width, this.Height);
g2.DrawRectangle(
Pens.White, 10.0f, 10.0f, this.Width - 200, this.Height - 200);
}
Ultimately I just want to gain a better understanding of what’s happening here, but specifically I have these three questions:
- Why does
g1redraw the image in the whole window, whileg2only draws the new portion, even if I callg2.Clear()before drawing? - Why, with either
Graphicsobject, is the image only redrawn when the window increases in size, and not when it is made smaller? - If
PaintEventArgs.Graphicscan (or should) not be used for drawing, what is it used for? I would imagine it just prevents you from having to create a newGraphicsinstance if the form doesn’t need to be redrawn; is there more to it that I’m missing?
You .NET WinForms kids really should learn the Win32 API. Pick up a copy of Petzold already!
Presumably
g2is a wrapper around a device context received fromBeginPaint. I imagine WinForms wrapsPAINTSTRUCT::rcPaintfor you – this variable describes the area to be painted. This is expected behaviour – rather than burning CPU cycles redrawing your entire window every single time another window overlaps it by just one pixel, you can redraw … just the one pixel!g2.Clearis presumably limited byrcPaint.g1is probably aGetDCfor the window – which gives you the entire surface to draw on.The underlying window class probably doesn’t have
CS_HREDRAWorCS_VREDRAWwindow styles. Without these, there’s no reason for the default behaviour to request you redraw the window when it gets smaller: Windows knows what the entire window looks like, it can clip the unwanted bits away. This is unlike when the window gets bigger, it doesn’t know what to draw in the new area.It’s used for drawing. Unless you have some complex drawing requirements, you can use the
PaintEventArgs.Graphicsminimize the amount of painting that goes on to your window. (As above – this is a huge saver of CPU cycles and it’s probably a simple wrapper overBeginPaintandEndPaint– which is how drawing to the client area is meant to be done.)