'checks for changed disks or flashdrives
Sub UpdateTrees
	Dim As HTREEITEM Parent1, Parent0, Parent0a, Parent1a, Dummy
	Dim As Integer L, L2
	Dim As String FirstHD, Build, VName
	'
	If MyDrives.ScanChange Then
		'Drive (USB or network) added/removed or disk inserted/removed
		If Len(MyDrives.NewDisk) Then
			'Print "Disk changed: ";MyDrives.NewDisk
			VName = MyDrives.DriveName(MyDrives.NewDisk) 'this may be null
			Build = MyDrives.NewDisk+":"+Path_Delim + " [" + VName + "]"
			'find drive
			Dummy = TreeView_GetRoot(DTop) 'first drive in tree
			While Dummy
				FirstHD = Left(TreeView_GetItemText(DTop, Dummy),3)
				If FirstHD = Left(Build,3) Then Exit While
				Dummy = TreeView_GetNextSibling(DTop, Dummy)
			Wend
			TV_NameIt(DTop,Parent0,Build)
			'delete all children
			Parent0 = Dummy
			Dummy = TreeView_GetChild(DTop,Parent0)
			While Dummy
				TreeView_DeleteItem(DTop,Dummy)
				Dummy = TreeView_GetChild(DTop,Parent0)
			Wend
			're-populate children
			Check4Children DTop,Parent0,TRUE
			L = TreeView_SortChildren(DTop,Parent0,0)
			'was drive is selected in tree
			If Left(Build,3) = Left(wtTop,3) Then
				wtTop = Left(Build,3)
				GetFileListTop
				SetWindowText(PDispTop,wtTop)
			EndIf
			'find drive
			Dummy = TreeView_GetRoot(DBottom) 'first drive in tree
			While Dummy
				FirstHD = Left(TreeView_GetItemText(DBottom, Dummy),3)
				If FirstHD = Left(Build,3) Then Exit While
				Dummy = TreeView_GetNextSibling(DBottom, Dummy)
			Wend
			TV_NameIt(DBottom,Parent0,Build)
			'delete all children
			Parent0 = Dummy
			Dummy = TreeView_GetChild(DBottom,Parent0)
			While Dummy
				TreeView_DeleteItem(DBottom,Dummy)
				Dummy = TreeView_GetChild(DBottom,Parent0)
			Wend
			're-populate children
			Check4Children DBottom,Parent0,TRUE
			L = TreeView_SortChildren(DBottom,Parent0,0)
			'was drive is selected in tree
			If Left(Build,3) = Left(wtBottom,3) Then
				wtBottom = Left(Build,3)
				GetFileListBottom
				SetWindowText(PDispBottom,wtBottom)
			EndIf
		Else
			'drive added or removed
			If Len(MyDrives.DrvRemove) Then
				'Print "Drive removed: ";MyDrives.DrvRemove
				Build = MyDrives.DrvRemove +":"+Path_Delim
				'find drive
				Parent0 = TreeView_GetRoot(DTop) 'first drive in tree
				Parent1 = TreeView_GetNextSibling(DTop, Parent0)
				FirstHD = Left(TreeView_GetItemText(DTop, Parent0),3)
				If FirstHD = Build Then
					'removed "First drive"?
					TreeView_SelectItem(DTop, Parent1)
					TreeView_DeleteItem(DTop, Parent0)
				Else
					While Parent1
						FirstHD = Left(TreeView_GetItemText(DTop, Parent1),3)
						If FirstHD = Build Then Exit While
						Parent0 = Parent1
						Parent1 = TreeView_GetNextSibling(DTop, Parent1)
					Wend
					TreeView_SelectItem(DTop, Parent0)
					TreeView_DeleteItem(DTop, Parent1)
				EndIf
				'find drive
				Parent0 = TreeView_GetRoot(DBottom) 'first drive in tree
				Parent1 = TreeView_GetNextSibling(DBottom, Parent0)
				FirstHD = Left(TreeView_GetItemText(DBottom, Parent0),3)
				If FirstHD = Build Then
					'removed "First drive"?
					TreeView_SelectItem(DBottom, Parent1)
					TreeView_DeleteItem(DBottom, Parent0)
				Else
					While Parent1
						FirstHD = Left(TreeView_GetItemText(DBottom, Parent1),3)
						If FirstHD = Build Then Exit While
						Parent0 = Parent1
						Parent1 = TreeView_GetNextSibling(DBottom, Parent1)
					Wend
					TreeView_SelectItem(DBottom, Parent0)
					TreeView_DeleteItem(DBottom, Parent1)
				EndIf
			Else
				'If Len(MyDrives.NewDisk) = 0 Then Print "New listing of drive letters: ";MyDrives.DriveList
				'If Len(MyDrives.DrvAdd) Then Print "Drive added: ";MyDrives.DrvAdd
				VName = MyDrives.DriveName(MyDrives.DrvAdd) 'this may be null
				Build = MyDrives.DrvAdd+":"+Path_Delim + " [" + VName + "]"
				'L can never be 1
				'Drives A and B are pre allocated, and Drive C is always the main fixed drive. So any "new" drives will follow C
				L = InStr(MyDrives.DriveList,MyDrives.DrvAdd)
				'
				Parent1 = TreeView_GetRoot(DTop) 'if L = 2 then insert after this
				If L > 2 Then
					For L2 = 3 To L
						Parent1 = TreeView_GetNextSibling(DTop, Parent1)
					Next
				EndIf
				'Parent0 = PutTree(Build,TVI_ROOT,0)
				Parent0 = TV_InsertHere(DTop, TVI_ROOT, Parent1, Build)
				Check4Children DTop,Parent0,TRUE
				'
				Parent1 = TreeView_GetRoot(DBottom) 'if L = 2 then insert after this
				If L > 2 Then
					For L2 = 3 To L
						Parent1 = TreeView_GetNextSibling(DBottom, Parent1)
					Next
				EndIf
				'Parent0 = PutTree(Build,TVI_ROOT,1)
				Parent0 = TV_InsertHere(DBottom, TVI_ROOT, Parent1, Build)
				Check4Children DBottom,Parent0,TRUE
			EndIf
		EndIf
	Else
		'first run
		Path_Delim = "\"
		MyRecycle = ExePath + Path_Delim + "Trash" 'note no end delim!!
		FTPTemp = ExePath + Path_Delim + "FTPHold" 'note no end delim!!
		TempExtractPath = ExePath + Path_Delim + "TempView" + Path_Delim
		For L = 1 To Len(MyDrives.DriveList)
			Build = Mid(MyDrives.DriveList,L,1)+":"+Path_Delim
			L2 = MyDrives.GetDrvType(Build)
			If L2 = DRIVE_FIXED And FirstHD = "" Then
				FirstHD = Build
				strShare = FirstHD
			EndIf
			VName = MyDrives.DriveName(Build)
			Build += " ["+VName+"]"
			'
			Parent0 = PutTree(Build,TVI_ROOT,0)
			Check4Children DTop,Parent0,TRUE
			L2 = TreeView_SortChildren(DTop,Parent0,0)
			Parent1 = PutTree(Build,TVI_ROOT,1)
			Check4Children DBottom,Parent1,TRUE
			L2 = TreeView_SortChildren(DBottom,Parent1,0)
		Next
	EndIf
End Sub

Function PutTree(T As String,Where As HTREEITEM,WhichSide As Integer) As HTREEITEM
	Dim tvis As TVINSERTSTRUCT
	tvis.item.Mask = TVIF_TEXT' or TVIF_IMAGE or TVIF_SELECTEDIMAGE
	tvis.item.pszText         	= StrPtr(T)
	tvis.item.cchTextMax      	= Len(T)
	'tvis.item.iImage         	= 0
	'tvis.item.iSelectedImage 	= 1
	tvis.hInsertAfter        	= 0
	tvis.hParent             	= Where
	If WhichSide = 1 Then
		Function = TreeView_InsertItem( DBottom, @tvis )
	Else
		Function = TreeView_InsertItem( DTop, @tvis )
	EndIf
End Function

Function ResolveTree(TheTree As HWND, Sel As HTREEITEM) As String
	'returns full path
	Dim As String P,Q
	While Sel
		'get the text
		Q = TreeView_GetItemText(TheTree, Sel)
		If InStr(Q,Path_Delim) Then
			'at root
			P = Left(Q,3) + P 'remove volume name
		Else
			P = Q + Path_Delim + P
		EndIf
		'next?
		Sel = TreeView_GetParent(TheTree, Sel)
	Wend
	Return P
End Function

'should be named Check4GrandChilren
Sub Check4Children(TheTree As HWND, Sel As HTREEITEM, AddDrive As BOOL)
	Dim As String F, ThePath
	Dim As Integer RAtt
	Dim As HTREEITEM Dummy
	Dim As TV_ITEM item
	'
	If AddDrive Then
		'called from UpdateTrees
		Dim As BOOL NoFolders = TRUE
		ThePath = ResolveTree(TheTree,Sel)
		F = Dir(ThePath+"*.*",55,@RAtt)
		'Print "AddDrive: ";ThePath
		While F <> ""
			'ignore "system" folders..........................................................................ALLOW ZIP FILE..........ALLOW FOLDER ATTRIB
			If F <> "." And F <> ".." And Left(F,4) <> "$REC" And F <> "System Volume Information" And (UCase(Right(F,4)) = ".ZIP" Or (RAtt And 16) = 16) Then
				If TheTree = DTop Then
					Dummy = PutTree(F,Sel,0)
				Else
					Dummy = PutTree(F,Sel,1)
				EndIf
				NoFolders = FALSE
				'Zip file on root of drive
				'If UCase(Right(F,4)) = ".ZIP" Then ZipInTree TheTree, Dummy, ThePath + F
			EndIf
			F = Dir(@RAtt)
		Wend
		'Print "AddDrive Exit"
		If NoFolders Then Exit Sub
	EndIf
	'check for grandchildren
	'Has children! Either by expanding or prior if/then
	Sel = TreeView_GetChild(TheTree, Sel)
	While Sel
		'did we already expand/collapse?
		item.hItem = Sel
		item.mask = TVIF_CHILDREN
		TreeView_GetItem(TheTree, @item)
		If item.cChildren = 0 Then
			'did not do it already or no folders
			ThePath = ResolveTree(TheTree,Sel)
			If InStr(UCase(ThePath),".ZIP"+Path_Delim) Then
				ZipInTree TheTree, Sel, ThePath
			Else
				F = Dir(ThePath+"*.*",55,@RAtt)
				While F <> ""
					'System Recycle bin and SVI folders are only on root
					'ignore "system" folders............MyRecycle bin.............ALLOW ZIP FILE............ALLOW FOLDER ATTRIB
					If F <> "." And F <> ".." And ThePath+F <> MyRecycle And (UCase(Right(F,4)) = ".ZIP" Or (RAtt And 16) = 16) Then
						If TheTree = DTop Then
							Dummy = PutTree(F,Sel,0)
						Else
							Dummy = PutTree(F,Sel,1)
						EndIf
					EndIf
					F = Dir(@RAtt)
				Wend
				RAtt = TreeView_SortChildren(TheTree, Sel,0)
			EndIf
		EndIf
		Sel = TreeView_GetNextSibling(TheTree, Sel)
	Wend
End Sub

Sub TV_NameIt(Tree As HWND,Where As HTREEITEM,T As String)
	Dim tvi As TV_ITEM
	'
	tvi.mask  = TVIF_TEXT
	tvi.pszText = StrPtr(T)
	tvi.cchTextMax = Len(T)
	tvi.hItem = Where
	SendMessage(Tree,TVM_SETITEM,0,@tvi)
End Sub

Sub FindPathInTree(TV As HWND)
	Dim As String NewPath,V,Build,ThisFolder
	Dim As HTREEITEM hti
	Dim As Integer l,r 'pointers to slashes
	'
	If TV = DTop Then
		NewPath = wtTop
	Else
		NewPath = wtBottom
	EndIf
	'
	hti = TreeView_GetRoot(TV) 'first drive in tree
	Do
		V = TreeView_GetItemText(TV, hti)
		'remove volName
		If Left(V,3) = Left(NewPath,3) Then
			'on right drive
			Exit Do
		EndIf
		hti = TreeView_GetNextSibling(TV, hti)
	Loop
	Build = Left(V,3)
	'already have gchildren
	While Build <> NewPath
		'check children
		hti = TreeView_GetChild(TV, hti)
		'find what folder we are looking for
		l = Len(Build)+1
		r = InStr(l,NewPath,Path_Delim)
		ThisFolder = Mid(NewPath,l,r-l)
		Do
			V = TreeView_GetItemText(TV, hti)
			If V = ThisFolder Then
				'correct folder
				Check4Children TV, hti, FALSE 'not sure how deep we are
				Exit Do
			EndIf
			hti = TreeView_GetNextSibling(TV, hti)
		Loop
		Build += V + Path_Delim
	Wend
	TreeView_SelectItem(TV, hti)
End Sub

Function FolderExistInTree(Tv As HWND,Check As String) As HTREEITEM
	Dim As HTREEITEM CurrLook
	Dim As Integer l,r
	Dim As String T,Bld
	'
	CurrLook = TreeView_GetRoot(Tv)
	Do
		T = TreeView_GetItemText(Tv, CurrLook)
		'remove volName
		If Left(T,3) = Left(Check,3) Then
			'on right drive
			Exit Do
		EndIf
		CurrLook = TreeView_GetNextSibling(Tv, CurrLook)
	Loop
	Bld = Left(T,3)
	'
	While (Bld <> Check) And (CurrLook <> 0)
		CurrLook = TreeView_GetChild(Tv,CurrLook)
		While CurrLook
			T = TreeView_GetItemText(Tv,CurrLook)
			If Bld+T+Path_Delim = Left(Check,Len(Bld+T+Path_Delim)) Then
				Exit While
			EndIf
			CurrLook = TreeView_GetNextSibling(Tv, CurrLook)
		Wend
		If CurrLook Then
			Bld += T+Path_Delim
		EndIf
	Wend
	Return CurrLook
End Function

'not available in 0.20.0
Function TreeView_GetItemText(TV As HWND, Item As HTREEITEM) As String
	Dim As TV_ITEM tvi
	Dim As String r
	tvi.mask = TVIF_TEXT
	tvi.hItem = Item
	tvi.cchTextMax = 250
	tvi.pszText = Callocate(tvi.cchTextMax + 1)
	TreeView_GetItem(TV, @tvi)
	r = *tvi.pszText
	DeAllocate( tvi.pszText )
	Return r
End Function

'Check4Childern "discovers" a zip file
Sub ZipInTree(TheTree As HWND, Sel As HTREEITEM, ZFile As String)
	Dim As Integer Num, x, y
	Dim As String LookF, Entry, FList(50)
	Dim As Integer LookFLevel,EntryFLevel
	Dim As HTREEITEM Dummy
	'
	'DebugFile "Temp", __FUNCTION__
	x = InStr(UCase(ZFile),".ZIP"+Path_Delim)+3
	'DebugFile "Temp", Left(ZFile,x)
	Entry = Mid(ZFile,x+2)
	LookF = str_ReplaceAnyAll(Path_Delim,"/",Entry)
	'DebugFile "Temp", "subfolder: "+LookF
	If InStr(LookF,"/") = 0 Then LookF = ""
	LookFLevel = str_numparse(LookF,"/")
	'
	Dim As zip Ptr ZPtr = zip_open(Left(ZFile,x), ZIP_CHECKCONS, NULL)
	If ZPtr <> NULL Then
		Num = zip_get_num_files(ZPtr) 'deprecated
		For x = 0 To Num - 1
			Entry = *zip_get_name(ZPtr, x, 0)
			'some zip files have IMPLIED folder entries!
			'
			'try this for each entry
			EntryFLevel = str_numparse(Entry,"/")
			If EntryFLevel > LookFLevel And (LookFLevel=1 Or (Left(Entry,Len(LookF)) = LookF And Len(LookF) > 0)) Then
				Entry = str_parse(Entry,"/",LookFLevel)
				y = 0
				Do
					If FList(y) = "" Then
						'add to list and tree
						FList(y) = Entry
						Dummy = TV_InsertHere(TheTree,Sel,0,Entry)
					EndIf
					If FList(y) = Entry Then Exit Do 'already or just added
					y += 1
				Loop
			EndIf
		Next
		zip_close(ZPtr)
		ZPtr = NULL
		x = TreeView_SortChildren(TheTree, Sel,0)
	Else
		MessageBox(NULL,Left(ZFile,x),"Could not read",MB_OK)
	EndIf
End Sub

'remove the item specified of the current selected TreeItem, deletion of folder or zip file
Sub RemoveChild(TheTree As HWND, TVSel As HTREEITEM, RemoveItem As String)
	'TVSel = TreeView_GetSelection(TheTree)
	'the "child" may not exist in "other" tree
	TVSel = TreeView_GetChild(TheTree,TVSel)
	While TreeView_GetItemText(TheTree, TVSel) <> RemoveItem And TVSel <> NULL
		TVSel = TreeView_GetNextSibling(TheTree,TVSel)
	Wend
	'this macro, thankfully, removes any children of this item
	If TVSel Then TreeView_DeleteItem(TheTree,TVSel)
End Sub

Function TV_InsertHere(TheTree As HWND, Parent As HTREEITEM, AfterChild As HTREEITEM, AddThis As String) As HTREEITEM
	Dim tvis As TVINSERTSTRUCT
	tvis.item.Mask = TVIF_TEXT' or TVIF_IMAGE or TVIF_SELECTEDIMAGE
	tvis.item.pszText         	= StrPtr(AddThis)
	tvis.item.cchTextMax      	= Len(AddThis)
	'tvis.item.iImage         	= 0
	'tvis.item.iSelectedImage 	= 1
	'
	'hInsertAfter
	'Handle to the item after which the new item is to be inserted or one of the following values:
	'Value	Meaning
	'TVI_FIRST	Inserts the item at the beginning of the list.
	'TVI_LAST	Inserts the item at the end of the list.
	'TVI_SORT	Inserts the item into the list in alphabetical order.
	tvis.hInsertAfter        	= AfterChild
	'hParent
	'Handle to the parent item. If this member is the TVI_ROOT value or NULL, the item is inserted at the root of the tree-view control. 
	tvis.hParent             	= Parent
	Function = TreeView_InsertItem( TheTree, @tvis )
End Function
