Board index » delphi » Painting Only What Needs Painting

Painting Only What Needs Painting

How is it possible to find out what portion of the client area of a
form needs repainting in the OnPaint event of the form?  In C you
normally call BeginPaint which fills out a paint structure, which
tells you which portion of the area is invalidated.  How do you do
something like this in Delphi?

Thanks,
Eric

 

Re:Painting Only What Needs Painting


On Sat, 17 Feb 1996 18:05:40 GMT, emey...@flinet.com (Eric Meyers)
wrote:

Quote
>How is it possible to find out what portion of the client area of a
>form needs repainting in the OnPaint event of the form?  In C you
>normally call BeginPaint which fills out a paint structure, which
>tells you which portion of the area is invalidated.  How do you do
>something like this in Delphi?

>Thanks,
>Eric

If you look in the Windows API help under WM_PAINT, it talks about how
to get the update region, and when you should or should not call
BeginPaint.  Essentially what you will do, is do a set of API
functions to get the area which needs painting, then paint there.

Re:Painting Only What Needs Painting


Quote
>How is it possible to find out what portion of the client area of a
>form needs repainting in the OnPaint event of the form?

        You could use the API GetUpdateRect, but you don't need to -
only the invalid part gets repainted in the OnPaint.

        You sound like you don't believe it. Add a field num:integer to the
form, and then say the following in the form's OnPaint handler:

canvas.brush.style:=bsClear;
canvas.rectangle(0,0,num,num);
num:=num+10;

Now experiment: Run the program and cover the form by another window - each
time you uncover it a slightly larger rectangle appears. The interesting part:
Cover part of the form by another window but leave the upper left corner of that
rectangle visible. Now pull the window away and see what happens.

--
David Ullrich
Don't you guys find it tedious typing the same thing
after your signature each time you post something?
I know I do, but when in Rome...

Re:Painting Only What Needs Painting


Quote
David Ullrich wrote:

> >How is it possible to find out what portion of the client area of a
> >form needs repainting in the OnPaint event of the form?

>         You could use the API GetUpdateRect, but you don't need to -
> only the invalid part gets repainted in the OnPaint.

Actually no, or yes, but not quite (or something similar). What happens
is that the clipping code in Windows prevents the output to be put out.
That is, the code for the painting is executed, but the output is stopped.
So if you have a really slow painting algorithm (like a fractal or something),
uncovering all or part of the window would take (almost) the same time
to repaint.
So calling GetUpdateRect might be worthwhile.
Of course, doing the drawing on an off-screen bitmap and then just blasting
it on would be better.... :*)

Quote
> Don't you guys find it tedious typing the same thing
> after your signature each time you post something?
> I know I do, but when in Rome...

Yes!  :*)

M.

--
Martin Larsson, author of several unknown utilities for DOS and Windows.
mailto:martin.lars...@delfi-data.msmail.telemax.no
http://www.delfi.infonet.no
X.400:G=martin;S=larsson;O=delfi-data;P=msmail;A=telemax;C=no

Re:Painting Only What Needs Painting


Quote
Martin Larsson <martin.larsson@delfi_data.msmail.telemax.no> wrote:
>David Ullrich wrote:

>> >How is it possible to find out what portion of the client area of a
>> >form needs repainting in the OnPaint event of the form?

>>         You could use the API GetUpdateRect, but you don't need to -
>> only the invalid part gets repainted in the OnPaint.
>So calling GetUpdateRect might be worthwhile.
>Of course, doing the drawing on an off-screen bitmap and then just blasting
>it on would be better.... :*)

I'm having the same problem.  I need to find the Invalid region within my
Paint procedure.  While I'm writing a component, I did look through the
source code and TForm does much the same thing as TCustomControl.  The
problem is as the original poster alluded.  Coming from a C/C++ background
I'm used to calling BeginPaint and EndPaint by hand.  And when this is done
you pass it a TPaintStruct and get back in rcPaint the coordinates of the
current Invalid rectangle.  But, as in my case, TWinControl.PaintHandler
makes the call to BeginPaint and to EndPaint.  In between, it calls
PaintWindow, which calls Paint.  So, way down here in the inheiritance
chain, how do I get a hold of that rcPaint that tells me what the invalid
rectangle looks like.  PaintHandler made the call to BeginPaint, so I
*cannot* use GetUpdateRect as the call to BeginPaint validates the region.
And the TPaintStruct (PS) passed to BeginPaint is a local variable.  

Now, this is the way I'm seeing it.  Obviously I believe I've missed
something.  I cannot believe that what I'm seeing as a roadblock is really
the way things were designed.  TForm does things much the same way as
TCustomControl. They share TWinControl as a closed ancestor.

Please, tell us.  How does one find the invalid region down in the paint
procedure for that class?

Re:Painting Only What Needs Painting


Quote
>Actually no, or yes, but not quite (or something similar). What happens
>is that the clipping code in Windows prevents the output to be put out.
>That is, the code for the painting is executed, but the output is stopped.

        Oh. Thanks...

--
David Ullrich
Don't you guys find it tedious typing the same thing
after your signature each time you post something?
I know I do, but when in Rome...

Re:Painting Only What Needs Painting


EM>How is it possible to find out what portion of the client area of a
EM>form needs repainting in the OnPaint event of the form?  In C you
EM>normally call BeginPaint which fills out a paint structure, which
EM>tells you which portion of the area is invalidated.  How do you do
EM>something like this in Delphi?

This is the general problem with abstraction. In the OnPaint event, you
cannot do this directly. However, you can call the GetUpdateRect API
function or create a WM_PAINT message handler.

Regards,

Jani

--
---------------------------------------------------------------------
Jani Jarvinen, Helsinki Finland          jani.jrvi...@hiway.fipnet.fi

Check out Help Editor 2.0 for Windows at:
ftp://ftp.mpoli.fi/metropoli/windows/utils/hlped20.zip

1996: Only four years to computer confusion!
What have you done to avoid it?
---------------------------------------------------------------------
---
 * SLMR 2.1a *

Re:Painting Only What Needs Painting


In article <31287CFC.3FB@delfi_data.msmail.telemax.no>, Martin Larsson <martin.l

Quote
arsson@delfi_data.msmail.telemax.no> writes:
|>David Ullrich wrote:

|>>
|>> >How is it possible to find out what portion of the client area of a
|>> >form needs repainting in the OnPaint event of the form?
|>>
|>>         You could use the API GetUpdateRect, but you don't need to -
|>> only the invalid part gets repainted in the OnPaint.
|>
|>Actually no, or yes, but not quite (or something similar). What happens
|>is that the clipping code in Windows prevents the output to be put out.
|>That is, the code for the painting is executed, but the output is stopped.
|>So if you have a really slow painting algorithm (like a fractal or something),
|>uncovering all or part of the window would take (almost) the same time
|>to repaint.
|>So calling GetUpdateRect might be worthwhile.
|>Of course, doing the drawing on an off-screen bitmap and then just blasting
|>it on would be better.... :*)
|>
|>Martin Larsson, author of several unknown utilities for DOS and Windows.

Hi

Thanks for the explanation. It matches my observations of the
behavior of my program. My question is related to the onResize (or
is it onSize) event and the onPaint event. I am painting information
on the form canvas and when the form is resized, the entire format
of the information on the form need reformating. When the form is
dragged to a larger size, I use on the onResize event to reformat and
repaint the information on the canvas. Next the onPaint event is
triggered and information is repainted again, but only the new
portion of the form is actually repainted. This causes a slight flicker
on the portion of the form that is actually repainted. I suppose that
the flicker is related to the painting routines which actually do the
painting in a couple of layers. I do need the onPaint event to repaint
the form when it have been covered and then uncovered. I did try to
place all the display (or painting) code in the onPaint event but then
only the new part of the form was repainted rather than the entire form.
Is there a proper way to deal with the onResize and onPaint events
happening together or do I need to cleanup my painting routines ?

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
Chris Poole
Computing Services                        E-Mail: Chris.Po...@USask.CA
56 Physics Building                       Phone: (306) 966-4807
University of Saskatchewan                FAX:   (306) 966-4938
Saskatoon, Saskatchewan, Canada, S7N 0W0

Re:Painting Only What Needs Painting


        I'm not sure I follow the question. It seems like maybe the problem
is the following: When you resize the form you want to have everything repainted
but in fact only the part that just appeared gets repainted. That's the problem
I faced when I was drawing a checkerboard for someone that was supposed to
resize with the form, anyway - if I made the form bigger I got the old board
with part of the new one appearing around the edges.

        IF that's the problem then the solution (well, _a_ solution) is simply
to call the Invalidate method for the form (or the paintbox or whatever) in
the OnResize event.

--
David Ullrich
Don't you guys find it tedious typing the same thing
after your signature each time you post something?
I know I do, but when in Rome...

Other Threads