The non-recursive algorithm I posted yesterday for listing subdirectories can also be used to walk through a TreeView in just about 20 lines of code - pretty short as compared to most examples I've seen on the forum.
Here's the basic algorithm. The four basic arrays used are Items(), ItemsP(), ItemsS() and ItemsL() - handles, position, descriptions and levels of the nodes in the TreeView control.
With TreeView structures, which in my experience are relative small (a few hundreds of items), this algorithm work very fast. You may recall from the earlier posting on the algorithm that reading very large subdirectory structures (10K items) doesn't give an "instant" response. Also, since TreeView structures are in memory, the speed is especially enhanced over reading subdirectories from a disk drive. In my test, it scanned over 5K items as quickly as I could press the button - no noticeable delay.
Another good thing about using the algorithm with a TreeView is that the maximum number of items is known, answering the question of how large to make the arrays that contain the results.
And here's a complete example app using the algorithm. A short TreeView is created, the tree scanned, and then each node highlighted sequentially just to show that it works. An array with the node handles and an array with a text description of each node are the basic output.
This example is set up to handle a 5-level Tree and 1000 children per item. Just extend the "00000..." string by groups of 3 zero's to support more levels.
Here's the basic algorithm. The four basic arrays used are Items(), ItemsP(), ItemsS() and ItemsL() - handles, position, descriptions and levels of the nodes in the TreeView control.
Code:
Sub SearchTreeView(hTmp As Dword, ItemsCount As Long) Dim iPOS As Long, iLevel As Long, iOrder As Long ItemsL(ItemsCount) = iLevel : Items(ItemsCount) = hTmp '1st item (starting point) Treeview Get Text hDlg, 100, hTmp To ItemsS(ItemsCount) ItemsP(ItemsCount) = "000000000000" 'use "000" for each level (1000 items max per level) ItemsS(ItemsCount) = ItemsP(ItemsCount) + Str$(ItemsL(ItemsCount)) + " " + ItemsS(ItemsCount) 'cycles through all items, put various info in arrays While Items(iPOS) iOrder = 0 Treeview Get Child hDlg, 100, Items(iPOS) To hTmp If hTmp Then iLevel = ItemsL(iPOS) + 1 While hTmp Incr iOrder : Incr ItemsCount Items(ItemsCount) = hTmp ItemsL(ItemsCount) = iLevel ItemsP(ItemsCount) = ItemsP(iPOS) Mid$(ItemsP(ItemsCount),(iLevel-1)*3+1,3) = Format$(iOrder,"000") Treeview Get Text hDlg, 100, hTMP To ItemsS(ItemsCount) ItemsS(ItemsCount) = ItemsP(ItemsCount) + Str$(ItemsL(ItemsCount)) + " " + ItemsS(ItemsCount) Treeview Get Next hDlg, 100, hTmp To hTmp Wend Incr iPOS Wend 'sort the ItemsS array (tag Items along with it) ReDim Preserve ItemsS(ItemsCount), Items(ItemsCount) Array Sort ItemsS(), TagArray Items() End Sub
Another good thing about using the algorithm with a TreeView is that the maximum number of items is known, answering the question of how large to make the arrays that contain the results.
And here's a complete example app using the algorithm. A short TreeView is created, the tree scanned, and then each node highlighted sequentially just to show that it works. An array with the node handles and an array with a text description of each node are the basic output.
Code:
#Compile Exe #Resource "pb-test.pbr" Global hDlg As Dword, hLst As Dword, hRoot As Dword, hItem As Dword, hTmp As Dword Global Items() As Dword, ItemsS() As String, ItemsP() As String, ItemsL() As Long Function PBMain() As Long Dialog New Pixels, 0, "TreeView Test",300,100,330,230, _ %WS_OverlappedWindow, 0 To hDlg 'create control Control Add Treeview, hDlg, 100, "", 10,40,150,175 Control Add Button, hDlg, 101,"Start Search", 10,10,100,20 Control Add Label, hDlg, 150,"<count>", 120,10,100,20, %WS_Border Or %SS_Center 'create imagelist w,h,depth,size ImageList New Icon 16,16,32,3 To hLst ImageList Add Icon hLst, "x" ImageList Add Icon hLst, "y" ImageList Add Icon hLst, "z" ImageList Add Icon hLst, "check" 'attach imagelist Treeview Set ImageList hdlg, 100, hLst 'add items hdlg,id&,hPrnt,hIAftr,image&,selimage&,txt$ To hItem Treeview Insert Item hDlg,100,0,%TVI_Last,0,0,"Home" To hRoot Treeview Insert Item hDlg,100,hRoot,%TVI_Last,1,1,"One" To hTmp Treeview Insert Item hDlg,100,hTmp,%TVI_Last,1,1,"One-1" To hItem Treeview Insert Item hDlg,100,hTmp,%TVI_Last,2,2,"One-2" To hItem Treeview Insert Item hDlg,100,hRoot,%TVI_Last,2,2,"Two" To hTmp Treeview Insert Item hDlg,100,hTmp,%TVI_Last,1,1,"Two-1" To hItem Treeview Insert Item hDlg,100,hTmp,%TVI_Last,2,2,"Two-2" To hItem Treeview Insert Item hDlg,100,hRoot,%TVI_Last,3,3,"Three" To hTmp Treeview Insert Item hDlg,100,hTmp,%TVI_Last,1,1,"Three-1" To hItem Treeview Insert Item hDlg,100,hTmp,%TVI_Last,2,2,"Three-2" To hItem Dialog Show Modal hDlg Call DlgProc End Function CallBack Function DlgProc() As Long If Cb.Msg = %WM_Command And Cb.Ctl = 101 And Cb.CtlMsg = %BN_Clicked Then 'initialize variables and dimension arrays Dim iCount As Long, hSelected As Dword, ItemsCount As Long Treeview Get Count hDlg, 100 To iCount 'max items is no more than entire tree ReDim Items(iCount), ItemsS(iCount), ItemsP(iCount), ItemsL(iCount) 'Items-handles, ItemsS-sort string, ItemP-position string, ItemsL-level 'get the Tree data Treeview Get Select hDlg, 100 To hSelected SearchTreeView(hSelected, ItemsCount) 'Remove empty elements, sort and display the array ItemsS() Control Add ListBox, hDlg, 200,ItemsS(), 170,40,150,175 Control Set Text hDlg, 150, Str$(ItemsCount+1) Dialog ReDraw hDlg 'walk through tree from starting point, highlighting each item For iCount = 0 To UBound(Items) Treeview Select hDlg, 100, Items(iCount) Sleep 400 Next i End If End Function Sub SearchTreeView(hTmp As Dword, ItemsCount As Long) Dim iPOS As Long, iLevel As Long, iOrder As Long ItemsL(ItemsCount) = iLevel : Items(ItemsCount) = hTmp '1st item (starting point) Treeview Get Text hDlg, 100, hTmp To ItemsS(ItemsCount) ItemsP(ItemsCount) = "000000000000000" 'use "000" for each level (1000 items max per level) ItemsS(ItemsCount) = ItemsP(ItemsCount) + Str$(ItemsL(ItemsCount)) + " " + ItemsS(ItemsCount) 'cycles through all items, put various info in arrays While Items(iPOS) iOrder = 0 Treeview Get Child hDlg, 100, Items(iPOS) To hTmp If hTmp Then iLevel = ItemsL(iPOS) + 1 While hTmp Incr iOrder : Incr ItemsCount Items(ItemsCount) = hTmp ItemsL(ItemsCount) = iLevel ItemsP(ItemsCount) = ItemsP(iPOS) Mid$(ItemsP(ItemsCount),(iLevel-1)*3+1,3) = Format$(iOrder,"000") Treeview Get Text hDlg, 100, hTMP To ItemsS(ItemsCount) ItemsS(ItemsCount) = ItemsP(ItemsCount) + Str$(ItemsL(ItemsCount)) + " " + ItemsS(ItemsCount) Treeview Get Next hDlg, 100, hTmp To hTmp Wend Incr iPOS Wend 'sort the ItemsS array (tag Items along with it) ReDim Preserve ItemsS(ItemsCount), Items(ItemsCount) Array Sort ItemsS(), TagArray Items() End Sub
Comment