Gdi

barski

Well-known member
Joined
Apr 7, 2002
Messages
239
Location
Tennessee
ive just started tinkering with gdi and have a very basic question. attached is form class that fills a rectangle and it works but when i resize it the information from the original rectangle is retained therefore causing it to look less than great. any info on what im missing here would be nice.
 

Attachments

The question is how can you tell that the rectangle stays the same? According to your rectangle set up, the rectangle is always extending 100 pixels from the left end all the way over to the right from top to bottom.
 
Iceplug said:
The question is how can you tell that the rectangle stays the same? According to your rectangle set up, the rectangle is always extending 100 pixels from the left end all the way over to the right from top to bottom.
I assume barski means because of the errors in the gradient. In certain cases, resizing the form causes odd patterns to appear in gradient (giving an effect similar to offset stacked squares, assumbably something todo with the size changes during resize). Ive had a reasonable amount of experience using GDI+ and I couldnt fix the problem (at least I couldnt fix it in the few minutes I spent).
 
Ok, I obviously wasnt thinking hard enough last time as I managed to fix it this time. Heres some stuff you need to know...

Firstly drawing in the OnPaint event is not always the quickest method of achieving what you want. As a general rule I like to keep by OnPaint method as clear as possible so I do all drawing to a BackBuffer, which in my case is a Bitmap object. The only code I would put in the OnPaint method is as follows.
C#:
		protected override void OnPaint(PaintEventArgs e)
		{
                        // buffer is a Bitmap object declared at the top of the form
                        // and initialised (at least to start with) in the contructor.
			if(buffer != null)
				e.Graphics.DrawImageUnscaled(buffer, 0, 0);
		}
Now your probably thinking well thats nice but it doesnt draw anything, in which case your quite right. So we also need to add code to draw to the buffer. The way I generally do this is by creating a method called Draw().
C#:
		private void Draw()
		{
			// load buffer into a graphics object
			System.Drawing.Graphics graphx = Graphics.FromImage(buffer);						
			
			// create objects
			System.Drawing.Rectangle rect = new Rectangle(0,0,this.Width,this.Height);			
			System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(rect,System.Drawing.Color.Blue,System.Drawing.Color.Gray,System.Drawing.Drawing2D.LinearGradientMode.BackwardDiagonal);		
			
			// draw to buffer
			graphx.FillRectangle(brush,rect);	
			
			// dispose of objects to prevent memory leak
			brush.Dispose();
			graphx.Dispose();

			// tell the application to update the screen (which essential calls OnPaint)
			Invalidate();
		}
This piece of code does all the drawing operations, painting everything to the buffer. So we need to call this section of code whenever we need to change something. Now in the case of resizing the form we need todo two things. Firstly resize the buffer so that it is the right size again and secondly call the draw method all over again.
C#:
		private void Form1_Resize(object sender, System.EventArgs e)
		{
			buffer = new Bitmap(this.Width, this.Height);
			Draw();
		}
If you were to run the application at this stage you should notice that everything looks ok, but the Form appears to flash during Resize. This is because OnPaintBackground is called before OnPaint, in situations where you are painting all or the majority of the Control/Form you should Override this method to prevent it from drawing the background first. (alternatively you could draw as part of that method instead, but I tend to stick with the OnPaint method.)
C#:
		protected override void OnPaintBackground(PaintEventArgs pevent)
		{
                        // comment out to avoid flicker
			// base.OnPaintBackground (pevent);
		}
Right I think that covers most aspects of the method I use to buffer controls. Other people may do it differently but this method has served me well.
 
Back
Top