19th lesson tree view control
In this lesson, we will learn how to use tree view controls. Also learn how to complete the drag - pull in the tree view, and how to use the image list.
Theory: Tree view is a special window, we can use it clearly represent a level of relationship. For example, in the left window in the resource manager is a tree view. You can call CREATEWINDOWEX to create a tree view, pass a class name "SystreeView32", or you can also put it in a dialog. Don't forget to join the INTCOMMONCONTROLS function in your code.
Tree view has several unique style. Here are several commonly used.
TVS_HASBUTTONS == Displays ( ) or (-) in the parent project. Users can expand or collect subcommets under the parent project by clicking on the symbol. If you want to have this symbol in the root directory, you must specify the TVS_LinesTroot style.
TVS_haslines == Use the lines in the level to connect to each project name.
TVS_LINESTROOT == Items under root directory are also connected in line. If you do not specify a TVS_haslines style, the style will be ignored.
Like other generic controls, the tree view uses a message to complete the communication. The parent window sends a range of messages to the tree view, while the tree view sends a "Notification" message to its parent window. In this regard, the tree view and other general control have no two.
When there is an event, the tree view sends a WM_NOTIFY message parent window and passes some additional information in the message.
WM_NOTIFY
WPARAM == Control ID. Because this value is not unique, we don't have to use it. We use the HWndFrom or IDFROM member variable in the NMHDR structure.
LPARAM == Pointer to the NMHDR structure. Some controls may pass a pointer to a larger part. But the structure must ensure that its first member variable is a NMHDR variable. In this way, at least one NMHDR type variable can be obtained when processing the LPARAM variable.
Let's take a look at NMHDR:
NMHDR Struct DWORD
HWNDFROM DWORD?
IDFROM DWORD?
Code DWORD?
NMHDR ENDS
HWndFrom is a window handle of a control for sending a WM_NOTIFY message.
IDFROM is the ID of the control to send a WM_NOTIFY message.
Code is the data sent to the parent window.
The tree view is sent to the parent window to head in TVN_. The message received by the tree view takes a TVM_ head, such as TVM_createdragimage. The tree view is sent to the NMHDR type variable during the CODE variable when the TVN_xxx message is sent. The parent window sends a TVM_ message to control the tree view.
Add a project in the tree view to create a TVM_INSERTITEM message after creating a TVM_INSERTITEM message after creating a TVM_INSERTITEM message.
TVM_INSERTITEM WPARAM = 0; LPARAM = Pointer to the structural TV_INSERTSTRUCT;
You should know some terms about the relationship between the projects in the tree view. A project may be a father, son or both. The parent project contains subprojects, and the parent project may be a subproject of other projects. A project without a parent project is called root project. There may be multiple root projects in the tree view. Now let's take a look at the TV_INSERTSTRUCT structure:
TV_INSERTSTRUCT STRUCT DWORD
HParent DWORD?
HinsetAfter DWORD?
ItemType <>
TV_INSERTSTRUCT ENDS
HParent = handle of the parent project. If the value is TVi_root value or null, the project is inserted into the root of the tree view. HinsertAfter = should be inserted into the handle of the project from the rear item or the value below:
TVi_first ==> Insert the header of the list. TVi_last ==> Insert the tail of the list. Tvi_sort ==> Insert in alphabetical order.
ItemType Union
ItemEX TViteMex <>
Item TVItem <>
ItemType Ends
We only use TVItem.
TV_Item Struct DWORD
IMASK DWORD?
HITEM DWORD?
State DWord?
STATEMASK DWORD?
PSZTEXT DWORD?
CCHTEXTMAX DWORD?
IIMAGE DWORD?
ISELECTEDIMAGE DWORD?
CCHildren DWORD?
LPARAM DWORD?
TV_Item Ends
The structure is used to send or receive information about a project of a tree view according to the message type. For example, for the message TVM_INSERTITEM, it is used to specify the properties of the project inserted into the tree view control. For messages TVM_GETITEM, the structure is used to populate information about selected items. IMASK is used to specify those members variables of TV_Item. For example, if TVIF_Text is specified, this means that the PSZText member variable is valid. You can specify several flags at the same time. HITEM is the handle of the tree view project. Every project has its own handle, just like a window. If you want to operate a project, you must choose its handle. PSZText is a string pointer. It is the label name of the project. CchtextMax is only used when the name of the query item is queried. Since the pointer is specified in PSZText, Windows must know the size of the buffer. So you must give this value. IIMAGE and ISELECTEDIMAGE are used to specify an image list and an index number. This way you know that the item is indicated when the item is selected or not selected. A small chart in the folder in the left window in the resource manager is determined by these two parameters. In order to insert an item in the tree view, you must set at least hParent, hinset, and you still have to set the IMASK and PSZText values.
Put the graphics to the graphical view If you want to display the icon on the left side of the project, you must create a graphic list and associate it with the tree view. You can call imagelist_create to create a graphic list.
ImageList_create Proto CX: DWORD, CY: DWORD, FLAGS: DWORD, /
Cinitial: DWORD, CGROW: DWORD
If you create a success, the function returns a handle of an empty image list. CX == in the width of the image of the image. CY == The height of the image in pixels. Each of the image list must be the same. Otherwise Windows cut your image, if you excessively, you may cut into a few pieces. So you must specify the image of the same size. Flags == The color depth of the image of the image list is specified. For details, please refer to the Win32 API Guide. Cinitial == Specifies the number of images included. WindWos will allocate appropriate memory in this way. CGROW == In adding a new image is an increased number.
The image list is not a window. It is only a resource saved to other windows. Once the image list is generated, you can call imagelist_add to join the image. ImageList_add Proto HiMl: DWORD, HBMIMAGE: DWORD, HBMMASK: DWORD
Returns -1 if the function calls failed.
HiML == The handle of the image list. It is the value returned when calling imagelist_create.
HBMIMAGE == Add to the handle of the bitmap of the image list. You usually save the bitmap in the resource, then call LoadBitmap to load it. Note that you don't have to specify the number of images contained in this bitmap. Windows automatically calculates according to its size.
HBmmask == Mask the handle of the bitmap. This value can be ignored if the mask bitmap is not used. Usually we join two images to the image list. An image displayed when it is selected, and when the other is not selected.
When the image list is ready, you can send a message TVM_setImageList to the tree view to let the image list and the tree view.
TVM_SetImageList
WPARAM = The status of the image list, there are two types:
TVSIL_NORMAL contains images that are selected and not selected in both states. TVSIL_State contains images of user-defined status.
LPARAM = Handle of the image list.
Search Tree View Information You can retrieve the information of the graphic view by sending a message TVM_GETITEM.
TVM_GETITEM WPARAM = 0 lparam = Pointer to the structural TV_Item. The structure will be used to obtain relevant information.
The value of the member variable iMask must be set before sending the message so that Windows can tell the relevant information. Of course, the most important thing is that you must pass the handle of the item you want to get information. This caused a problem, how do you get the handle of the project? Want to save the handle of all items? The answer is very simple: there is no need. You can send a message TVM_GetNextItem to the tree view to retrieve the handle of the item you want to get its properties. For example, you can query the handle of the first sub-project, the handle of the root directory, the handle of the selected item, and the like.
TVM_GetNextItem
WPARAM = Sign
LPARAM = Handle of the tree view (only when WPARAM is valued).
The value in WPARAM is very important, I explained below:
TVGN_CARET selected item TVGN_Child Hitem parameter specifies the first child item of the project TVGN_Drophilite drag-pull operation project TVGN_FirstVisible first visible item TVGN_Next Next classified item TVGN_NextVisible Next visible item, the specified item must be visible. Send a message TVM_GETITEMRECT to determine if the project visible TVGN_Parent specifies the parent item of the project TVGN_PREVIOUS ahead of the TVGN_PREVIOSIBLE for the previous visible item, the specified project must be visible. Send a message TVM_GETITEMRECT to determine if the project can see the TVGN_Root root project
This allows you to get the item's handle by sending the message, and then adding information about the item in the Member Variable Hitem of Structure Variable TV_Item when sending a message TVM_GETITEM.
Drag in the tree view - pull operation is because of this part I decided to write this lesson. When I run an example in accordance with the Inprise's Win32 help, I find the lack of realistic information in its help. I only have to do experiments by myself, and finally finalize the way. I hope you don't go to these detours just like me. Here I will describe the steps I know in the tree view in the tree view: When the user wants to drag an item, the tree view control will give it. The parent window sends a TVN_BEGINDRAG notification message. You can create an image in drag operation here, which can be implemented by sending a TVM_CREATEDRAGIMAGE message to the tree view, allowing it to generate a default image to the currently used image. Tree view control will create an image list, where only one image is displayed in the drag, and after the image list is created, you can get its handle. After the image is generated, you can specify the hotspot position of the drag image by calling imagelist_begindrag.
ImageList_Begindrag Proto HiMltrack: DWORD, /
Itrack: DWORD, /
Dxhotspot: DWORD, /
DYHOTSPOT: DWORD
HiMLTrack is a handle of an image list of an image displayed when a drag is displayed
iTrack is the index number selected in the image list.
DXHOTSPOT This image is used to replace the cursor in the drag, so we must specify which point in the image is the position of the upper left corner of the cursor. Dxhotspot is the relative position in horizontal.
Dyhotspot is vertically relative position.
iTrack is equal to 0. If you want to want the hotspot of the cursor in the upper left corner of the image displayed in the drag, set DXHOTSPOT and DYHOTSPOT to 0.
When the image of the drag is to be displayed, we call imagelist_dragenter to display the image in the tree view.
ImageList_Dragenter Proto Hwndlock: DWORD, X: DWORD, Y: DWORD
HWndlock is a handle of a window in drag, and the action of the drag is restricted in this window.
X and Y are coordinate values of the initial position of the image when dragging. These values are in the upper left corner of the client relative to the window.
Since the image in the drag can be displayed, we have to handle the drag operation. There is a small problem here. Our monitoring is achieved by monitoring the movement of the mouse cursor, such as moving the WM_MouSemove message by capturing the WM_MOUSEMOVE message, by capturing the WM_LBUTTONUP message, by capturing the WM_LBUTTONUP message. However, if the parent window cannot be able to get the movement of the mouse cursor and the button message of the mouse when the mouse light is passed. The solution is to call the SetCapture function to lock the mouse event, so that we can know no matter what the mouse moves there, our windows can know. When processing the WM_MOUSEMOVE message, you can call imagelist_dragmove to update the trajectory of the image movement. This function can move the image location in the drag and drop operation. Also, if you want to make the image in some items, you can call TVM_HitteTest to determine if you have a project. If so, you can send a TVM_SELECTITEM message and set the TVGN_Drophilite flag to make the item high brightness display. Note: Before sending a message TVM_SELECTITEM, you must first hide the image list, otherwise it will leave a very ugly trajectory. The image to be hidden in the drag can call imagelist_dragshownolock, then call the function after displaying the image of the luminance to make the image in the drag again. When the user releases the primary key, you have to do a few things. If you release the mouse primary key when you display it in high brightness (indicating that you want to add this item here), you must make the project to make it normally, which can be implemented by sending a message TVM_SELECTITEM message and setting the flag bit TVGN_Drophilite. Just at this time LPARAM must be 0. If you don't let the items displayed by high brightness, you will have a strange phenomenon: When you choose another project, the image of that item will be included in a square, and the high-brightness displayed project is still Previous project. Next, imagelist_enddrag and imagelist_dragleave must be called. There is also a call to release the captured mouse. If you have created an image list, you have to call Calling ImageList to destroy it, you can do additional operations after the drag and drop operation. Example code:
.386
.Model flat, stdcall
Option CaseMAP: NONE
INCLUDE /MASM32/INCLUDE/Windows.inc
INCLUDE /MASM32/INCLUDE/USER32.INC
INCLUDE /MASM32/INCLUDE / WANEL32.INC
INCLUDE /MASM32/INCLUDE/ComctL32.inc
INCLUDE /MASM32/INCLUDE/gdi32.inc
INCLUDELIB /MASM32/LIB/GDI32.LIB
INCLUDELIB /MASM32/LIB/ComctL32.lib
INCLUDELIB /MASM32/LIB/USER32.LIB
INCLUDELIB /MASM32/LIB/kernel32.lib
WinMain PROTO: DWORD,: DWORD,: DWORD,: DWORD .const IDB_TREE equ 4006; ID of the bitmap resource .data ClassName db "TreeViewWinClass", 0 AppName db "Tree View Demo", 0 TreeViewClass db "SysTreeView32", 0 Parent DB "Parent Item", 0 Child1 DB "Child1", 0 Child2 DB "Child2", 0 DragMode DD False; A FLAG TO DETERMINE IF WE ARE IN DRAG MODE.DATA? HINSTANCE HINSTANCE? HWNDTREEVIEW DD?; Handle of the Tree View Control HParent DD?; HANDLE OF THE ROOT TREE VIEW ITEM HIMAGELIST DD?; HANDLE OF THE IMAGELIST USED IN The Tree View Control HDragimagelist Dd?; Handle of the Image List Used to Store The Drag Image
. Code Start: Invoke GetModuleHandle, Null Mov Hinstance, Eax Invoke Winmain, Hinstance, Null, Null, SW_SHOWDEFAULT INVOKE EXITPROCESS, EAX INVOKE INVOMMONTROLS
WinMain proc hInst: HINSTANCE, hPrevInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD LOCAL wc: WNDCLASSEX LOCAL msg: MSG LOCAL hwnd: HWND mov wc.cbSize, SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL push hInst pop wc.hInstance mov wc.hbrBackground, COLOR_APPWORKSPACE mov wc.lpszMenuName, NULL mov wc.lpszClassName, OFFSET ClassName invoke LoadIcon, NULL, IDI_APPLICATION mov wc.hIcon, eax mov wc.hIconSm, eax invoke LoadCursor, NULL, IDC_ARROW mov wc.hCursor, eax invoke RegisterClassEx, addr wc invoke CreateWindowEx, WS_EX_CLIENTEDGE, aDDR ClassName, aDDR AppName, / WS_OVERLAPPED WS_CAPTION WS_SYSMENU WS_MINIMIZEBOX WS_MAXIMIZEBOX WS_VISIBLE, CW_USEDEFAULT, / CW_USEDEFAULT, 200, 400, NULL, NULL, / HINST, NULL MOV HWND, EAX .While True Invoke GetMessage, Addr MSG, NULL, 0, 0. Break .if (! EAX) Invoke TranslateMessage, Addr Msg Invoke DispatchMessage, Addr Msg .Endw Mov Eax, Msg.wParam Ret Winmain Endp
WndProc proc uses edi hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM LOCAL tvinsert: TV_INSERTSTRUCT LOCAL hBitmap: DWORD LOCAL tvhit: TV_HITTESTINFO .if uMsg == WM_CREATE invoke CreateWindowEx, NULL, ADDR TreeViewClass, NULL, / WS_CHILD WS_VISIBLE TVS_HASLINES TVS_HASBUTTONS TVS_LINESATROOT, 0, / 0,200,400, hWnd, NULL, / hInstance, NULL; Create the tree view control mov hwndTreeView, eax invoke ImageList_Create, 16,16, ILC_COLOR16,2,10; create the associated image list mov hImageList, eax invoke LoadBitmap, hInstance, IDB_TREE; load the bitmap from the resource mov hBitmap, eax invoke ImageList_Add, hImageList, hBitmap, NULL; Add the bitmap into the image list invoke DeleteObject, hBitmap; always delete the bitmap resource invoke SendMessage, hwndTreeView , TVM_setimagelist, 0, Himagelist Mov Tvinsert.hparent, Null Mov Tvinsert.hinsertafter, TV I_ROOT mov tvinsert.item.imask, TVIF_TEXT TVIF_IMAGE TVIF_SELECTEDIMAGE mov tvinsert.item.pszText, offset Parent mov tvinsert.item.iImage, 0 mov tvinsert.item.iSelectedImage, 1 invoke SendMessage, hwndTreeView, TVM_INSERTITEM, 0, addr tvinsert mov hParent, eax mov tvinsert.hParent, eax mov tvinsert.hInsertAfter, TVI_LAST mov tvinsert.item.pszText, offset Child1 invoke SendMessage, hwndTreeView, TVM_INSERTITEM, 0, addr tvinsert mov tvinsert.item.pszText, offset Child2 invoke SendMessage, hwndTreeView, TVM_INSERTITEM , 0, addr tvinsert .elseif umsg == wm_mousemove .IF DragMode ==
TRUE mov eax, lParam and eax, 0ffffh mov ecx, lParam shr ecx, 16 mov tvhit.pt.x, eax mov tvhit.pt.y, ecx invoke ImageList_DragMove, eax, ecx invoke ImageList_DragShowNolock, FALSE invoke SendMessage, hwndTreeView, TVM_HITTEST, NULL, addr tvhit .if eax! = NULL invoke SendMessage, hwndTreeView, TVM_SELECTITEM, TVGN_DROPHILITE, eax .endif invoke ImageList_DragShowNolock, TRUE .endif .elseif uMsg == WM_LBUTTONUP .if DragMode == TRUE invoke ImageList_DragLeave, hwndTreeView invoke ImageList_EndDrag invoke ImageList_Destroy, hDragImageList invoke SendMessage, hwndTreeView, TVM_GETNEXTITEM, TVGN_DROPHILITE, 0 invoke SendMessage, hwndTreeView, TVM_SELECTITEM, TVGN_CARET, eax invoke SendMessage, hwndTreeView, TVM_SELECTITEM, TVGN_DROPHILITE, 0 invoke ReleaseCapture mov DragMode, FALSE .endif .elseif uMsg == WM_NOTIFY mov edi, lParam assume edi: ptr NM_TREEVIEW .if [edi] .hdr.code == TVN_BEGINDRAG invoke SendMessage, hwndTreeView, TVM_CREATEDRAGIMAGE, 0, [edi] .itemNew.hItem mov hDragImageList, eax invoke ImageList_BeginDrag, hDragImageList, 0,0,0 invoke ImageList_DragEnter, hwndTreeView, [edi] .ptDrag.x, [edi] .ptDrag.y invoke SetCapture, hWnd mov DragMode, TRUE .endif assume edi: nothing .elseif uMsg ==
WM_DESTROY INVOKE POSTQUITMESSAGE, NULL .ELSE INVOKE DEFWINDOWPROC, HWND, UMSG, WPARAM, LPARM RETPAR END STAR EAX, EAX RET WNDPROC ENDP End Start Analysis: In the code of the message WM_CREATE, you can create a tree view control.
Invoke CreateWindowex, Null, AddR TreeViewClass, NULL, /
WS_CHILD WS_VISIBLE TVS_HASLINES TVS_HASBUTTONS TVS_LINESTROOT, 0, /
0,200,400, hwnd, null, /
Hinstance, NULL
Note: TVS_xxxx is a style unique to the tree view.
Invoke imagelist_create, 16, 16, ilc_color16, 2, 10
Mov HimageList, EAX
Invoke loadingbitmap, hinstance, idb_tree
Mov Hbitmap, EAX
Invoke imagelist_add, himagelist, hbitmap, null
Invoke deleteObject, hbitmap
Invoke SendMessage, HwndtreeView, TVM_setimagelist, 0, HimageList
Next, you can create an empty image list, which is hosted by an image of a pixel 16x16 size and a 16-bit depth, the image list initially contains two images, up to 10. Then we load images from the resource and put them in the list of images. Then we delete the handle of the image because we don't need to use it again. After setting the image list, we link it to the tree view control by sending a message TVM_setImageList.
Mov tvinsert.hparent, null
Mov tvinsert.hinsertafter, TVi_root
Mov tvinsert.u.Item.imask, TVif_text TVif_image TVif_selectedImage
Mov tvinsert.u.Item.psztext, offset parent
Mov tvinsert.u.Item.iimage, 0
Mov tvinsert.u.item.iselectedImage, 1
Invoke SendMessage, HWndtreeView, TVM_INSERTITEM, 0, AddR TVinsert
Now insert the project into the tree view control, first we start from the root project. Because it is a root project, the member variable hParent is null, and HinsetAfter is TVi_root. IMASK specifies the value of PSZText, IIMAGE, and ISELECTEDIMAGE in the TV_Item structure variable. We should give these three member variables to the correct value. Where PSZText displays the name of the project, IIMAGE is an index number of the image in the image list. The image is displayed on the left of the name of the item name, ISELECTEDIMAGE is the image index number of the selected item. After setting these values, we send TVM_INSERTITEM messages to the tree view control to join the root project to the tree view control.
Mov HParent, EAX
Mov Tvinsert.hparent, EAX
Mov tvinsert.hinsertafter, TVi_last
Mov tvinsert.u.Item.psztext, offset child1
Invoke SendMessage, HWndtreeView, TVM_INSERTITEM, 0, AddR TVinsertmov TVinsert.ud.psztext, Offset Child2
Invoke SendMessage, HWndtreeView, TVM_INSERTITEM, 0, AddR TVinsert
After adding the IF, we join the subproject. The member variable hParent is the handle of its parent project, and the value of HinsetAfter is TVi_last. As for the image selected and non-selected, we do not need to change the value of other variables.
.ELSEIF uMSG == WM_NOTIFY
MOV EDI, LPARAM
Assume EDI: PTR NM_TREEVIEW
.IF [EDI] .hdr.code == TVn_begindrag
Invoke SendMessage, HwndtreeView, TVM_createdragimage, 0, [EDI] .Itemnew.hitem
Mov HDragimagelist, EAX
Invoke imagelist_begindrag, HDragimagelist, 0,0,0
Invoke imagelist_dragenter, hwndtreeview, [edi] .ptdrag.x, [edi] .ptdrag.y
Invoke setcapture, hwnd
Mov Dragmode, True
.endif
Assume EDI: Nothing
When the user drags the project, the tree view control will send a WM_NOTIFY message to its parent window, the sub-message number is TVN_BEGINDRAG. In LPARAM, it is a pointer to the structural NM_TreeView, which contains some additional information. Let's put the value of the LPARAM into the EDI register so that EDI can be used as a pointer. "Assume EDI: PTR NM_TREEVIEW" statement is used to tell the compiler MASM to use the EDI as a variable that points to the structure of NM_TreeView. We created a dragned image by sending a message TVM_CreatedragImage. It will return a handle of a newly created image list that contains images in the drag. We call the imagelist_begindrag function to set the hotspot that drags the image. Call the imagelist_dragenter function to enter the operation. This function displays the image in the specific location. At first displayed, we are located in the position of the member variable PTDrag in the structural nm_treeview. We lock the input of the mouse and set the logo variable, indicating that we have entered the drag operation.
.ELSEIF uMSG == WM_MOUSEMOVE
.IF DragMode == True
Mov Eax, LPARAM
And Eax, 0FFFFH
MOV ECX, LPARAM
SHR ECX, 16
Mov TVhit.pt.x, EAX
Mov tvhit.pt.y, ECX
Invoke imagelist_dragmove, Eax, ECX
Invoke ImageList_DragShownolock, False
Invoke SendMessage, HwndtreeView, TVM_Hittest, Null, Addr TVHit
.IF EAX! = NULL
Invoke SendMessage, HWndTreeView, TVM_SELECTITEM, TVGN_DROPHILITE, EAX
.endif
Invoke imagelist_dragshownolock, True
.endif
Now let's take a look at the processing of the WM_MOUSEMOVE message. When the user drags the image, our parent window will receive WM_MOUSEMOVE. In response to these messages, we call imagelist_dragmove to update the location of the updated image. Then we send a message TVM_HitTest to the list view control to see if the image in the drag is just through some items, and of course the information such as the transfer coordinate position. If you pass, we send a message TVM_SELECTITEM and come with the TVGN_Drophilite flag to the tree view control, the latter will display the high brightness to display the project being passed. During the high-brightness display, we hide the image from the image from the drag is ugly. .ELSEIF uMSG == WM_LBUTTONUP
.IF DragMode == True
Invoke imagelist_dragleave, HWNDTreeView
INVOKE IMAGELIST_ENDDRAG
Invoke imagelist_destroy, hdragimagelist
Invoke SendMessage, HWndTreeView, TVM_GetNextItem, TVGN_Drophilite, 0
Invoke SendMessage, HWndtreeView, TVM_SelectItem, TVGN_Caret, EAX
Invoke SendMessage, HwndtreeView, TVM_SELECTITEM, TVGN_DROPHILITE, 0
Invoke ReleaseCapture
Mov Dragmode, False
.endif
When the user releases the left mouse button, the drag operation can be over. We call imagelist_dragleave, imagelist_enddrag, and imagelist_destroy to end the drag operation mode. In order to make the tree view control look good, we check the final high-brightness display project and select it. We must also make its low brightness display, otherwise it is not possible to display when the other items are selected. Finally we release capture of the mouse input event.