Add a background image to the TreeView in C #

Source: Internet
Author: User
Tags transparent color valid win32 window
The TreeView is in Microsoft's. NET Forms window controls, such as the TreeView and ListView, are simply encapsulation of common controls, so they do not normally raise paint events. The only advice you can see in Microsoft's release is to set the Controlstyles.userpaint type of the control, and then do all the drawing operations for the control yourself. The foreigner provides a Treeviewwithpaint control class that derives from the TreeView class and provides hooks for paint events. )

To solve this problem, we used a graphics object based on the bitmap class inside the class. When any window is redefined, the object will be rebuilt.

Recreate internal Graphics object
protected override void OnResize (System.EventArgs e)
{
if (Internalbitmap = null | | internalbitmap.width!= Width | | internalbitmap.height!= Height)
{
if (Width!= 0 && Height!= 0)
{
Disposeinternal ();
Internalbitmap = new Bitmap (Width, Height);
Internalgraphics = Graphics.fromimage (Internalbitmap);
}
}
}
Second, rewrite the window process

When the control receives the WM_PAINT message, the following three steps are performed:

1. Through an internal wm_printclient message, let the original control process to draw the image to the internal graphics object.

Draw Internal Graphics
INTPTR hdc = INTERNALGRAPHICS.GETHDC ();
Message Printclientmessage = Message.create (Handle, Wm_printclient, HDC, IntPtr.Zero);
Defwndproc (ref printclientmessage);
INTERNALGRAPHICS.RELEASEHDC (HDC);
2. Create PaintEventArgs parameters using the internal graphics object, and raise the OnPaint () function of the user.

Add the Missing OnPaint () call
OnPaint (New PaintEventArgs (Internalgraphics, RECTANGLE.FROMLTRB (
Updaterect.left,
Updaterect.top,
Updaterect.right,
Updaterect.bottom)));
3. Copy the bitmap of the internal graphics object to the graphics device on the screen.

Draw Screen Graphics
Screengraphics.drawimage (internalbitmap, 0, 0);

WM_ERASEBKGND messages are filtered out and do nothing. Case WM_ERASEBKGND:
Removes flicker
Return
Third, the provided code and test program can use the Paint event to draw a yellow border on the border when TreeNode is selected. However, in fact, for the project I actually want to use, the ability to add a background map is not implemented. And here is a step away from our purpose, we add a step between 2 and 3 of the preceding drawing process:

Bitmap temp = new Bitmap (Internalbitmap, internalbitmap.size); Create a temporary bitmap temp, save the previously painted interface

Temp. Maketransparent (Color.White); Set White to Transparent color
Internalgraphics.fillrectangle (brushes.white, 0, 0, this.) Bounds.width, this. Bounds.height);
On the original interior bitmap object, redraw the background with white
if (image!= null)//If a background image is set, draw the background on the inner object
Internalgraphics.drawimage (image, 0, 0, image. Width, image. Height);
Internalgraphics.drawimage (temp, 0, 0, temp.) Width, temp. Height)//Make the front painted interface white to transparent color composite to the internal bitmap
Screengraphics.drawimage (internalbitmap, 0, 0); Brush the synthesized temporary bitmap onto the screen
In fact, there is a problem here: when dealing with WM_PAINT messages, the usual practice is to use the BeginPaint and EndPaint functions to manipulate DC drawing, when the tree node expansion or folding, we received WM_PAINT message, and refresh the area by the message or say flush the rectangle. The key is that the refresh area here is not the entire client area, and the background image is distorted by overlapping parts.

WORKAROUND: Consider the use of GETDC and RELEASEDC operations, you can avoid the limitations of the refresh area, we can redraw the entire customer area, and achieve the integrity of the background. It is important to note here that the BeginPaint and EndPaint functions automatically set the area that needs to be refreshed to be valid, while the GETDC and RELEASEDC functions do not, so we have to add two operations for ourselves GetUpdateRect and ValidateRect, That is, you set the area that needs to be refreshed to be valid. Otherwise: will keep getting WM_PAINT message, and the same as the dead loop, CPU occupancy up to 100%.


Iv. concluding remarks

Because of the use of Win32 API functions, a Win32 inner class is appended, and the functions that you need are imported.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.