Groups | Blog | Home
all groups > dotnet windows forms controls > april 2008 >

dotnet windows forms controls : UserControl always erases all ClientRectangle


Juan Dent
4/3/2008 6:20:01 PM
Hi,

I am creating a UserControl in VS2005, which overrides OnPaint and
OnPaintBackground.
I have a button placed in a corner inside of the control which when pressed
calls Invalidate(rect) with a rectangle that is only part of the
ClientRectangle (actually one half). I expected both OnPaint and
OnPainitBackground routines would receive a e.ClipRectangle equal to the
rectangle passed to Invalidate().
However, inspecting OnPaintBackground i can see that the clipping rectangle
is equal to the ClientRectangle as if I had called Invalidate() instead of
Invalidate(rect).

Also, I am puzzled as to why OnPaintBackground is called at all. Where can I
control if I want to invalidate a portion of a control but not force an
erasing of the background?


--
Thanks in advance,

Morten Wennevik [C# MVP]
4/3/2008 10:30:00 PM
Hi Juan,

Make sure Visual Studio isn't causing the entire control to be repainted.
This means to effectively see what happens in the paint calls you need to be
able to see the entire control while Visual Studio is focused. Drag the
control to a second monitor or adjust the size of Visual Studio so that it
doesn't cover the control.

OnPaintBackground should receive the same ClipRectangle as OnPaint, and in
my test it does that as well. Furthermore if you use
SetStyle(ControlStyles.Opaque, true) OnPaintBackground won't get called at
all, which means you can draw transparent controls and whatnot using just
OnPaint. Use this if the background painting is overriding your drawing
algorithm.

As for the point of OnPaintBackground. This is .Net's answer to the
WM_ERASEBKGND message sent by Windows to prepare a control for repainting.
Generally this just means you don't have to clear the background of the
control before you draw lines and such.

--
Happy Coding!
Morten Wennevik [C# MVP]


[quoted text, click to view]
jetan@online.microsoft.com (
4/4/2008 6:04:58 AM
Hi Juan,

The PaintEventArgs parameter of OnPaintBackground() method is hard coded.
It always contains the client rectangle of the target control. It is setup
in the Control.WmEraseBkgnd() method, like below:

//From .Net Reflector
private void WmEraseBkgnd(ref Message m)
{
.....
NativeMethods.RECT rect = new NativeMethods.RECT();
UnsafeNativeMethods.GetClientRect(new HandleRef(this,
this.Handle), ref rect);
PaintEventArgs e = new PaintEventArgs(wParam,
Rectangle.FromLTRB(rect.left, rect.top, rect.right, rect.bottom));
this.PaintWithErrorHandling(e, 1, true);
.....
}
As you can see, the Winform code sets up PaintEventArgs structure with
values from GetClientRect() Win32 API, so this is expected.
PaintWithErrorHandling() finally calls OnPaintBackground() method by
passing this PaintEventArgs.

Regarding why OnPaintBackground() is called, it is determined by the
ControlStyle of the UserControl. Basically, this message is determined by
the 3rd parameter of the Win32 InvalidateRect() API. In the source code of
"Invalidate()", we can see:

public void Invalidate(bool invalidateChildren)
{
if (this.IsHandleCreated)
{
if (invalidateChildren)
{
SafeNativeMethods.RedrawWindow(new HandleRef(this.window,
this.Handle), (NativeMethods.COMRECT) null, NativeMethods.NullHandleRef,
0x85);
}
else
{
using (MultithreadSafeCallScope scope = new
MultithreadSafeCallScope())
{
SafeNativeMethods.InvalidateRect(new HandleRef(this.window,
this.Handle), (NativeMethods.COMRECT) null, (this.controlStyle &
ControlStyles.Opaque) != ControlStyles.Opaque);
}
}
this.NotifyInvalidate(this.ClientRectangle);
}
}

As you can see, .Net Winform code use (this.controlStyle &
ControlStyles.Opaque) != ControlStyles.Opaque) logic to determine whether
to erase the control background or not. Since your control did not
ControlStyles.Opaque style by default, the "bErase" parameter is always
true for InvalidateRect() API. This generates the WM_ERASEBKGND message
when BeginPaint function is finally called. Please see the MSDN link below
for details:
http://msdn2.microsoft.com/en-us/library/ms534893(VS.85).aspx

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
=========================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.



Ken Halter
4/24/2008 9:24:29 AM
[quoted text, click to view]

Beta quality development platforms produce beta quality applications. Even
if your code is perfect, don't expect the framework bugs to go away... no,
instead, they'll replaced by new bugs.

--
Ken Halter - MS-MVP-VB - Please keep all discussions in the groups..
In Loving Memory - http://www.vbsight.com/Remembrance.htm

AddThis Social Bookmark Button