TreeView & WM_PAINT

R

RedLars

I'm curious, given the below code, where does .NET perform the drawing
of the treeview? I'm especailly interested in how a TreeNode is painted
on the screen with a checkbox in front of it.

And yes, I'm fully aware of the TreeViewDrawMode.OwnerDrawText and
base.SetStyle(ControlStyles.UserPaint, true); options.

class TreeViewE : System.Windows.Forms.TreeView
{
public TreeViewE()
{
this.DrawMode = TreeViewDrawMode.Normal;
}
}

By using .NET Reflector on System.Windows.Forms.dll I have debugged the
issue at bit.

It seems the TreeView::WndProc does not handle WM_PAINT message and
send it to the base class.

The Control::WndProc forwards the WM_PAINT message to WmPaint.

Here is where I get a bit lost. The method is pasted in below but its
difficult to follow it, especially with "Native" methods being called.
I'm assuming at some stage the Graphics object needs to be used to draw
text, checkbox etc.

private void WmPaint(ref Message m)
{
if (this.DoubleBuffered ||
(this.GetStyle(ControlStyles.AllPaintingInWmPaint) &&
this.DoubleBufferingEnabled))
{
IntPtr ptr1;
Rectangle rectangle1;
NativeMethods.PAINTSTRUCT paintstruct1 = new
NativeMethods.PAINTSTRUCT();
bool flag2 = false;
if (m.WParam == IntPtr.Zero)
{
ptr1 = UnsafeNativeMethods.BeginPaint(new HandleRef(this,
this.Handle), out paintstruct1);
rectangle1 = new Rectangle(paintstruct1.rcPaint_left,
paintstruct1.rcPaint_top, paintstruct1.rcPaint_right -
paintstruct1.rcPaint_left, paintstruct1.rcPaint_bottom -
paintstruct1.rcPaint_top);
flag2 = true;
}
else
{
ptr1 = m.WParam;
rectangle1 = this.ClientRectangle;
}
IntPtr ptr2 = Control.SetUpPalette(ptr1, false, false);
try
{
if ((rectangle1.Width > 0) && (rectangle1.Height > 0))
{
Rectangle rectangle2 = this.ClientRectangle;
using (BufferedGraphics graphics1 =
this.BufferContext.Allocate(ptr1, rectangle2))
{
Graphics graphics2 = graphics1.Graphics;
graphics2.SetClip(rectangle1);
GraphicsState state1 = graphics2.Save();
using (PaintEventArgs args1 = new
PaintEventArgs(graphics2, rectangle1))
{
this.PaintWithErrorHandling(args1, 1,
false);
graphics2.Restore(state1);
this.PaintWithErrorHandling(args1, 2,
false);
graphics1.Render();
}
}
}
}
finally
{
if (ptr2 != IntPtr.Zero)
{
SafeNativeMethods.SelectPalette(new HandleRef(null,
ptr1), new HandleRef(null, ptr2), 0);
}
}
if (flag2)
{
UnsafeNativeMethods.EndPaint(new HandleRef(this,
this.Handle), ref paintstruct1);
}
}
else
{
if (m.WParam == IntPtr.Zero)
{
NativeMethods.PAINTSTRUCT paintstruct2 = new
NativeMethods.PAINTSTRUCT();
IntPtr ptr3 = this.Handle;
IntPtr ptr4 = UnsafeNativeMethods.BeginPaint(new
HandleRef(this, ptr3), out paintstruct2);
IntPtr ptr5 = Control.SetUpPalette(ptr4, false, false);
try
{
PaintEventArgs args2 = new PaintEventArgs(ptr4, new
Rectangle(paintstruct2.rcPaint_left, paintstruct2.rcPaint_top,
paintstruct2.rcPaint_right - paintstruct2.rcPaint_left,
paintstruct2.rcPaint_bottom - paintstruct2.rcPaint_top));
try
{
if
(this.GetStyle(ControlStyles.AllPaintingInWmPaint))
{
this.PaintWithErrorHandling(args2, 1,
false);
args2.ResetGraphics();
}
this.PaintWithErrorHandling(args2, 2, false);
return;
}
finally
{
args2.Dispose();
if (!this.IsDisposed && this.IsHandleCreated)
{
ptr3 = this.Handle;
}
UnsafeNativeMethods.EndPaint(new
HandleRef(this, ptr3), ref paintstruct2);
}
return;
}
finally
{
if (ptr5 != IntPtr.Zero)
{
SafeNativeMethods.SelectPalette(new
HandleRef(null, ptr4), new HandleRef(null, ptr5), 0);
}
}
}
PaintEventArgs args3 = new PaintEventArgs(m.WParam,
this.ClientRectangle);
this.PaintWithErrorHandling(args3, 2, true);
}
}

Appreciate any input
 

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