The Wayback Machine - https://web.archive.org/web/20111028062101/http://www.codeguru.com/cpp/controls/treeview/treetraversal/article.php/c673/

    Search text in labels




    The tree view control does not have any built-in method for searching the entire tree for a label that contains a given sub-string. The GetItem() function listed below takes a sub-string to search for and searches the item labels for this sub-string. It also has arguments to specify whether to do a case sensitive search, whether to search in the down direction, whether to look for whole words only and which item to start looking from. It uses the GetNextItem(), GetPrevItem() and GetLastItem() described earlier. Note that when a matching item is found, the IsFindValid() function is called to determine if this item is acceptable. IsFindValid() is a virtual function and can be overridden to implement a custom filter. The default implementation returns TRUE.
     
    // FindItem		- Finds an item that contains the search string
    // Returns		- Handle to the item or NULL
    // str			- String to search for
    // bCaseSensitive	- Should the search be case sensitive
    // bDownDir		- Search direction - TRUE for down
    // bWholeWord		- True if search should match whole words
    // hItem		- Item to start searching from. NULL for
    //			- currently selected item
    HTREEITEM CTreeCtrlX::FindItem(CString &str, 
    				BOOL bCaseSensitive /*= FALSE*/, 
    				BOOL bDownDir /*= TRUE*/, 
    				BOOL bWholeWord /*= FALSE*/, 
    				HTREEITEM hItem /*= NULL*/)
    {
    	int lenSearchStr = str.GetLength();
    	if( lenSearchStr == 0 ) return NULL;
    
    	HTREEITEM htiSel = hItem ? hItem : GetSelectedItem();
    	HTREEITEM htiCur = bDownDir ? GetNextItem( htiSel ) : GetPrevItem( htiSel );
    	CString sSearch = str;
    
    	if( htiCur == NULL )
    	{
    		if( bDownDir )  htiCur = GetRootItem();
    		else htiCur = GetLastItem( NULL );
    	}
    
    	if( !bCaseSensitive )
    		sSearch.MakeLower();
    
    	while( htiCur && htiCur != htiSel )
    	{
    		CString sItemText = GetItemText( htiCur );
    		if( !bCaseSensitive )
    			sItemText.MakeLower();
    
    		int n;
    		while( (n = sItemText.Find( sSearch )) != -1 )
    		{
    			// Search string found
    			if( bWholeWord )
    			{
    				// Check preceding char
    				if( n != 0 )
    				{
    					if( isalpha(sItemText[n-1]) || 
    					    	sItemText[n-1] == '_' ){
    						// Not whole word
    						sItemText = sItemText.Right(
    							sItemText.GetLength() - n - 
    							lenSearchStr );
    						continue;
    					}
    				}
    
    				// Check succeeding char
    				if( sItemText.GetLength() > n + lenSearchStr
    					&& ( isalpha(sItemText[n+lenSearchStr]) ||
    					sItemText[n+lenSearchStr] == '_' ) )
    				{
    					// Not whole word
    					sItemText = sItemText.Right( sItemText.GetLength() 
    							- n - sSearch.GetLength() );
    					continue;
    				}
    			}
    			
    			if( IsFindValid( htiCur ) )
    				return htiCur;
    			else break;
    		}
    
    
    		htiCur = bDownDir ? GetNextItem( htiCur ) : GetPrevItem( htiCur );
    		if( htiCur == NULL )
    		{
    			if( bDownDir )  htiCur = GetRootItem();
    			else htiCur = GetLastItem( NULL );
    		}
    	}
    	return NULL;
    }
    
    
    // IsFindValid	- Virtual function used by FindItem to allow this
    //		  function to filter the result of FindItem
    // Returns	- True if item matches the criteria
    // Arg		- Handle of the item
    BOOL CTreeCtrlX::IsFindValid( HTREEITEM )
    {
    	return TRUE;
    }
    In the class declaration add the following.
     
    public:
    	virtual HTREEITEM FindItem(CString &sSearch, 
    				BOOL bCaseSensitive = FALSE, 
    				BOOL bDownDir = TRUE, 
    				BOOL bWholeWord = FALSE, 
    				HTREEITEM hItem = NULL);
    protected:
    	virtual BOOL IsFindValid( HTREEITEM );
    


    IT Offers