Win32 Tree Question
-
It seems that when I add to a TreeControl (Win32 SDK not MFC) the pszString item I add is not the same was what I put in (eg. Put in text and get back a large string of hi-ascii). I insert into the tree thusly:
TVINSERTSTRUCT tvs; TVITEM tvi; HTREEITEM last; tvs.hInsertAfter = TVI_LAST; tvi.mask = TVIF_TEXT; tvi.pszText = "Test Item #1"; tvs.hParent = TVI_ROOT; tvs.item = tvi; last = TreeView_InsertItem(GetDlgItem(MainWindow,IDC_TREE),&tvs);
To retrieve I handle the WM_NOTIFY message when the event is TVN_SELCHANGED.case WM_NOTIFY: node = (LPNMTREEVIEW)lParam; if(node->hdr.code == TVN_SELCHANGED) { MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0); } break;
In the debugger node->itemNew.pszText is high ascii garbage and no where near the "Test #1" item I put in. The book I have and the docs I've found so far all use the TreeControl by comparing the selected item to a list of the items added which is no good for me because I'm trying to build up the entire path from each selected tree item (like a file path). This occurs with multiple items in the tree control as well. Any suggestions or ideas on where I have gone wrong would be greatly appricated. Sean -
It seems that when I add to a TreeControl (Win32 SDK not MFC) the pszString item I add is not the same was what I put in (eg. Put in text and get back a large string of hi-ascii). I insert into the tree thusly:
TVINSERTSTRUCT tvs; TVITEM tvi; HTREEITEM last; tvs.hInsertAfter = TVI_LAST; tvi.mask = TVIF_TEXT; tvi.pszText = "Test Item #1"; tvs.hParent = TVI_ROOT; tvs.item = tvi; last = TreeView_InsertItem(GetDlgItem(MainWindow,IDC_TREE),&tvs);
To retrieve I handle the WM_NOTIFY message when the event is TVN_SELCHANGED.case WM_NOTIFY: node = (LPNMTREEVIEW)lParam; if(node->hdr.code == TVN_SELCHANGED) { MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0); } break;
In the debugger node->itemNew.pszText is high ascii garbage and no where near the "Test #1" item I put in. The book I have and the docs I've found so far all use the TreeControl by comparing the selected item to a list of the items added which is no good for me because I'm trying to build up the entire path from each selected tree item (like a file path). This occurs with multiple items in the tree control as well. Any suggestions or ideas on where I have gone wrong would be greatly appricated. SeanRule #1 of the list/tree control structs is: always init them to zero. You'd be surprised how much havoc is wrought if you don't do that.
TVINSERTSTRUCT tvs = {0};
TVITEM tvi = {0};--Mike-- Just released - RightClick-Encrypt - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm
-
Rule #1 of the list/tree control structs is: always init them to zero. You'd be surprised how much havoc is wrought if you don't do that.
TVINSERTSTRUCT tvs = {0};
TVITEM tvi = {0};--Mike-- Just released - RightClick-Encrypt - Adds fast & easy file encryption to Explorer My really out-of-date homepage Sonork-100.19012 Acid_Helm
Unfortunately, even with that problem still occurs. :L Sean
-
It seems that when I add to a TreeControl (Win32 SDK not MFC) the pszString item I add is not the same was what I put in (eg. Put in text and get back a large string of hi-ascii). I insert into the tree thusly:
TVINSERTSTRUCT tvs; TVITEM tvi; HTREEITEM last; tvs.hInsertAfter = TVI_LAST; tvi.mask = TVIF_TEXT; tvi.pszText = "Test Item #1"; tvs.hParent = TVI_ROOT; tvs.item = tvi; last = TreeView_InsertItem(GetDlgItem(MainWindow,IDC_TREE),&tvs);
To retrieve I handle the WM_NOTIFY message when the event is TVN_SELCHANGED.case WM_NOTIFY: node = (LPNMTREEVIEW)lParam; if(node->hdr.code == TVN_SELCHANGED) { MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0); } break;
In the debugger node->itemNew.pszText is high ascii garbage and no where near the "Test #1" item I put in. The book I have and the docs I've found so far all use the TreeControl by comparing the selected item to a list of the items added which is no good for me because I'm trying to build up the entire path from each selected tree item (like a file path). This occurs with multiple items in the tree control as well. Any suggestions or ideas on where I have gone wrong would be greatly appricated. SeanNullStream wrote: In the debugger node->itemNew.pszText is high ascii garbage and no where near the "Test #1" item I put in That must be because you are simply not looking at the good item. I do not know enough about non MFC app to be of a great help, but try to see if the lines
node = (LPNMTREEVIEW)lParam;
if(node->hdr.code == TVN_SELCHANGED) {
MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0);
}really refers to the correct item. ~RaGE();
-
It seems that when I add to a TreeControl (Win32 SDK not MFC) the pszString item I add is not the same was what I put in (eg. Put in text and get back a large string of hi-ascii). I insert into the tree thusly:
TVINSERTSTRUCT tvs; TVITEM tvi; HTREEITEM last; tvs.hInsertAfter = TVI_LAST; tvi.mask = TVIF_TEXT; tvi.pszText = "Test Item #1"; tvs.hParent = TVI_ROOT; tvs.item = tvi; last = TreeView_InsertItem(GetDlgItem(MainWindow,IDC_TREE),&tvs);
To retrieve I handle the WM_NOTIFY message when the event is TVN_SELCHANGED.case WM_NOTIFY: node = (LPNMTREEVIEW)lParam; if(node->hdr.code == TVN_SELCHANGED) { MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0); } break;
In the debugger node->itemNew.pszText is high ascii garbage and no where near the "Test #1" item I put in. The book I have and the docs I've found so far all use the TreeControl by comparing the selected item to a list of the items added which is no good for me because I'm trying to build up the entire path from each selected tree item (like a file path). This occurs with multiple items in the tree control as well. Any suggestions or ideas on where I have gone wrong would be greatly appricated. SeanI would suggest that where you have gone wrong is to assume the pszText member of itemNew is valid, it isnt. See the MSDN Library topic for TVN_SELCHANGED. Try it like this: if(node->hdr.code == TVN_SELCHANGED) { node->itemNew.mask |= TVIF_TEXT; TreeView_GetItem(GetDlgItem(MainWindow,IDC_TREE),&node->itemNew); MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0); }
-
I would suggest that where you have gone wrong is to assume the pszText member of itemNew is valid, it isnt. See the MSDN Library topic for TVN_SELCHANGED. Try it like this: if(node->hdr.code == TVN_SELCHANGED) { node->itemNew.mask |= TVIF_TEXT; TreeView_GetItem(GetDlgItem(MainWindow,IDC_TREE),&node->itemNew); MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0); }
Ok. That seem to do it and according to the help file I ended up with:
HWND ctrl = GetDlgItem(MainWindow,IDC_TREE); char buffer[1024]; memset(buffer,0,1024); if(ctrl == NULL) MessageBox(MainWindow,"GET TREE","Selection CHANGED!",0); node->itemNew.mask |= TVIF_TEXT; node->itemNew.pszText = buffer; node->itemNew.cchTextMax = 1024; if(TreeView_GetItem(ctrl,&node->itemNew)) MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0);
This works fine but it seems from the Help files regarding TVITEM suggest than I can only "tell" if an item has a child. Is there a way to use the control itself to follow the lineage of the selected item? For arguments sake let's just say i'm trying to implement a file browser (not the case but the same idea). If I choose a file I need to build up the entire path based on the selection back to through the parents to the root. Do I have to "already know" the structure of the tree already? Having two copies (one in the tree control itself and the other in my program) of the same tree in memory seems to be a waste and terribly inefficient which is why I'm trying to just use the data in the treecontrol instead of building a tree data structure in memory which is replicated to the treecontrol. Man that's wierdly stated hopefully I'm making some sort of sense here. X| Sean -
Ok. That seem to do it and according to the help file I ended up with:
HWND ctrl = GetDlgItem(MainWindow,IDC_TREE); char buffer[1024]; memset(buffer,0,1024); if(ctrl == NULL) MessageBox(MainWindow,"GET TREE","Selection CHANGED!",0); node->itemNew.mask |= TVIF_TEXT; node->itemNew.pszText = buffer; node->itemNew.cchTextMax = 1024; if(TreeView_GetItem(ctrl,&node->itemNew)) MessageBox(MainWindow,(char *)node->itemNew.pszText,"Selection CHANGED!",0);
This works fine but it seems from the Help files regarding TVITEM suggest than I can only "tell" if an item has a child. Is there a way to use the control itself to follow the lineage of the selected item? For arguments sake let's just say i'm trying to implement a file browser (not the case but the same idea). If I choose a file I need to build up the entire path based on the selection back to through the parents to the root. Do I have to "already know" the structure of the tree already? Having two copies (one in the tree control itself and the other in my program) of the same tree in memory seems to be a waste and terribly inefficient which is why I'm trying to just use the data in the treecontrol instead of building a tree data structure in memory which is replicated to the treecontrol. Man that's wierdly stated hopefully I'm making some sort of sense here. X| SeanSean, Either way is messy, keeping a copy of the structure in memory or using the control. Look to continuously call TreeView_GetParent() until it returns NULL. If you use a loop you will need to insert the parent item's text at the beginning of the buffer each time. If you use a recursive function call then you can build the string by appending each item's text on the way back out of the recursive function.
-
Sean, Either way is messy, keeping a copy of the structure in memory or using the control. Look to continuously call TreeView_GetParent() until it returns NULL. If you use a loop you will need to insert the parent item's text at the beginning of the buffer each time. If you use a recursive function call then you can build the string by appending each item's text on the way back out of the recursive function.
That's exactly what I'm looking for and using GetParent doesn't sound as messy as a tree comparisson unless of course the control itself doesn't handle it well. I'd have to do a recursive match either way so I'll let the control do most of the work. Thanks a million none the less. :-D Sean