Painting: rectangles or regions?

G

Guest

I would lilke to know what is the best (most efficient) way to paint a
control. I was told that if you call Invalidate(Rectangle) Windows will
calculate the bounding rectangle of the current invalid rectangle and the
supplied rectangle (the one passed in the call). This seems like a
sub-optimal approach. Consider a grid in which the top left cell is
invalidated and the bottom right cell is invalidated. The bounding rectangle
is the entire grid. I've looked a bit at regions and it appears as if
regions solves this problem. From what I read it appears if you invalidate a
region Windows will add that region to the invalid regions list and will
continue to send the control WM_PAINT messages until the invalid region list
is empty.

If my above statements are correct I would expect the .NET controls to make
use of regions as opposed to rectangles when it comes to invalidating a
control. However, it appears DataGridView.InvalidateCell() calls
Control.Invalidate(Rectangle) as opposed to Control.Invalidate(Region). Why?
 
S

Stoitcho Goutsev \(100\)

nickdu,

Whenever you invalidate a rectangle or region the windows send WM_PAIN that
contains the bounding rectangle of the invalidated region. This is more
informative, though. When the graphics context its clip region is set that
all the areas that don't belong to the invalidated region are clipped off
(no drowing happens there).
The same is for .NET if you invalidate a region the Paint event args contain
ClipRectangle, which is a bounding rectangle for the clipping region. The
clipping region itself can be get from the Graphics object.

Why InvalidateCell calls Invalidate(Rectangle) I guess this is because the
cells are rectangular. Further more the cells are small. Repainting a small
cell could be comparable to only creating a region in order to call the
invalidate method.

What kind of region you are expecting to be invalidated anyways?
 
G

Guest

What I would like to invalidate are individual cells. And I don't want to
only know about a bounding rectangle. There is a bunch of work that
potentially has to get done to draw each grid cell. Rules may have to run.
Formatting has to take place, etc. So I only want to draw the cells that
need to be drawn. As in the example I gave, if only the upper left cell and
lower right cell need to be drawn (lets say their underlying data has
changed) I don't want to get a bounding rectangle since that would cause me
to redraw all cells. With the bounding rectangle I realize that at some
point when I attempt to actually render to the screen that most of the
drawing would be clipped, but I've already done most of the work by this
point which in this example would have been wasted as only two cells needed
to be updated.

I'm still reading up on a bunch of painting docs so maybe things will become
more clear soon. I've dumped some information in my sample application and
it doesn't make sense to me. I created a user control while I dock fill to
my form. I override OnPaint() in this user control and dump out the clip
rectangle from the PaintEventArgs and the clip bounds from the graphics
object. This is what I get:

clip rectangle: {X=0,Y=0,Width=0,Height=0}
bounds: {X=-4194304,Y=-4194303,Width=8388608,Height=8388608}

I get the same values each time I size the window. The clip rectangle is
empty. What does this mean? That no drawing needs to take place? If so,
why did I get a WM_PAINT message? And why would I get an empty clip
rectangle when I resize (larger) the window? And why this huge clip bounds
that is rooted at some negative origin? Is this just uninitialized data
since the clip rectangle is empty?

--
Thanks,
Nick


Stoitcho Goutsev (100) said:
nickdu,

Whenever you invalidate a rectangle or region the windows send WM_PAIN that
contains the bounding rectangle of the invalidated region. This is more
informative, though. When the graphics context its clip region is set that
all the areas that don't belong to the invalidated region are clipped off
(no drowing happens there).
The same is for .NET if you invalidate a region the Paint event args contain
ClipRectangle, which is a bounding rectangle for the clipping region. The
clipping region itself can be get from the Graphics object.

Why InvalidateCell calls Invalidate(Rectangle) I guess this is because the
cells are rectangular. Further more the cells are small. Repainting a small
cell could be comparable to only creating a region in order to call the
invalidate method.

What kind of region you are expecting to be invalidated anyways?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top