PC Review Forums Newsgroups Microsoft DotNet Microsoft Dot NET Framework Forms TreeView & WM_PAINT

Reply

TreeView & WM_PAINT

 
Thread Tools Rate Thread
Old 11-01-2007, 06:57 AM   #1
RedLars
Guest
 
Posts: n/a
Default TreeView & WM_PAINT


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

  Reply With Quote
Old 15-01-2007, 12:30 AM   #2
Bryan Phillips
Guest
 
Posts: n/a
Default Re: TreeView & WM_PAINT

The painting is done inside the Win32 API.

--
Bryan Phillips
MCSD, MCDBA, MCSE
Blog: http://bphillips76.spaces.live.com



"RedLars" <Liverpool1892@gmail.com> wrote in message
news:1168498662.625713.236260@i39g2000hsf.googlegroups.com:

> 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


  Reply With Quote
Reply



Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off