|
I have a TreeView with 8 root nodes in which I want to select / deselect all decedent nodes based on any given node I select / deselect.
I have tried overriding the OnNotify, but have been unsuccessful in trying to get the behavior I want. Currently, the OnNotify only seems to work on the first root node... none of the other sibling root nodes seem to trip the OnNotify. The other problem I'm having is on the one root node that does respond via OnNotify, I cannot traverse its branches to select / deselect node paths I want ignored. All decendant nodes of this one root node only react when the root node is selected / deselected.
This is what I have on the OnNotify:
BOOL CViewFilter::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
if (wParam == IDC_TREE1)
{
HTREEITEM hItem = m_filterTreeCtrl.GetSelectedItem();
if ((hItem != 0) && (m_filterTreeCtrl.GetCheck(hItem) == 0))
{
SetDecendentNodesOff(hItem);
}
else if ((hItem != 0) && (m_filterTreeCtrl.GetCheck(hItem) == 1))
{
SetDecendentNodesOn(hItem);
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
Any help would be greatly appreciated.
modified on Thursday, September 4, 2008 1:56 PM
|
|
|
|
|
I read your post a couple times and I have no idea what you are trying to do. Have you read any beginner material for working with windows tree controls like this CodeProject article[^]
That's only one, there are tens of CP articles using the Tree Control
led mike
|
|
|
|
|
I am using a tree view with 16,384 nodes (2048 nodes per root node). I'm trying to allow a user to select or deselect a node anywhere on the tree view such that when a node is selected or deselected, all of its children nodes would mirror that selection.
|
|
|
|
|
There is a lot of notifications sent by a tree control.
Do you really want your code to execute on every one of them?
Also, what are you doing with the item check state, and how does
that apply to the selected item?
Tree View Controls[^]
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I originally tried doing a message map of the OnNotify that I saw elsewhere through googling, but there does not seem to be a notification appropriate for what I want to do.
I was using item check state to see if the node which has the user's focus was checked or not.
The idea was that once a user clicks on a node within the tree view, OnNotify would fire off and it would check to see if the node was selected or not. Depending on its state, I would either select or deselect all decedent nodes from the node the user selected.
|
|
|
|
|
What about something like this:
BOOL CViewFilter::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
if (wParam == IDC_TREE1)
{
NMHDR *pHdr = (NMHDR *)lParam;
if (pHdr->code == TVN_SELCHANGED)
{
LPNMTREEVIEW pNMTreeView = (LPNMTREEVIEW)lParam;
if (pNMTreeView->itemNew.hItem)
{
if (m_filterTreeCtrl.GetCheck(pNMTreeView->itemNew.hItem))
{
SetDecendentNodesOn(pNMTreeView->itemNew.hItem);
}
else
{
SetDecendentNodesOff(pNMTreeView->itemNew.hItem);
}
}
return TRUE;
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
It only works on the very first mouse click for the first root node only. Decendent nodes nor any of the other root nodes have any effect on the OnNotify.
After the first mouse click to either select / deselect the 1st root node, that root node then behaves like the other root nodes.
|
|
|
|
|
Do you call SetCheck anywhere? How do the items get their check state set?
What's happening in your SetDecendentNodes functions?
Have you put a breakpoint in the OnNotify? Are you getting
notifications for all item selections?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I do not call SetCheck.
The nodes get their check state set whenever the user clicks on the node's box to check or uncheck the node.
|
|
|
|
|
Ohhh....
Maybe you want the TVN_ITEMCHANGED notification instead of TVN_SELCHANGED
BOOL CViewFilter::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
if (wParam == IDC_TREE1)
{
NMHDR *pHdr = (NMHDR *)lParam;
if (pHdr->code == TVN_ITEMCHANGED)
{
NMTVITEMCHANGE *pNMTVItemChange = (NMTVITEMCHANGE *)lParam;
if (pNMTVItemChange->hItem)
{
if (m_filterTreeCtrl.GetCheck(pNMTreeView->itemNew.hItem))
{
SetDecendentNodesOn(pNMTVItemChange->hItem);
}
else
{
SetDecendentNodesOff(pNMTVItemChange->hItem);
}
}
return TRUE;
}
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yeah, that was one I had tried using before but the problem is you need Windows Vista to use it. I'm running on XP Pro.
|
|
|
|
|
Stuck At Zero wrote: the problem is you need Windows Vista to use it
There's other OSs?
Do you get any notification in XP when you check/uncheck an item?
If so, what is the code?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
I really thought it was available on XP.
The macro is wrapped in "#if (_WIN32_IE >= 0x0600)"
which seems to indicate a common controls version 6
or better feature.
If you define _WIN32_IE to something >= 0x0600 does
it work on XP? I don't have a handy XP machine to test on.
Also, have you tried (in the debugger)to see if there's any
notification sent when you change the check state? I'm interested
in what notification code it is if there is one.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I couldn't figure out how to filter out the other things OnNotify would trigger, but I believe part of my problem seems to be that the hItem is what the TreeView has as a keyboard highlighted region rather than the actual node clicked on by mouse.
Do you have any ideas as to change hItem to reflect what is actually clicked on by the mouse and thus ignore the keyboard rectangular region that highlights the 1st root node or changes if I use my keyboard to move it around?
In other words,
HTREEITEM hItem = m_filterTreeCtrl.GetSelectedItem();
Is not with respect to the node I click on with my mouse.
|
|
|
|
|
Hi, I'm using VC++ with MFC.
I have a CScrollBar in my program which is supposed to perform various functions when it is moved.
How can I tell when the user has clicked on the scrollbar and moved it up and down? I thought it might just be EN_CHANGE but this does not seem to work.
I am setting up all of the scroll bar's parameters using SetScrollInfo, which does seem to work, but I cannot tell when the bar is moved and when it IS moved, it does not seem to "stick" at its new position, it just returns to the "nPos" that I initially set it to in SetScrollInfo.
KR
|
|
|
|
|
|
|
In my application i am creating a dialog to create a new username and passowrd. i am saving the username ans password in a file. now i want to know how do i update my password with the help of a gui. now the format of the file is
harry pass_harry
what is the way to change the password?
|
|
|
|
|
A better way would be to encrypt and store the password into a database. I am not sure how safe is it to store passwords along with username in a text file.
Many are stubborn in pursuit of the path they have chosen, few in pursuit of the goal - Friedrich Nietzsche
.·´¯`·->Rajesh<-·´¯`·.
[Microsoft MVP - Visual C++]
|
|
|
|
|
Chandrasekharanp wrote: ...know how do i update my password with the help of a gui.
A file is a file whether you are using a GUI, a console, or a service.
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|
|
I just wanted to parse some data read into an CStringArray. The string to be parsed is got out of the array and is a CString type.
I have been trying to use strtok() to do this.
Typical string is "qwerty,123,,33,ABCD,,4545,"
I have another member variable (CString type array) to hold the parsed strings (as CString).
Typical string is "qwerty,123,,33,ABCD,,4545," sent to the GetDataItem procedure.
void CGenerate_FilesDlg::GetDataItem(CString str)
{
char *P1 = strtok((char*)(LPCTSTR)str, ",");
char *P2 = strtok(NULL, "\0");
}
I get error when trying to put the parsed data into m_ParseParams[]
Error 3 error C2664: 'void ATL::CStringT<BaseType,StringTraits>::Format(const wchar_t *,...)' : cannot convert parameter 1 from 'const char [3]' to 'const wchar_t *' c:\generate_filesdlg.cpp 225
I am having problems with the UNICODE.
Because I am using CStringArray I seem to be having problems using functions like strtok() in the VS 2005 environment.
What I am trying to do is so simple, but in a mess with types!
Andy.
|
|
|
|
|
Most CRT string functions have a TCHAR.H generic string
type equivalent. Since CString is a generic string type
you should use generic string CRT functions.
Try _tcstok().
You may also want to look into using equivalent CStringT
methods instead of using CRT functions on CStrings.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi Mark, can you give me a few pointers as to use MFC C++ with UNICODE.
I was just using the following:-
CString str = _T("qwerty");
and then casting my way out of any problems.
I seem to have come unstuck.
Just need help with project options, header files and settings, if possible.
Many thanks,
Andy.
|
|
|
|
|
Andy202 wrote: Just need help with project options, header files and settings, if possible.
What do you mean? Either UNICODE is defined (via #define ) or it isn't.
"Love people and use things, not love things and use people." - Unknown
"The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch
|
|
|
|