Chris

Chris

  • NA
  • 7
  • 0

GDI+ Invalidate() artifacts

Mar 25 2008 11:32 AM
Hi all,

Could someone please explain to me why the following code doesnt work?


<code>
   Rectangle r = new Rectangle(0, 0, 100, 100);
            Pen p = Pens.Black;
      private void Form1_Load(object sender, EventArgs e)
            {

this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint,true);

                  //a.AddLine(new Point(10, 10), new Point(100, 10));

            }
            protected override void OnMouseMove(MouseEventArgs e)
            {
                  //Invalidate old location
                  Invalidate(r);
                  r.Location = e.Location;
                  //Invalidate new location
                  Invalidate(r);
            }
            protected override void OnPaint(PaintEventArgs e)
            {
                  base.OnPaint(e);

                  //Clear clipping rect
                
                  e.Graphics.FillRectangle(Brushes.White, e.ClipRectangle);

                  //Draw invalidated region
                  e.Graphics.DrawRectangle(p, r); //Method will draw the right and bottom side out of clipping rect

            }</code>

When i run it, the rectangles bottom and right hand side are drawn outside the clipping rectangle. I thought that if something was drawn outside the clipping rectangle, it would be discarded. However this doesnt seem to be the case here.

when i move the mouse, I move the rectangles location also. Before i change the location of the rect, i invalidate it, and then invalidate again once change has been made.

In the drawing routine i wipe the clipping rect with background colour, but for some reason artifacts ouside the clipping area remain.

The end result of the mouse move is an artifact trail, similar to a mouse trail and exactly like what happens, when you win at ms solitare.

It would appear that im not invalidating the right area, but i dont understand why!

I have done a fair bit of graphics programming before, and have never experienced any problem like this. If im invalidating the old bounds before changing them for the new bounds, it should be removing the old screen.


If i change the drawing code to make sure that the rectangle is drawn inside the clipping rect, the problem doesnt happen.
But I just cant understand why the problem occurs anyway. Surely invalidate should cause the overlapping line to be removed?

Here is the code that has been modified not to overdraw the clipping region:


<code>
      protected override void OnPaint(PaintEventArgs e)
            {
                  base.OnPaint(e);

                  //Clear clipping rect
                
                  e.Graphics.FillRectangle(Brushes.White, e.ClipRectangle);
                  Rectangle r2 = r;
                  r2.Height -= 1;
                  r2.Width -= 1;
                  //Draw invalidated region
                  e.Graphics.DrawRectangle(p, r2); //Method will draw the right and bottom side out of clipping rect

            }</code>

I would be most grateful to anyone that could point me in the right direction, or tell me if im doing something stupid.

Many thanks,
chris.


Answers (1)