[Author Press] CTREECTRL Tree control check box, there is no direct click message. That is, when we click on the check box, there is no directly corresponding to the message mapping. I don't know what is the reason why Microsoft deliberately is. The author believes that Microsoft just wants to use the check box as a static logo.
[Program Function] A number of questions from many netizens is: Click on a directory in the tree, I hope that the child node in this directory is selected or not selected at the same time (ie check box at the same time). In some software installations, we can see similar features.
[Implementation] This article only implements the inspection box of the directory, select or not select the direct sub-node in this directory, regardless of the child node under the subdirectory in the directory, It can be extended to the program provided herein. As for other applications, it is easy to implement after the selected check box is obtained. This article tests under VC6.0.
The way in this paper is to derive a CTREECTRL subclass CMYTREECTRL, then overload the NM_Click event of CTreeCtrl, and do the following processing in this event:
1. Use the getCursorpos function to get the mouse position. Convert the point coordinates to coordinates with respect to the control with the ScreenToClient function.
Cpoint Pt; GetCursorpos (& PT); ScreenToClient (& PT);
2. Use the HitTest function to detect which directory you have selected.
HtreeItem HITEM = Hittest (PT);
3. Get the rectangle size of this directory with GetItemRect (calculate text)
CRECT RC; GetItem, rc, true); // true indicates that only the size of the text
4. Calculate the size and location of the check box according to the size and position of the text
CRECT CHECKRC; Checkrc.top = rc.top; checkrc.bottom = rc.bottom; checkrc.left = rc.left - rc.height (); // Consider check box is a rectangular checkrc.right = rc.left;
5. It is judged whether or not the position of the mouse is in the location of the check box of the directory. If, modify the child node status
IF (PtinRect (Checkrc, PT)) {}
If so, you can confirm that the mouse click on the check box of the directory. The following operation is to consistency with the status of the child node in the directory.
IF (PtinRect (CHECKRC, PT)) {if (itemHaschildren (HITEM)) // Decision is a directory {bool bcheck = getCheck (HITEM); // Get directory status hnext = getChildItem (HITEM); // Get first A child node while (hnext! = Null) {setCheck (hnext,! BCheck); // Modify child node status hnext = getNextSiblingItem (hnext); // Get the next child node}}}}
============================================================================================================================================================================================================= ========== The full program is as follows:
void CMyTreeCtrl :: OnClick (NMHDR * pNMHDR, LRESULT * pResult) {CPoint pt; GetCursorPos (& pt); ScreenToClient (& pt); HTREEITEM hItem = HitTest (pt); CRect rc; GetItemRect (hItem, rc, true); CRect checkRc Checkrc.top = rc.top; checkrc.bottom = rc.bottom; checkrc.left = rc.Left - rc.height (); checkrc.right = rc.left; if (PtinRect (Checkrc, PT)) {IF (ItemHasChildren (hItem)) {BOOL bCheck = GetCheck (hItem); HTREEITEM hNext = GetChildItem (hItem); while (! hNext = NULL) {SetCheck (hNext, bCheck!); hNext = GetNextSiblingItem (hNext);}}} * PRESULT = 0;}