How can i find treeview node by which label equals string variable?
c++, winapi
Solution
The treeview control does not provide an API to search for a label. You will have to manually traverse the items and compare them to your string.
If your treeview is more than one level deep you will have to decide how to traverse the items (either depth first or breadth first). In case there are multiple items with the same label these strategies may return different items.
An implementation might look something like this:
// Helper function to return the label of a treeview item
std::wstring GetItemText( HWND hwndTV, HTREEITEM htItem )
{
static const size_t maxLen = 128;
WCHAR buffer[ maxLen + 1 ];
TVITEMW tvi = { 0 };
tvi.hItem = htItem; // Treeview item to query
tvi.mask = TVIF_TEXT; // Request text only
tvi.cchTextMax = maxLen;
tvi.pszText = &buffer[ 0 ];
if ( TreeView_GetItem( hwndTV, &tvi ) )
{
return std::wstring( tvi.pszText );
}
else
{
return std::wstring();
}
}
This is where the actual traversal takes place. The function is called recursively until no more items can be searched or a match has been found. This implementation uses a case-sensitive comparison (`wstring::operator==( const wstring& )`). If you need a different predicate you will have to modify the implementation as you see fit.
HTREEITEM FindItemDepthFirstImpl( HWND hwndTV, HTREEITEM htStart, const std::wstring& itemText )
{
HTREEITEM htItemMatch = NULL;
HTREEITEM htItemCurrent = htStart;
// Iterate over items until there are no more items or we found a match
while ( htItemCurrent != NULL && htItemMatch == NULL )
{
if ( GetItemText( hwndTV, htItemCurrent ) == itemText )
{
htItemMatch = htItemCurrent;
}
else
{
// Traverse into child items
htItemMatch = FindItemDepthFirstImpl( hwndTV, TreeView_GetChild( hwndTV, htItemCurrent ), itemText );
}
htItemCurrent = TreeView_GetNextSibling( hwndTV, htItemCurrent );
}
return htItemMatch;
}
The following function wraps the recursion and passes the root element as the starting point. This is the function you would call in your code. It will return an `HTREEITEM` if one is found, `NULL` otherwise.
HTREEITEM FindItem( HWND hwndTV, const std::wstring& itemText )
{
HTREEITEM htiRoot = TreeView_GetRoot( hwndTV );
return FindItemDepthFirstImpl( hwndTV, htiRoot, itemText );
}
Problem
I would like to start by saying thanks to everyone who takes some time to view this thread and try to help. I have searched the Internet, and couldn't find an example of selecting tree view node that has label text as same as text of a string variable. On MSDN I have found message TVM_GETISEARCHSTRING but I don't know if it can be used to solve my problem. Even if it can, I still don't know how to use it. I have a string variable that holds text from database. When program loads, tree view should have a node with the same text selected. Please help with some instructions or code snippets, since I have no clue how to even start coding this. I work in MS Visual Studio Express 2008, on Windows XP, in C++, using pure WIN32 API. That would be all, again I thank everyone who tries to help.Thank you very very much! EDIT: Both answers are good for me, but I don't know how to mark them both, it seems that on this site only one answer can be accepted. I couldn't have just neglected all the work both of them invested to help me, so I write this in order to try to repay to the Jonathan at least by officially stating that his solution is acceptable for me too, it is just that Tim's solution suits my coding style better.I will also upvote both answers.