pratimag
asked on
check/Uncheck tree control in MFC using recursive
i have a tree control with check boxes. i want to check or uncheck the tree control using recursive function.
how can i do this.
Requirements.
1. when i click on check box of an item all its parent should be checked.
2. when i double click on check box of an item all its child nodes has to be checked.
3. if an item has childrens then its single click event should not change the state of its item.
how can i do this.
Requirements.
1. when i click on check box of an item all its parent should be checked.
2. when i double click on check box of an item all its child nodes has to be checked.
3. if an item has childrens then its single click event should not change the state of its item.
ASKER
i have written a recursive function for this, but it is not working properly. if someone can send a sample code for this i will be greatful to him.
Send in your code and I will tell you what you need to correct.
Are you/your design requirements flexible enough to implement
a non recursive implementation?
Are you/your design requirements flexible enough to implement
a non recursive implementation?
ASKER
Here is the code:
The description for parameters:
hParent - parent node of the item checked(in some cases it might be the grandparent node)
void CTestDialog::CheckParentSt atus(HTREE ITEM hParent,BOOL &bchkTreeStatus)
{
HTREEITEM hChildItem;
CTreeCtrl* pDbgTree = (CTreeCtrl*)GetDlgItem(IDC _DEBUGGING TREE);
if(pDbgTree->ItemHasChildr en(hParent ))
{
hChildItem = pDbgTree->GetChildItem(hPa rent);
while (hChildItem != NULL)
{
BOOL btemp = pDbgTree->GetCheck(hChildI tem);
if(btemp)
{
if(pDbgTree->ItemHasChildr en(hChildI tem))
{
CheckParentStatus(hChildIt em,bchkTre eStatus);
}
else
{
bchkTreeStatus = TRUE;
}
break;
}
else
{
if(pDbgTree->ItemHasChildr en(hChildI tem))
{
CheckParentStatus(hChildIt em,bchkTre eStatus);
}
else
{
bchkTreeStatus = FALSE;
}
}
hChildItem = pDbgTree->GetNextItem(hChi ldItem, TVGN_NEXT);
}
} // END of if loop for checking the children
else
{
BOOL btemp = pDbgTree->GetCheck(hParent );
if(btemp)
{
bchkTreeStatus = TRUE;
}
else
{
bchkTreeStatus = FALSE;
}
return;
}
if(bchkTreeStatus)
{
pDbgTree->SetCheck(hParent ,TRUE);
HTREEITEM hpItem;
hpItem = pDbgTree->GetParentItem(hP arent);
while(hpItem != NULL)
{
pDbgTree->SetCheck(hpItem, TRUE);
hpItem = pDbgTree->GetParentItem(hp Item);
}
}
else
{
pDbgTree->SetCheck(hParent ,FALSE);
HTREEITEM hpItem;
hpItem = pDbgTree->GetParentItem(hP arent);
while(hpItem != NULL)
{
pDbgTree->SetCheck(hpItem, FALSE);
hpItem = pDbgTree->GetParentItem(hp Item);
}
}
}
The description for parameters:
hParent - parent node of the item checked(in some cases it might be the grandparent node)
void CTestDialog::CheckParentSt
{
HTREEITEM hChildItem;
CTreeCtrl* pDbgTree = (CTreeCtrl*)GetDlgItem(IDC
if(pDbgTree->ItemHasChildr
{
hChildItem = pDbgTree->GetChildItem(hPa
while (hChildItem != NULL)
{
BOOL btemp = pDbgTree->GetCheck(hChildI
if(btemp)
{
if(pDbgTree->ItemHasChildr
{
CheckParentStatus(hChildIt
}
else
{
bchkTreeStatus = TRUE;
}
break;
}
else
{
if(pDbgTree->ItemHasChildr
{
CheckParentStatus(hChildIt
}
else
{
bchkTreeStatus = FALSE;
}
}
hChildItem = pDbgTree->GetNextItem(hChi
}
} // END of if loop for checking the children
else
{
BOOL btemp = pDbgTree->GetCheck(hParent
if(btemp)
{
bchkTreeStatus = TRUE;
}
else
{
bchkTreeStatus = FALSE;
}
return;
}
if(bchkTreeStatus)
{
pDbgTree->SetCheck(hParent
HTREEITEM hpItem;
hpItem = pDbgTree->GetParentItem(hP
while(hpItem != NULL)
{
pDbgTree->SetCheck(hpItem,
hpItem = pDbgTree->GetParentItem(hp
}
}
else
{
pDbgTree->SetCheck(hParent
HTREEITEM hpItem;
hpItem = pDbgTree->GetParentItem(hP
while(hpItem != NULL)
{
pDbgTree->SetCheck(hpItem,
hpItem = pDbgTree->GetParentItem(hp
}
}
}
Hi
I read the code,
I tried reproducing the error on my machine, by adding
a dialog box around your code, but could not do much
after that as I got swamped in my own work.
Shouldn't you divide functions that handle parents
and childs into separate functions and call each of them
exactly once.
Due to current design, for every child you will loop
over its parents. This although not infinite loop
is waste of time and complicated logic.
Few questions, what is the second param for? to return
the finally check value or value to set in first place.
You seem to be using same variable for multiple reasons.
if possible, Send me event code where you make this call!
I read the code,
I tried reproducing the error on my machine, by adding
a dialog box around your code, but could not do much
after that as I got swamped in my own work.
Shouldn't you divide functions that handle parents
and childs into separate functions and call each of them
exactly once.
Due to current design, for every child you will loop
over its parents. This although not infinite loop
is waste of time and complicated logic.
Few questions, what is the second param for? to return
the finally check value or value to set in first place.
You seem to be using same variable for multiple reasons.
if possible, Send me event code where you make this call!
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
To be deleted and points refunded
Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
Roshan Davis
EE Cleanup Volunteer
I will leave a recommendation in the Cleanup topic area that this question is:
To be deleted and points refunded
Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
Roshan Davis
EE Cleanup Volunteer
I had forgotten about this question. I think she used the solutions implied
and got on with it. I leave it to you to judge whether it is sufficiently
answered. In any case, I would request u to remove question from PAQ
list so that some other poor joe does not end up wasting points to see it.
and got on with it. I leave it to you to judge whether it is sufficiently
answered. In any case, I would request u to remove question from PAQ
list so that some other poor joe does not end up wasting points to see it.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
you will need two separate recursive paths.
1st path : Check/uncheck parent of current element and recurse on parent.
2nd path : Check current element and loop for all its childs. (recurse at each child node)
When item is clicked, you travel on 1st path.
When item is double clicked, You will need to go to both paths and in this case
you have to ensure (via sentinel or thru global var) that items do not overlap
Needless to say, recursion is intuitive to think, but tricky to implement and also
tree control tends to present itself as a linked list, so looped alogirthms may
be more efficient.