' CYA ALERT
' I AM NOT RESPONSABLE FOR ANY LOST FILES OR ANY DAMAGE TO COMPUTER

#Include "windows.bi"
#Include "vbcompat.bi"
#Include Once "win/shellapi.bi"
#Include Once "win/commctrl.bi"
#Include "PleaseWait.bi"

'temp add for debug
Sub DebugFile(FName As String, Note As String)
	Dim As Integer DFile, FileCnt,KB
	Dim As Double LastLog
	Dim As String CheckIt, NextCheck
	'
	KB = 30 'this can be changed any time
	'check size of file, if getting large, make new file (infinite loop or A LOT of errors ????)
	'skip over older files!!!
	Do
		FileCnt += 1
		If FileCnt > 1 Then
			CheckIt = NextCheck
		Else
			CheckIt = ExePath + "\" + FName + ".txt"
		EndIf
		'append # to name
		NextCheck = ExePath + "\" + FName + "-" + Str(FileCnt+1)+ ".txt"
		If FileExists(NextCheck)=0 Then
			'check size of last used file
			If FileLen(CheckIt) > KB * 1024 Then CheckIt = NextCheck
			Exit Do
		EndIf
	Loop
	LastLog = 0
	If FileExists(CheckIt) Then
		LastLog = FileDateTime(CheckIt)
	EndIf
	DFile = FreeFile
	Open CheckIt For Append As #DFile
	If Int(Now) > Int(LastLog) Then
		'new date
		If Lof(DFile) Then Print #DFile, "" 'blank line -- will not add if a "new" file
		Print #DFile, String(10,"-");" ";
		Print #DFile, Format(Now,"mmmm d, yyyy");
		Print #DFile, " ";String(10,"-")
	EndIf
	Print #DFile, "At ";
	Print #DFile, Format(Now,"h:mm:ssam/pm");
	Print #DFile, " ";Note
	Close #DFile
End Sub

'LVInit
Dim iccx As InitCommonControlsEx
iccx.dwSize = Len( InitCommonControlsEx )
iccx.dwICC  = ICC_TREEVIEW_CLASSES Or ICC_WIN95_CLASSES Or ICC_LISTVIEW_CLASSES' Or ICC_BAR_CLASSES
InitCommonControlsEx( @iccx )

Const PrgName = "Double Directory Explorer v1.4c" 'used for FTP login

Declare Function CompareListViewsDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Declare Function FileDupDlgP(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Declare Function ConfDelDlg(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Declare Function MainDlgP(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Declare Function TrashDlgP(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Declare Function FTPDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Declare Function PropDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Declare Function Prop1DirDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
Declare Function PropMixDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
'other subs call dlg windows
#Include "DDir.bi"

'get time zone offset in seconds
TZ = GetTimeZone()
icons = ImageList_Create(32, 32, ILC_COLOR32 Or ILC_MASK, 0, 0)
smicons = ImageList_Create(16, 16, ILC_COLOR32 Or ILC_MASK, 0, 0)
hInstance=GetModuleHandle(NULL)
DialogBoxParam(hInstance, Cast(ZString Ptr,IDD_MainDlg), NULL, @MainDlgP, NULL)
ImageList_Destroy(icons)
ImageList_Destroy(smicons)
ExitProcess(0)
End

Function MainDlgP(ByVal hWin As HWND,ByVal uMsg As UINT,ByVal wParam As WPARAM,ByVal lParam As LPARAM) As Integer
	Dim As Long id, Event, x, y
	Dim As String GenStr
	Dim As HTREEITEM hti
	Static As BOOL SaveOnExit 'flag to save current folders on exit
	Static As BOOL KeepFTPLog 'keep each FTP session log
	Static As String PreFTPPath 'wtBottom before connection
	Static As EditLVItem RenameMe 'data for editing item in listview
	Static As RECT Top_xy, Bot_xy 'size of listviews -- re/set in WM_SIZE
	Static As Integer ZipOpen
	'
	Dim As HMENU hMainMenu,hTopPop,hBotPop
	Dim As RECT rc
	'
	Select Case uMsg
		Case WM_INITDIALOG
			SetWindowText(hWin,PrgName)
			'set up Listviews
			FTop(0) = GetDlgItem(hWin,IDC_LSVTop)
			LVSetMaxCols FTop(0),5
			LVSetHeader FTop(0),1,"Name",320
			LVSetHeader FTop(0),2,"Type",90 'extension
			LVSetHeader FTop(0),3,"Date",150
			LVSetHeader FTop(0),4,"Size",80
			LVSetHeader FTop(0),5,"Attrib",50
			'full row select
			SendMessage(FTop(0),LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_FULLROWSELECT)
			'hidden
			FTop(1) = GetDlgItem(hWin,IDC_LSVTopLgIcon)
			FTop(2) = GetDlgItem(hWin,IDC_LSVTopSmIcon)
			FTop(3) = GetDlgItem(hWin,IDC_LSVTopZip)
			LVSetMaxCols FTop(3),7
			LVSetHeader FTop(3),1,"Name",320
			LVSetHeader FTop(3),2,"Type",90 'extension
			LVSetHeader FTop(3),3,"Password",50
			LVSetHeader FTop(3),4,"Size",80
			LVSetHeader FTop(3),5,"Ratio",50
			LVSetHeader FTop(3),6,"Comp Size",80
			LVSetHeader FTop(3),7,"Date",150
			'full row select
			SendMessage(FTop(3),LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_FULLROWSELECT)
			ShowWindow(FTop(1),SW_HIDE)
			ShowWindow(FTop(2),SW_HIDE)
			ShowWindow(FTop(3),SW_HIDE)
			'
			'set up bottom
			FBottom(0) = GetDlgItem(hWin,IDC_LSVBottom)
			LVSetMaxCols FBottom(0),5
			LVSetHeader FBottom(0),1,"Name",320
			LVSetHeader FBottom(0),2,"Type",90 'extension
			LVSetHeader FBottom(0),3,"Date",150
			LVSetHeader FBottom(0),4,"Size",80
			LVSetHeader FBottom(0),5,"Attrib",50
			SendMessage(FBottom(0),LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_FULLROWSELECT)
			'hidden
			FBottom(1) = GetDlgItem(hWin,IDC_LSVBotLgIcon)
			FBottom(2) = GetDlgItem(hWin,IDC_LSVBotSmIcon)
			FBottom(3) = GetDlgItem(hWin,IDC_LSVBotZip)
			LVSetMaxCols FBottom(3),7
			LVSetHeader FBottom(3),1,"Name",320
			LVSetHeader FBottom(3),2,"Type",90 'extension
			LVSetHeader FBottom(3),3,"Password",50
			LVSetHeader FBottom(3),4,"Size",80
			LVSetHeader FBottom(3),5,"Ratio",50
			LVSetHeader FBottom(3),6,"Comp Size",80
			LVSetHeader FBottom(3),7,"Date",150
			'full row select
			SendMessage(FBottom(3),LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_FULLROWSELECT)
			ShowWindow(FBottom(1),SW_HIDE)
			ShowWindow(FBottom(2),SW_HIDE)
			ShowWindow(FBottom(3),SW_HIDE)
			'
			'fill in treeviews
			DTop = GetDlgItem(hWin,IDC_TRVTop)
			DBottom = GetDlgItem(hWin,IDC_TRVBottom)
			UpdateTrees
			'init icons for Listviews
			x = SetIcon("INIT","ME",FALSE) 'save and load icons for later use?????
			'settings
			If FileExists("DDir.ini") Then
				'open ini file
				x = FreeFile
				Open "DDir.ini" For Input As #x
				Input #x, wtTop
				Input #x, wtBottom
				Input #x, SaveOnExit
				If EOF(x) = 0 Then
					Input #x, KeepDirTop 'added v1.1
					Input #x, GroupDir 'added v1.1
					If EOF(x) = 0 Then
						Input #x, KeepFTPLog 'added v1.2
						Close #x
					Else
						Close #x
						SaveIni FALSE,FALSE
					EndIf
				Else
					Close #x
					KeepDirTop = TRUE
					GroupDir = TRUE
					KeepFTPLog = FALSE
					SaveIni SaveOnExit,KeepFTPLog
				EndIf
				'make sure paths exists
				If Len(Dir(wtTop+"*")) = 0 Then
					wtTop = strShare
					MessageBox(hWin,"Defaulted to first available drive."+Chr(13)+"Change your settings.","Top path setting no longer exists.",MB_ICONINFORMATION)
				EndIf
				If Len(Dir(wtBottom+"*")) = 0 Then
					wtBottom = strShare
					MessageBox(hWin,"Defaulted to first available drive."+Chr(13)+"Change your settings.","Bottom path setting no longer exists.",MB_ICONINFORMATION)
				EndIf
			Else
				'strShare assigned in UpdateTrees
				wtTop = strShare
				wtBottom = strShare
				SaveOnExit = FALSE
				KeepDirTop = TRUE
				GroupDir = TRUE
				KeepFTPLog = FALSE
				SaveIni SaveOnExit,KeepFTPLog
				GenStr = "Use at your own risk."+Chr(13)
				GenStr += "I am NOT responsable for any lost data or damage to your computer."
				MessageBox(hWin,GenStr,"CYA Alert!",MB_ICONINFORMATION)
			EndIf
			'set static for top
			PDispTop = GetDlgItem(hWin,IDC_STCTop)
			SetWindowText(PDispTop,wtTop)
			'set static for bottom
			PDispBottom = GetDlgItem(hWin,IDC_STCBottom)
			SetWindowText(PDispBottom,wtBottom)
			'
			'menu
			hMainMenu=GetMenu(hWin)
			InitPopUpMenu
			'define menu
			hTopPop = CreatePopupMenu()
			For x = 1 To UBound(NewFMenu)
				AppendMenu( hTopPop, MF_STRING, 12200 + x, NewFMenu(x).MenuDisp)
			Next
			ModifyMenu(hMainMenu,IDM_NewT,MF_POPUP,hTopPop,"New file Top")
			'define menu
			hBotPop = CreatePopupMenu()
			For x = 1 To UBound(NewFMenu)
				AppendMenu( hBotPop, MF_STRING, 12300 + x, NewFMenu(x).MenuDisp)
			Next
			ModifyMenu(hMainMenu,IDM_NewB,MF_POPUP,hBotPop,"New file Bottom")
			'
			'tick menu items if needed
			If SaveOnExit Then CheckMenuItem hMainMenu,IDM_SaveExit,MF_CHECKED
			If KeepDirTop Then CheckMenuItem hMainMenu,IDM_DirTop,MF_CHECKED
			If GroupDir Then CheckMenuItem hMainMenu,IDM_GrpF,MF_CHECKED
			If KeepFTPLog Then CheckMenuItem hMainMenu,IDM_KeepLog,MF_CHECKED
			'
			'my recycle bin
			PutTree("Trash",TVI_ROOT,0)
			PutTree("Trash",TVI_ROOT,1)
			RecycleStatus
			'ftp log area -- hidden at startup
			FTPStats = GetDlgItem(hWin,IDC_STCFTPLog)
			'
			'act like a change of path
			FindPathInTree DTop
			FindPathInTree DBottom
			'check for new/changed drive
			SetTimer(hWin,0,TimerDelay,0)
			'disable "move" menu items if only one zip file open
			SetTimer(hWin,1,1300,0)
			'
		Case WM_TIMER
			If wParam = 0 Then
				MyDrives.Scan
				If MyDrives.ScanChange Then UpdateTrees
				'if connected to FTP, keep alive!
				x = 7 'set idle minutes
				If Connected = TRUE And (ftp.LastFTP + 60 * x < Timer Or ftp.LastFTP > Timer) Then
					'no need to log "midnight"
					If ftp.LastFTP < Timer Then LogFTP "Session idle for more than "+Str(x)+" minutes."
					x = MAX_PATH
					Dim As ZString * MAX_PATH z
					'harmless???
					'use this function for updating status of bottom
					If FtpGetCurrentDirectory(ftp.hconn,@z,@x) = FALSE Then
						'lost connection?
						MessageBox(hWin,"Lost connection with server","",MB_OK)
						LogFTP "Lost connection with server"
						FTPClose KeepFTPLog
					Else
						ftp.LastFTP = Timer
					EndIf
				EndIf
			Else
				'disable "move" menu items if zip file open
				x = 0
				If TopZip.ZipPtr <> NULL Then x += 1
				If BottomZip.ZipPtr <> NULL Then x += 1
				If x < 2 And x <> ZipOpen Then
					'one or no zip open
					ZipOpen = x
					hMainMenu=GetMenu(hWin)
					If x = 1 Then
						'disable (ZipOpen=0 and x=1)
						EnableMenuItem hMainMenu, IDM_MTB, MF_GRAYED
						EnableMenuItem hMainMenu, IDM_MBT, MF_GRAYED
					Else
						'enable (ZipOpen=1 and x=0)
						EnableMenuItem hMainMenu, IDM_MTB, MF_ENABLED
						EnableMenuItem hMainMenu, IDM_MBT, MF_ENABLED
					EndIf
				EndIf
			EndIf
			'
		Case WM_CLOSE
			KillTimer(hWin,0)
			KillTimer(hWin,1)
			'Zip file open on exit?
			If TopZip.ZipPtr <> NULL Or BottomZip.ZipPtr <> NULL Then
				If TopZip.ZipPtr <> NULL Then zip_close(TopZip.ZipPtr)
				If BottomZip.ZipPtr <> NULL Then zip_close(BottomZip.ZipPtr)
				'delete temp file(s)
				ClearExtractFolder
				RmDir TempExtractPath
				Sleep 800
			EndIf
			If SaveOnExit Then
				SaveIni SaveOnExit,KeepFTPLog
			EndIf
			If Connected Then
				LogFTP "Closed program while still connected"
				FTPClose KeepFTPLog
			EndIf
			EndDialog(hWin, 0)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			Select Case id
				Case IDM_Exit
					SendMessage(hWin,WM_CLOSE,0,0)
					'
				Case IDM_CTB
					'copy top to bottom
					KillTimer(hWin,0)
					DoFileComm FTop(TopLVType),FBottom(BotLVType),"copied"
					SetTimer(hWin,0,TimerDelay,0)
					'
				Case IDM_CBT
					'copy bottom to top
					KillTimer(hWin,0)
					DoFileComm FBottom(BotLVType),FTop(TopLVType),"copied"
					SetTimer(hWin,0,TimerDelay,0)
					'
				Case IDM_MTB
					'move top to bottom
					'no moving to/from zip
					If TopZip.ZipPtr = NULL And BottomZip.ZipPtr = NULL Then
						KillTimer(hWin,0)
						DoFileComm FTop(TopLVType),FBottom(BotLVType),"moved"
						SetTimer(hWin,0,TimerDelay,0)
					EndIf
					'
				Case IDM_MBT
					'move bottom to top
					'no moving to/from zip
					If TopZip.ZipPtr = NULL And BottomZip.ZipPtr = NULL Then
						KillTimer(hWin,0)
						DoFileComm FBottom(BotLVType),FTop(TopLVType),"moved"
						SetTimer(hWin,0,TimerDelay,0)
					EndIf
					'
				Case IDM_DT
					'delete top
					'2nd param not used in these two
					KillTimer(hWin,0)
					DoFileComm FTop(TopLVType),FTop(TopLVType),"deleted"
					SetTimer(hWin,0,TimerDelay,0)
					'
				Case IDM_DB
					'delete bottom
					KillTimer(hWin,0)
					DoFileComm FBottom(BotLVType),FBottom(BotLVType),"deleted"
					SetTimer(hWin,0,TimerDelay,0)
					'
				Case IDM_TrashT
					'top to trash bin
					If TopZip.ZipPtr = NULL Then
						KillTimer(hWin,0)
						Recycle FTop(TopLVType)
						SetTimer(hWin,0,TimerDelay,0)
					EndIf
					'
				Case IDM_TrashB
					'bottom to trash bin
					'disabled on FTP connection
					'connection check ... just in case
					If Connected = 0 And BottomZip.ZipPtr = NULL Then
						KillTimer(hWin,0)
						Recycle FBottom(BotLVType)
						SetTimer(hWin,0,TimerDelay,0)
					EndIf
					'
				Case IDM_SAT
					'select all top
					SelAll FTop(TopLVType)
					'
				Case IDM_SAB
					'sel all bottom
					SelAll FBottom(BotLVType)
					'
				Case IDM_IST
					'inv sel top
					InvSel FTop(TopLVType)
					'
				Case IDM_ISB
					'inv sel bottom
					InvSel FBottom(BotLVType)
					'
				Case IDM_OpenT
					GenStr = wtTop 'check for change dir
					ViewOpenFile FTop(TopLVType)
					If GenStr <> wtTop Then
						'path change
						SetWindowText(PDispTop,wtTop)
						FindPathInTree DTop
					EndIf
					'
				Case IDM_OpenB
					'FBottom
					GenStr = wtBottom 'check for change dir
					ViewOpenFile FBottom(BotLVType)
					If GenStr <> wtBottom Then
						'path change
						SetWindowText(PDispBottom,wtBottom)
						FindPathInTree DBottom
					EndIf
					'
				Case IDM_SaveNow
					SaveOnExit = FALSE
					SaveIni SaveOnExit,KeepFTPLog
					hMainMenu=GetMenu(hWin)
					CheckMenuItem hMainMenu,IDM_SaveExit,MF_UNCHECKED
					'
				Case IDM_SaveExit
					hMainMenu=GetMenu(hWin)
					If SaveOnExit Then
						SaveOnExit = FALSE
						CheckMenuItem hMainMenu,IDM_SaveExit,MF_UNCHECKED
					Else
						SaveOnExit = TRUE
						CheckMenuItem hMainMenu,IDM_SaveExit,MF_CHECKED
					EndIf
					'
				Case IDM_DirTop
					hMainMenu=GetMenu(hWin)
					If KeepDirTop Then
						KeepDirTop = FALSE
						CheckMenuItem hMainMenu,IDM_DirTop,MF_UNCHECKED
					Else
						KeepDirTop = TRUE
						CheckMenuItem hMainMenu,IDM_DirTop,MF_CHECKED
						GroupDir = TRUE
						CheckMenuItem hMainMenu,IDM_GrpF,MF_CHECKED
					EndIf
					'
				Case IDM_GrpF
					hMainMenu=GetMenu(hWin)
					If GroupDir Then
						GroupDir = FALSE
						CheckMenuItem hMainMenu,IDM_GrpF,MF_UNCHECKED
						KeepDirTop = FALSE
						CheckMenuItem hMainMenu,IDM_DirTop,MF_UNCHECKED
					Else
						GroupDir = TRUE
						CheckMenuItem hMainMenu,IDM_GrpF,MF_CHECKED
					EndIf
					'
				Case IDM_FTPConnect
					hMainMenu=GetMenu(hWin)
					If Connected = FALSE Then
						'open connection dlg
						DialogBoxParam(hInstance, Cast(ZString Ptr,IDD_DLGFTP), NULL, @FTPDlgProc, NULL)
						If Connected Then
							PreFTPPath = wtBottom
							'make temp dir for file transfers
							MkDir(FTPTemp)
							'strShare = Host + "|" + LocalDir
							x = InStr(strShare,"|")
							GenStr = Left(strShare,x-1)
							SetWindowText(PDispBottom,GenStr) 'wtBottom
							wtBottom = GenStr
							LogFTP "Connected: "+GenStr
							GenStr = Mid(strShare,x+1) 'local dir wanted
							If GenStr <> wtTop Then
								wtTop = GenStr
								'path change
								SetWindowText(PDispTop,wtTop)
								FindPathInTree DTop
							EndIf
							EnableMenuItem hMainMenu,IDM_TrashB,MF_GRAYED 'disable Trash menu item for bottom
							ModifyMenu hMainMenu,IDM_FTPConnect,MF_STRING,IDM_FTPConnect,"Disconnect" 'change menu item label
							EnableWindow(DBottom,FALSE) 'disable treeview
							If UBound(NewFMenu) > 1 Then
								For x = 2 To UBound(NewFMenu)
									EnableMenuItem hMainMenu,12300+x,MF_GRAYED 'disable New files menu items for bottom
								Next
							EndIf
							ShowWindow(FTPStats,SW_SHOW) 'show ftp log area
							SendMessage(hWin,WM_SIZE,SIZE_RESTORED,0) 'it works....MAKELPARAM(cx,cy)
							Beep
							RefreshFTPFiles @ftp
						EndIf
					Else
						LogFTP "Disconnected"
						FTPClose KeepFTPLog
						Connected = FALSE
						EnableMenuItem hMainMenu,IDM_TrashB,MF_ENABLED
						ModifyMenu hMainMenu,IDM_FTPConnect,MF_STRING,IDM_FTPConnect,"Connect"
						If UBound(NewFMenu) > 1 Then
							For x = 2 To UBound(NewFMenu)
								EnableMenuItem hMainMenu,12300+x,MF_ENABLED 'enable New files menu items for bottom
							Next
						EndIf
						EnableWindow(DBottom,TRUE)
						wtBottom = PreFTPPath 'restore
						SetWindowText(PDispBottom,wtBottom)
						FindPathInTree DBottom
						ShowWindow(FTPStats,SW_HIDE)
						SendMessage(hWin,WM_SIZE,SIZE_RESTORED,0)
					EndIf
					'
				Case IDM_Compare
					DialogBoxParam(hInstance, Cast(ZString Ptr,IDD_DLGCompare), NULL, @CompareListViewsDlgProc, NULL)
					'
				Case IDM_KeepLog
					hMainMenu=GetMenu(hWin)
					If KeepFTPLog Then
						KeepFTPLog = FALSE
						CheckMenuItem hMainMenu,IDM_KeepLog,MF_UNCHECKED
					Else
						KeepFTPLog = TRUE
						CheckMenuItem hMainMenu,IDM_KeepLog,MF_CHECKED
					EndIf
					'
				Case IDM_ViewTopReport
					'start/default
					If TopLVType <> 0 And TopZip.ZipPtr = NULL Then
						ShowWindow(FTop(TopLVType),SW_HIDE)
						TopLVType = 0
						RefreshTopLV
						ShowWindow(FTop(0),SW_SHOW)
					EndIf
					'
				Case IDM_ViewTopLargeIcons
					If TopLVType <> 1 And TopZip.ZipPtr = NULL Then
						ShowWindow(FTop(TopLVType),SW_HIDE)
						TopLVType = 1
						RefreshTopLV
						ShowWindow(FTop(1),SW_SHOW)
					EndIf
					'
				Case IDM_ViewTopSmallIcons
					If TopLVType <> 2 And TopZip.ZipPtr = NULL Then
						ShowWindow(FTop(TopLVType),SW_HIDE)
						TopLVType = 2
						RefreshTopLV
						ShowWindow(FTop(2),SW_SHOW)
					EndIf
					'
				Case IDM_TopRevSort
					'only sort in report view
					If TopLVType = 0 Or TopLVType = 3 Then
						If LastSortAccendTop Then
							LastSortAccendTop = FALSE
						Else
							LastSortAccendTop = TRUE
						EndIf
						If TopLVType = 0 Then
							ListView_SortItems(FTop(0),@SortFuncTop,LastSortColTop)
						Else
							ListView_SortItems(FTop(3),@SortFuncTopZip,TopZip.SortCol)
						EndIf
					EndIf
					'
				Case IDM_ViewBotReport
					'start/default
					If BotLVType <> 0 And BottomZip.ZipPtr = NULL Then
						ShowWindow(FBottom(BotLVType),SW_HIDE)
						BotLVType = 0
						RefreshBottomLV
						ShowWindow(FBottom(0),SW_SHOW)
					EndIf
					'
				Case IDM_ViewBotLargeIcons
					If BotLVType <> 1 And BottomZip.ZipPtr = NULL Then
						ShowWindow(FBottom(BotLVType),SW_HIDE)
						BotLVType = 1
						RefreshBottomLV
						ShowWindow(FBottom(1),SW_SHOW)
					EndIf
					'
				Case IDM_ViewBotSmallIcons
					If BotLVType <> 2 And BottomZip.ZipPtr = NULL Then
						ShowWindow(FBottom(BotLVType),SW_HIDE)
						BotLVType = 2
						RefreshBottomLV
						ShowWindow(FBottom(2),SW_SHOW)
					EndIf
					'
				Case IDM_BottomRevSort
					'only sort in report view
					If BotLVType = 0 Or BotLVType = 3 Then
						If LastSortAccendBottom Then
							LastSortAccendBottom = FALSE
						Else
							LastSortAccendBottom = TRUE
						EndIf
						If BotLVType = 0 Then
							ListView_SortItems(FBottom(0),@SortFuncBottom,LastSortColBottom)
						Else
							ListView_SortItems(FBottom(3),@SortFuncBottomZip,BottomZip.SortCol)
						EndIf
					EndIf
					'
				Case 12201 To 12200+UBound(NewFMenu)
					'top pop up
					HandlePopUpMenu FTop(TopLVType),id-12200
					If strShare = "CF" Then
						x = ListView_GetNextItem(FTop(TopLVType), -1, LVNI_SELECTED)
						SendMessage(FTop(TopLVType),LVM_EDITLABEL ,x,0)
					EndIf
					'
				Case 12301 To 12300+UBound(NewFMenu)
					'top pop up
					HandlePopUpMenu FBottom(BotLVType),id-12300
					If strShare = "CF" Then
						x = ListView_GetNextItem(FBottom(BotLVType), -1, LVNI_SELECTED)
						SendMessage(FBottom(BotLVType),LVM_EDITLABEL ,x,0)
					EndIf
					'
			End Select
		Case WM_NOTIFY
			'' lParam of WM_NOTIFY contains a pointer to a NMHDR structure
			Dim As NMHDR Ptr nmhdr = Cast( NMHDR Ptr, lParam )
			'' wParam of WM_NOTIFY contains the identifier of the common control that sent the message
			'' it's better to use the hwndFrom from the NMHDR structure instead, because it's unique.
			'
			'' nmhdr->hwndFrom   - hWnd of the window/control that sent the message
			'' nmhdr->idFrom     - an identifier of the control that sent the message
			''                     (can use this or hwndFrom to identify the control, the
			''                     hWnd is always unique)
			'' nmhdr->code       - notification code
			'
			If nmhdr->hwndFrom = DTop Or nmhdr->hwndFrom = DBottom Then
				Select Case ( nmhdr->code )
					Case TVN_SELCHANGED
						'' selection changed
						'' for TVN_SELCHANGE, the lParam of WM_NOTIFY points to a larger structure
						'' (NMTREEVIEW) that contains NMHDR at the top.
						Dim As NMTREEVIEW Ptr nmtv = Cast( NMTREEVIEW Ptr, lParam )
						'' nmtv->itemOld     - itemOld/New are TVITEM structures
						'' nmtv->itemNew
						If (nmhdr->hwndFrom = DTop) Then
							hti = TreeView_GetSelection(DTop)
							GenStr = ResolveTree(DTop,hti)
							If Left(GenStr,5) = "Trash" Then
								'display contents of trash bin
								If Right(GenStr,4) <> "(0)"+Path_Delim Then
									strShare = GenStr
									CloseWindow(hWin)
									id = DialogBoxParam(hInstance, Cast(ZString Ptr,IDD_DLG_Recycle), NULL, @TrashDlgP, NULL)
									ShowWindow(hWin,SW_RESTORE)
									'may have restored files to these dir
									If TopZip.ZipPtr = NULL Then GetFileListTop
									If Connected = FALSE And BottomZip.ZipPtr = NULL Then GetFileListBottom
									RecycleStatus
								EndIf
								FindPathInTree DTop
							ElseIf InStr(UCase(GenStr),".ZIP"+Path_Delim) Then
								'Ignore if program changes the tree
								If strShare <> "FindZipInTree" Then
									'is it open in the bottom view?
									If BottomZip.ZipPtr = NULL Or (BottomZip.ZipPtr <> NULL And BottomZip.ZipFile <> Left(GenStr,Len(BottomZip.ZipFile))) Then OpenZipFile GenStr,TRUE
								EndIf
							Else
								If TopZip.ZipPtr <> NULL Then CloseZip TRUE
								wtTop = GenStr
								SetWindowText(PDispTop,wtTop)
								LastSortColTop = 0
								LastSortAccendTop = TRUE
								GetFileListTop
							EndIf
						Else
							'treeview disabled while connected
							hti = TreeView_GetSelection(DBottom)
							GenStr = ResolveTree(DBottom,hti)
							If Left(GenStr,5) = "Trash" Then
								'display contents of trash bin
								If Right(GenStr,4) <> "(0)"+Path_Delim Then
									strShare = GenStr
									CloseWindow(hWin)
									id = DialogBoxParam(hInstance, Cast(ZString Ptr,IDD_DLG_Recycle), NULL, @TrashDlgP, NULL)
									ShowWindow(hWin,SW_RESTORE)
									'may have restored files to these dir
									If TopZip.ZipPtr = NULL Then GetFileListTop
									If BottomZip.ZipPtr = NULL Then GetFileListBottom
									RecycleStatus
								EndIf
								FindPathInTree DBottom
							ElseIf InStr(UCase(GenStr),".ZIP"+Path_Delim) Then
								'Ignore if program changes the tree
								If strShare <> "FindZipInTree" Then
									'is it open in the top view?
									If TopZip.ZipPtr = NULL Or (TopZip.ZipPtr <> NULL And TopZip.ZipFile <> Left(GenStr,Len(TopZip.ZipFile))) Then OpenZipFile GenStr,FALSE
								EndIf
							Else
								If BottomZip.ZipPtr <> NULL Then CloseZip FALSE
								wtBottom = GenStr
								SetWindowText(PDispBottom,wtBottom)
								LastSortColBottom = 0
								LastSortAccendBottom = TRUE
								GetFileListBottom
							EndIf
						EndIf
						Return 0
						'
					Case TVN_ITEMEXPANDING
						Dim As NMTREEVIEW Ptr nmtv = Cast( NMTREEVIEW Ptr, lParam )
						'User change?
						'this is the only one that I care about
						If nmtv->action = TVE_EXPAND Then
							'The itemNew member is a TV_ITEM structure that contains valid information
							'about the parent item in the hItem
							'check for childen of children
							Check4Children(nmhdr->hwndFrom,nmtv->itemNew.hItem,FALSE)
						EndIf
						Return TRUE 'false if I handle the expand?
					Case Else
						Return TRUE
				End Select
			EndIf
			If nmhdr->hwndFrom = FTop(TopLVType) Or nmhdr->hwndFrom = FBottom(BotLVType) Then
				Dim As NMLISTVIEW Ptr nmlv = Cast(NMLISTVIEW Ptr, lParam)
				'nmlv->uNewState/uOldState/uChanged to check for selected?
				Select Case nmhdr->code
					'general messages
					'Case NM_RETURN
					'	'Print "enter key pressed"
					'	Beep
					Case NM_RCLICK
						'Print "Right click"
						x = nmlv->ptAction.x
						y = nmlv->ptAction.y
						GetWindowRect( nmhdr->hwndFrom, @rc )
						'pop up
						If nmhdr->hwndFrom = FTop(3) Or nmhdr->hwndFrom = FBottom(3) Then
							'right click in zip file
							RClick_Zip hWin, nmhdr->hwndFrom, rc.left+x, rc.top+y
						Else
							RClick hWin, nmhdr->hwndFrom, rc.left+x, rc.top+y
						EndIf
					Case NM_DBLCLK
						'Print "double click"
						If nmhdr->hwndFrom = FTop(TopLVType) Then
							If TopLVType = 3 Then
								ViewOpenFile_Zip TopZip
							Else
								GenStr = wtTop 'check for change dir
								ViewOpenFile FTop(TopLVType)
								If GenStr <> wtTop Then
									'path change
									SetWindowText(PDispTop,wtTop)
									FindPathInTree DTop
								EndIf
							EndIf
						Else
							If Connected = FALSE Then
								If BotLVType = 3 Then
									ViewOpenFile_Zip BottomZip
								Else
									GenStr = wtBottom 'check for change dir
									ViewOpenFile FBottom(BotLVType)
									If GenStr <> wtBottom Then
										'path change
										SetWindowText(PDispBottom,wtBottom)
										FindPathInTree DBottom
									EndIf
								EndIf
							Else
								'any change of dir will be handled in sub
								ViewOpenFile FBottom(BotLVType)
							EndIf
						EndIf
						'Case NM_CUSTOMDRAW
						'	Print "NM_CUSTOMDRAW"
						'	Print "Listview:";nmhdr->hwndFrom
						'	Print "Item:";nmlv->iItem
						'	Print "subItem:";nmlv->iSubItem
						'
						'LV messages
					'Case LVN_KEYDOWN
					'	'Print "Key was pressed" 'enter key not read
					'Case LVN_BEGINDRAG
					'	'drag and drop (left)
					'Case LVN_BEGINRDRAG
					'	'drag and drop (right)
					Case LVN_COLUMNCLICK
						'should only get this in "report" view
						If nmhdr->hwndFrom = FTop(TopLVType) Then
							If TopLVType = 0 Then
								If LastSortColTop = nmlv->iSubItem Then
									'reverse directions
									If LastSortAccendTop Then
										LastSortAccendTop = FALSE
									Else
										LastSortAccendTop = TRUE
									EndIf
								Else
									LastSortAccendTop = TRUE
									LastSortColTop = nmlv->iSubItem
								EndIf
								ListView_SortItems(FTop(0),@SortFuncTop,LastSortColTop)
							Else
								If TopZip.SortCol = nmlv->iSubItem Then
									'reverse directions
								If TopZip.Accend Then
										TopZip. Accend= FALSE
									Else
										TopZip.Accend = TRUE
									EndIf
								Else
									TopZip.Accend = TRUE
									TopZip.SortCol = nmlv->iSubItem
								EndIf
								ListView_SortItems(FTop(3),@SortFuncTopZip,TopZip.SortCol)
							EndIf
						Else
							If BotLVType = 0 Then
								If LastSortColBottom = nmlv->iSubItem Then
									'reverse directions
									If LastSortAccendBottom Then
										LastSortAccendBottom = FALSE
									Else
										LastSortAccendBottom = TRUE
									EndIf
								Else
									LastSortAccendBottom = TRUE
									LastSortColBottom = nmlv->iSubItem
								EndIf
								ListView_SortItems(FBottom(0),@SortFuncBottom,LastSortColBottom)
							Else
								If BottomZip.SortCol = nmlv->iSubItem Then
									'reverse directions
									If BottomZip.Accend Then
										BottomZip.Accend = FALSE
									Else
										BottomZip.Accend = TRUE
									EndIf
								Else
									BottomZip.Accend = TRUE
									BottomZip.SortCol = nmlv->iSubItem
								EndIf
								ListView_SortItems(FBottom(3),@SortFuncBottomZip,BottomZip.SortCol)
							EndIf
						EndIf
						'
					Case LVN_BEGINLABELEDIT
						With RenameMe
							.TheLView = nmhdr->hwndFrom 'which LV
							'there will be only one selected
							.ItemNum = ListView_GetNextItem(.TheLView, -1, LVNI_SELECTED)
							'the created edit box handle
							'.EditMe = ListView_GetEditControl(.TheLView) <-- not defined
							.EditMe = SendMessage(.TheLView,LVM_GETEDITCONTROL,0,0)
							'
							If .TheLView = FTop(3) Or .TheLView = FBottom(3) Then
								'rename in zip file
								.OldValue = LVGetValue(.TheLView,.ItemNum,0)
								.IsDir = FALSE
								If LVGetValue(.TheLView,.ItemNum,1) = "File Folder" Then .IsDir = TRUE
							Else
								Dim As FileStats FStats = SelFileInfo(.TheLView,.ItemNum)
								.OldValue = FStats.FName
								.IsDir = IIf((FStats.Att And 16) = 16,TRUE,FALSE)
							EndIf
							'set path
							.ThePath = wtBottom
							If .TheLView = FTop(TopLVType) Then .ThePath = wtTop
						End With
						'
					Case LVN_ENDLABELEDIT
						'press esc key?
						'
						'from MSDN
						'When label editing is canceled or completed,
						'a list-view control sends its parent window an LVN_ENDLABELEDIT notification code.
						'The lParam parameter is the address of an NMLVDISPINFO structure.
						'The item member of this structure is an LVITEM structure whose iItem member identifies the item.
						'If editing is canceled, the pszText member of the LVITEM structure is NULL;
						'otherwise, pszText is the address of the edited text.
						'The parent window is responsible for updating the item's label if it wants to keep the new label.
						'
						'* for UNICODE use NMLVDISPINFOW *
						Dim As NMLVDISPINFOA Ptr nmlvdi = Cast(NMLVDISPINFOA Ptr, lParam)
						'Print nmlvdi->item.pszText 'if esc then is 0
						If nmlvdi->item.pszText = 0 Then
							GenStr = RenameMe.OldValue
						Else
							Dim As ZString * 255 z
							GetWindowText(RenameMe.EditMe,@z,255)
							GenStr = z
							'check for extention change
							If RenameMe.IsDir = FALSE Then
								x = InStrRev(RenameMe.OldValue,".")
								Dim As String ECheck = UCase(Mid(RenameMe.OldValue,x))
								x = InStrRev(GenStr,".")
								Dim As String ECheck2 = UCase(Mid(GenStr,x))
								If ECheck2 <> ECheck Then
									'extenion change???
									x = MessageBox(hWin,"Changing the extention may cause file not to load properly."+Chr(13)+"Continue?", "Extention Change",MB_YESNO Or MB_ICONEXCLAMATION)
									If x = IDNO Then GenStr = RenameMe.OldValue
								EndIf
							EndIf
						EndIf
						'did rename?
						If GenStr <> RenameMe.OldValue Then
							If Connected = TRUE And RenameMe.TheLView = FBottom(BotLVType) Then
								'FTP
								'works for renaming folders also
								If FtpRenameFile(ftp.hconn,RenameMe.OldValue,GenStr) = 0 Then
									'error
									GenStr = LastErrorStr()
									MessageBox(hWin,GenStr,"Rename error",MB_OK Or MB_ICONERROR)
								EndIf
								RefreshFTPFiles @ftp
							ElseIf RenameMe.TheLView = FTop(3) Or RenameMe.TheLView = FBottom(3) Then
								'rename in zip
								If strShare = "CF" Then
									'create folder entry
									If RenameMe.TheLView = FTop(3) Then
										x = zip_add_dir(TopZip.ZipPtr, TopZip.SubF + GenStr + "/")
										If x > -1 Then
											hti = TreeView_GetSelection(DTop)
											hti = PutTree(GenStr,hti,0)
											ReLoadZip TopZip
											RefreshTopZip
										EndIf
									Else
										x = zip_add_dir(BottomZip.ZipPtr, BottomZip.SubF + GenStr + "/")
										If x > -1 Then
											hti = TreeView_GetSelection(DBottom)
											hti = PutTree(GenStr,hti,1)
											ReLoadZip BottomZip
											RefreshBottomZip
										EndIf
									EndIf
								Else
									'rename the entry
									If RenameMe.TheLView = FTop(3) Then
										x = RenameFileZip(TopZip, RenameMe.OldValue, GenStr, RenameMe.IsDir)
										'0 if success
										If x = 0 Then RefreshTopZip
									Else
										x = RenameFileZip(BottomZip, RenameMe.OldValue, GenStr, RenameMe.IsDir)
										'0 if success
										If x = 0 Then RefreshBottomZip
									EndIf
								EndIf
							Else
								'local rename
								x = Name(RenameMe.ThePath + RenameMe.OldValue,RenameMe.ThePath + GenStr)
								'0 if success
								If RenameMe.TheLView = FTop(TopLVType) Then
									GetFileListTop
									'add folder
									If RenameMe.IsDir = TRUE And strShare = "CF" Then
										hti = TreeView_GetSelection(DTop)
										hti = PutTree(GenStr,hti,0)
									EndIf
									'rename folder or create zip file
									If strShare = "CreateZip" Or (RenameMe.IsDir = TRUE And strShare <> "CF") Then
										hti = TreeView_GetSelection(DTop)
										hti = TreeView_GetChild(DTop, hti)
										PreFTPPath = TreeView_GetItemText(DTop, hti)
										While PreFTPPath <> RenameMe.OldValue
											hti = TreeView_GetNextSibling(DTop, hti)
											PreFTPPath = TreeView_GetItemText(DTop, hti)
										Wend
										TV_NameIt(DTop, hti, GenStr)
									EndIf
								Else
									GetFileListBottom
									'add folder
									If RenameMe.IsDir = TRUE And strShare = "CF" Then
										hti = TreeView_GetSelection(DBottom)
										hti = PutTree(GenStr,hti,1)
									EndIf
									'rename folder or create zip file
									If strShare = "CreateZip" Or (RenameMe.IsDir = TRUE And strShare <> "CF") Then
										hti = TreeView_GetSelection(DBottom)
										hti = TreeView_GetChild(DBottom, hti)
										PreFTPPath = TreeView_GetItemText(DBottom, hti)
										While PreFTPPath <> RenameMe.OldValue
											hti = TreeView_GetNextSibling(DBottom, hti)
											PreFTPPath = TreeView_GetItemText(DBottom, hti)
										Wend
										TV_NameIt(DBottom, hti, GenStr)
									EndIf
								EndIf
							EndIf
						Else
							'esc key on a creation of a new file/folder
							If Left(GenStr,4) = "New " And strShare = "CF" Then
								If RenameMe.IsDir Then
									If Connected = TRUE And RenameMe.TheLView = FBottom(BotLVType) Then
										FtpRemoveDirectory(ftp.hconn, RenameMe.OldValue)
									ElseIf RenameMe.TheLView = FTop(3) Or RenameMe.TheLView = FBottom(3) Then
										'new folder in zip
										'there was nothing actually done, so do nothing here
										Sleep 20
									Else
										RmDir(RenameMe.ThePath + RenameMe.OldValue)
									EndIf
								Else
									'no new files created on FTP or in zip
									Kill RenameMe.ThePath + RenameMe.OldValue
								EndIf
								SendMessage(RenameMe.TheLView,LVM_DELETEITEM,RenameMe.ItemNum,0)
							EndIf
						EndIf
						'
				End Select
			EndIf
			'
		Case WM_SIZE
			Dim As RECT rStat,rTree,rList
			GetClientRect(hWin,@rc)
			x = rc.right * .23 'width of tree
			y = rc.bottom * .45 'height of tree and listviews
			If Connected Then y = rc.bottom * .4 'allow room for FTPStats area
			'Top static - this really won't "move"
			rStat.top = rc.top+3
			rStat.left = rc.left+3
			rStat.right = rc.right-3
			rStat.bottom = rStat.top+20
			MoveWindow(PDispTop,rStat.left,rStat.top,rStat.right-rStat.left,rStat.bottom-rStat.top,TRUE)
			'top treeview
			rTree.left = rStat.left
			rTree.top = rStat.bottom+3
			rTree.right = rTree.left+x
			rTree.bottom = rTree.top+y
			MoveWindow(DTop,rTree.left,rTree.top,rTree.right-rTree.left,rTree.bottom-rTree.top,TRUE)
			'top listview
			rList.left = rTree.right+3
			rList.top = rTree.top
			rList.right = rc.right-3
			rList.bottom = rTree.bottom
			Top_xy = rList 'save new area
			For x = 0 To 3
				MoveWindow(FTop(x),rList.left,rList.top,rList.right-rList.left,rList.bottom-rList.top,TRUE)
			Next
			'bottom static
			rStat.top = rTree.bottom+3
			'rStat.left = rc.left+5
			'rStat.right = rc.right-5
			rStat.bottom = rStat.top+20
			MoveWindow(PDispBottom,rStat.left,rStat.top,rStat.right-rStat.left,rStat.bottom-rStat.top,TRUE)
			'bottom treeview
			'rTree.left = rStat.left
			rTree.top = rStat.bottom+3
			'rTree.right = rTree.left+x
			rTree.bottom = rTree.top+y
			MoveWindow(DBottom,rTree.left,rTree.top,rTree.right-rTree.left,rTree.bottom-rTree.top,TRUE)
			'bottom listview
			'rList.left = rTree.right+5
			rList.top = rTree.top
			'rList.right = rc.right-5
			rList.bottom = rTree.bottom
			Bot_xy = rList 'save new area
			For x = 0 To 3
				MoveWindow(FBottom(x),rList.left,rList.top,rList.right-rList.left,rList.bottom-rList.top,TRUE)
			Next
			'hidden FTP static
			rStat.top = rTree.bottom+3
			'rStat.left = rc.left+5
			'rStat.right = rc.right-5
			rStat.bottom = rStat.top+70
			MoveWindow(FTPStats,rStat.left,rStat.top,rStat.right-rStat.left,rStat.bottom-rStat.top,TRUE)
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE
End Function

Function FileDupDlgP(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
	Dim As Long id, Event
	Dim As HWND hGen
	Dim As ZString*200 zFile
	'
	Select Case uMsg
		Case WM_INITDIALOG
			hGen = GetDlgItem(hWin,IDC_EDTInput)
			SetWindowText(hGen,strShare)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			If Event=BN_CLICKED Then
				Select Case id
					Case IDC_BTNConfirm
						strShare = ""
						hGen = GetDlgItem(hWin,IDC_RBNRenameInput)
						id = SendMessage(hGen,BM_GETCHECK, 0, 0)
						If id Then
							hGen = GetDlgItem(hWin,IDC_EDTInput)
							GetWindowText(hGen,@zFile,199)
							strShare = zFile
						EndIf
						'
						hGen = GetDlgItem(hWin,IDC_RBNSkip)
						id = SendMessage(hGen,BM_GETCHECK, 0, 0)
						If id Then
							strShare = "piks"
						EndIf
						'
						hGen = GetDlgItem(hWin,IDC_RBNOverW)
						id = SendMessage(hGen,BM_GETCHECK, 0, 0)
						If id Then
							strShare = "revo"
						EndIf
						If strShare = "" Then
							MessageBox(hWin,"Make a selection","Error",MB_OK)
						Else
							EndDialog(hWin, 0)
						EndIf
						'
				End Select
			EndIf
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE
End Function

Function ConfDelDlg(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
	Dim As Long id, Event
	Dim As HWND hdl
	Select Case uMsg
		Case WM_INITDIALOG
			hdl = GetDlgItem(hWin,IDC_STCFileName)
			SetWindowText(hdl,strShare)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			If Event=BN_CLICKED Then
				hdl = GetDlgItem(hWin,IDC_CHKNoMore)
				Select Case id
					Case IDC_BTNDel
						If SendMessage(hdl,BM_GETCHECK, 0, 0) Then
							'checked
							EndDialog(hWin, 2)
						Else
							'not
							EndDialog(hWin, 3)
						EndIf
						'
					Case IDC_BTNSkip
						If SendMessage(hdl,BM_GETCHECK, 0, 0) Then
							'checked
							EndDialog(hWin, 4)
						Else
							'not
							EndDialog(hWin, 5)
						EndIf
						'
				End Select
			EndIf
			'
		Case WM_CLOSE
			EndDialog(hWin, 0)
			'
		Case WM_SIZE
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE

End Function

Function TrashDlgP(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
	Dim As Long id, Event
	Dim As RECT rc
	Static As HWND TrashLV
	Static As HMENU TMenu
	'
	Select Case uMsg
		Case WM_INITDIALOG
			'set up Listviews
			TrashLV = GetDlgItem(hWin,IDC_LSV_TrashFiles)
			LVSetMaxCols TrashLV,5
			LVSetHeader TrashLV,1,"Name",320
			LVSetHeader TrashLV,2,"Type",90 'extension
			LVSetHeader TrashLV,3,"Original Location",320
			LVSetHeader TrashLV,4,"Date",150
			LVSetHeader TrashLV,5,"Size",60
			'test and something to clear
			LVAddItem TrashLV,"Test.txt|TXT|Original|12/19/2011 12:15PM|1.5 KB"
			DispRecycle(TrashLV)
			TMenu = GetMenu(hWin)
			SetTimer(hWin,0,1500,0)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			Select Case id
				Case IDM_RestAll
					id = RestoreRecycle(TrashLV,TRUE,TRUE)
					If id Then
						MessageBox(hWin,"Some files could not be restored","Trash Error",MB_ICONERROR And MB_OK)
						DispRecycle(TrashLV)
					Else
						EmptyRecycle 'erase Data.ini and remove Trash dir
						EndDialog(hWin, 0)
					EndIf
					'
				Case IDM_RestSel
					id = RestoreRecycle(TrashLV,TRUE,FALSE)
					If id Then
						DispRecycle(TrashLV)
					Else
						EmptyRecycle 'erase Data.ini and remove Trash dir
						EndDialog(hWin, 0)
					EndIf
					'
				Case IDM_RmvAll
					EmptyRecycle
					EndDialog(hWin, 0)
					'
				Case IDM_RmvSel
					id = RestoreRecycle(TrashLV,FALSE,FALSE)
					If id Then
						DispRecycle(TrashLV)
					Else
						EmptyRecycle 'erase Data.ini and remove Trash dir
						EndDialog(hWin, 0)
					EndIf
					'
			End Select
			'
		Case WM_CLOSE
			EndDialog(hWin, 0)
			'
		Case WM_SIZE
			GetClientRect(hWin,@rc)
			MoveWindow(TrashLV,rc.left+5,rc.top+5,rc.right-rc.left-5,rc.bottom-rc.top-5,TRUE)
			'
		Case WM_TIMER
			'is any selected?
			If SendMessage(TrashLV,LVM_GETSELECTEDCOUNT,0,0) Then
				'enable
				EnableMenuItem TMenu,IDM_RestSel,MF_ENABLED
				EnableMenuItem TMenu,IDM_RmvSel,MF_ENABLED
			Else
				'disable
				EnableMenuItem TMenu,IDM_RestSel,MF_GRAYED
				EnableMenuItem TMenu,IDM_RmvSel,MF_GRAYED
			EndIf
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE
	'
End Function

Function FTPDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
	Dim As Long id, Event,x
	Dim As HWND hTemp
	Dim As ZString * MAX_PATH BoxText
	Dim As String Host,User,Pass,RemoteDir,ConName,LocalDir
	'
	Select Case uMsg
		Case WM_INITDIALOG
			'search for prior connections on disk and put in listbox
			hTemp = GetDlgItem(hWin,IDC_LSTConnections)
			ConName = Dir(ExePath + Path_Delim + "*.ftp",32)
			While Len(ConName)
				Host = hStripFileExt(ConName)
				SendMessage(hTemp,LB_ADDSTRING,0,Cast(LPARAM,StrPtr(Host)))
				ConName = Dir()
			Wend
			SetWindowText(GetDlgItem(hWin,IDC_EDTRemDir),Path_Delim)
			SetWindowText(GetDlgItem(hWin,IDC_EDTLDir),wtTop)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			Select Case id
				Case IDC_BTNConnect
					'get textbox values
					hTemp = GetDlgItem(hWin,IDC_EDTHost)
					GetWindowText(hTemp,@BoxText,MAX_PATH)
					Host = BoxText
					hTemp = GetDlgItem(hWin,IDC_EDTUser)
					GetWindowText(hTemp,@BoxText,255)
					User = BoxText
					hTemp = GetDlgItem(hWin,IDC_EDTPassw)
					GetWindowText(hTemp,@BoxText,255)
					Pass = BoxText
					hTemp = GetDlgItem(hWin,IDC_EDTRemDir)
					GetWindowText(hTemp,@BoxText,255)
					RemoteDir = BoxText
					hTemp = GetDlgItem(hWin,IDC_EDTLDir)
					GetWindowText(hTemp,@BoxText,MAX_PATH)
					LocalDir = BoxText
					hTemp = GetDlgItem(hWin,IDC_EDTConnection)
					GetWindowText(hTemp,@BoxText,255)
					ConName = BoxText
					'try to connect
					If ftp_connect( @ftp, Host, User, Pass) Then
						'connected!
						Connected = TRUE
						'put Host + RemoteDir in a shared var?
						strShare = Host + Path_Delim
						If RemoteDir <> Path_Delim Then
							FtpSetCurrentDirectory( ftp.hconn, RemoteDir )
							strShare += RemoteDir + Path_Delim
						EndIf
						strShare += "|" + LocalDir
						'save connection data to file
						x = FreeFile
						Open ExePath + Path_Delim + ConName + ".ftp" For Output As #x
						Print #x, Host
						Print #x, User
						Print #x, Pass
						Print #x, RemoteDir
						Print #x, LocalDir
						Close #x
						SendMessage(hWin,WM_CLOSE,0,0)
					Else
						'error someplace
						MessageBox(hWin,"Connection not made","Error",MB_OK Or MB_ICONERROR)
					EndIf
					'
				Case IDC_LSTConnections
					If Event = LBN_SELCHANGE Then
						hTemp = GetDlgItem(hWin,IDC_LSTConnections)
						x = SendMessage(hTemp,LB_GETCURSEL,0,0)
						SendMessage(hTemp,LB_GETTEXT,x,Cast(LPARAM,StrPtr(BoxText)))
						ConName = BoxText
						SetWindowText(GetDlgItem(hWin,IDC_EDTConnection),ConName)
						'open this file
						x = FreeFile
						Open ExePath + Path_Delim + ConName + ".ftp" For Input As #x
						Input #x, Host
						SetWindowText(GetDlgItem(hWin,IDC_EDTHost),Host)
						Input #x, User
						SetWindowText(GetDlgItem(hWin,IDC_EDTUser),User)
						Input #x, Pass
						SetWindowText(GetDlgItem(hWin,IDC_EDTPassw),Pass)
						Input #x, RemoteDir
						SetWindowText(GetDlgItem(hWin,IDC_EDTRemDir),RemoteDir)
						Input #x, LocalDir
						SetWindowText(GetDlgItem(hWin,IDC_EDTLDir),LocalDir)
						Close #x
					EndIf
			End Select
			'
		Case WM_CLOSE
			EndDialog(hWin, 0)
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE
End Function

Function CompareListViewsDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
	Dim As Long id, Event
	Dim As Integer t,b
	Dim As Integer TMax,BMax
	Dim As HWND hNew,hNF,hOlder
	Dim As BOOL SelBtnPress = FALSE
	Dim As ZString * MAX_PATH z
	ReDim As FileStats TArr(0), BArr(0)
	'
	Select Case uMsg
		Case WM_INITDIALOG
			'"click" button to automaticly scan
			SendMessage(hWin,WM_COMMAND,MAKEWPARAM(IDC_BTNRefresh,0),0)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			Select Case id
				Case IDC_BTNRefresh
					'may have changed folders since last refresh
					'this is run on init also
					If TopZip.ZipPtr <> NULL Then
						Dim As String LVLine = TopZip.ZipFile
						If Len(TopZip.SubF) Then LVLine += " (" + TopZip.SubF+ ")"
						SetWindowText(GetDlgItem(hWin,IDC_STCCompTop),LVLine)
						'
						TMax = SendMessage(FTop(3),LVM_GETITEMCOUNT,0,0) - 1
						ReDim TArr(TMax)
						For t =  0 To TMax
							TArr(t) = SelFileInfo(FTop(3),t)
						Next
					Else
						SetWindowText(GetDlgItem(hWin,IDC_STCCompTop),wtTop)
						'
						TMax = UBound(FTPL)
						ReDim TArr(TMax)
						For t = 0 To TMax
							TArr(t).FName = FTPL(t).FName
							TArr(t).Att = FTPL(t).Att
							TArr(t).DT = FTPL(t).DT
						Next
					EndIf
					'
					If BottomZip.ZipPtr <> NULL Then
						Dim As String LVLine = BottomZip.ZipFile
						If Len(BottomZip.SubF) Then LVLine += " (" + BottomZip.SubF+ ")"
						SetWindowText(GetDlgItem(hWin,IDC_STCCompBot),LVLine)
						'
						BMax = SendMessage(FBottom(3),LVM_GETITEMCOUNT,0,0) - 1
						ReDim BArr(BMax)
						For t =  0 To BMax
							BArr(t) = SelFileInfo(FBottom(3),t)
						Next
					Else
						If Connected Then
							TMax = MAX_PATH
							If FtpGetCurrentDirectory(ftp.hconn,@z,@TMax) Then
								SetWindowText(GetDlgItem(hWin,IDC_STCCompBot),z)
								ftp.LastFTP = Timer
							Else
								'lost ftp connection
								MessageBox(hWin,"Lost connection with server","",MB_OK)
								'LogFTP "Lost connection with server"
								'FTPClose KeepFTPLog
								EndDialog(hWin, 0) 'EXIT NOW!
							EndIf
						Else
							SetWindowText(GetDlgItem(hWin,IDC_STCCompBot),wtBottom)
						EndIf
						BMax = UBound(FTPR)
						ReDim BArr(BMax)
						For t = 0 To BMax
							BArr(t).FName = FTPR(t).FName
							BArr(t).Att = FTPR(t).Att
							BArr(t).DT = FTPR(t).DT
						Next
					EndIf
					'
					'flags for Older,Newer and not found
					Dim As Byte TStat(TMax),BStat(BMax)
					'Compare date/time of all files in top against the bottom
					For t = 0 To TMax
						b = 0
						'compare apples to apples.....
						Do
							If (TArr(t).Att And 16) = 16 And (BArr(b).Att And 16) = 16 Then
								If TArr(t).FName = BArr(b).FName Then
									'mark both as "found"
									TStat(t) = 2
									BStat(b) = 2
									Exit Do
								EndIf
							EndIf
							If (TArr(t).Att And 16) <> 16 And (BArr(b).Att And 16) <> 16 Then
								If TArr(t).FName = BArr(b).FName Then
									'compare date/time
									If TArr(t).DT > BArr(b).DT Then
										TStat(t) = 1
										BStat(b) = -1
										'give couple seconds leeway?
										If TArr(t).DT <= BArr(b).DT + TimeSerial(0,0,2) Then
											'close enough to be equal
											TStat(t) = 2
											BStat(b) = 2
										EndIf
									Else
										TStat(t) = -1
										BStat(b) = 1
										'give couple seconds leeway?
										If TArr(t).DT >= BArr(b).DT - TimeSerial(0,0,2) Then
											'close enough to be equal
											TStat(t) = 2
											BStat(b) = 2
										EndIf
									EndIf
									If TArr(t).DT = BArr(b).DT Then
										'same time and date
										TStat(t) = 2
										BStat(b) = 2
									EndIf
									Exit Do
								EndIf
							EndIf
							b += 1
						Loop Until b > BMax
					Next
					'clear out listboxes
					hNew = GetDlgItem(hWin,IDC_LSTTopNew)
					hNF = GetDlgItem(hWin,IDC_LSTTopNF)
					hOlder = GetDlgItem(hWin,IDC_LSTTopOldSame)
					SendMessage(hNew,LB_RESETCONTENT,0,0)
					SendMessage(hNF,LB_RESETCONTENT,0,0)
					SendMessage(hOlder,LB_RESETCONTENT,0,0)
					'check flags to determine what to do
					For t = 0 To TMax
						Select Case TStat(t)
							Case 1
								'newer
								SendMessage(hNew,LB_ADDSTRING,0,Cast(LPARAM,StrPtr(TArr(t).FName)))
								'
							Case 0
								'not found
								SendMessage(hNF,LB_ADDSTRING,0,Cast(LPARAM,StrPtr(TArr(t).FName)))
								'
							Case -1
								'older
								SendMessage(hOlder,LB_ADDSTRING,0,Cast(LPARAM,StrPtr(TArr(t).FName)))
								'
						End Select
					Next
					'enable/disable buttons
					If SendMessage(hNew,LB_GETCOUNT,0,0) Then
						EnableWindow(GetDlgItem(hWin,IDC_BTNTopNew),TRUE)
					Else
						EnableWindow(GetDlgItem(hWin,IDC_BTNTopNew),FALSE)
					EndIf
					If SendMessage(hNF,LB_GETCOUNT,0,0) Then
						EnableWindow(GetDlgItem(hWin,IDC_BTNTopNF),TRUE)
					Else
						EnableWindow(GetDlgItem(hWin,IDC_BTNTopNF),FALSE)
					EndIf
					If SendMessage(hOlder,LB_GETCOUNT,0,0) Then
						EnableWindow(GetDlgItem(hWin,IDC_BTNTopOld),TRUE)
					Else
						EnableWindow(GetDlgItem(hWin,IDC_BTNTopOld),FALSE)
					EndIf
					'
					'clear out listboxes
					hNew = GetDlgItem(hWin,IDC_LSTBotNew)
					hNF = GetDlgItem(hWin,IDC_LSTBotNF)
					hOlder = GetDlgItem(hWin,IDC_LSTBotOldSame)
					SendMessage(hNew,LB_RESETCONTENT,0,0)
					SendMessage(hNF,LB_RESETCONTENT,0,0)
					SendMessage(hOlder,LB_RESETCONTENT,0,0)
					'check flags to determine what to do
					For b = 0 To BMax
						Select Case BStat(b)
							Case 1
								'newer
								SendMessage(hNew,LB_ADDSTRING,0,Cast(LPARAM,StrPtr(BArr(b).FName)))
								'
							Case 0
								'Print " not found"
								SendMessage(hNF,LB_ADDSTRING,0,Cast(LPARAM,StrPtr(BArr(b).FName)))
								'
							Case -1
								'older
								SendMessage(hOlder,LB_ADDSTRING,0,Cast(LPARAM,StrPtr(BArr(b).FName)))
								'
						End Select
					Next
					'
					'enable/disable buttons
					If SendMessage(hNew,LB_GETCOUNT,0,0) Then
						EnableWindow(GetDlgItem(hWin,IDC_BTNBotNew),TRUE)
					Else
						EnableWindow(GetDlgItem(hWin,IDC_BTNBotNew),FALSE)
					EndIf
					If SendMessage(hNF,LB_GETCOUNT,0,0) Then
						EnableWindow(GetDlgItem(hWin,IDC_BTNBotNF),TRUE)
					Else
						EnableWindow(GetDlgItem(hWin,IDC_BTNBotNF),FALSE)
					EndIf
					If SendMessage(hOlder,LB_GETCOUNT,0,0) Then
						EnableWindow(GetDlgItem(hWin,IDC_BTNBotOld),TRUE)
					Else
						EnableWindow(GetDlgItem(hWin,IDC_BTNBotOld),FALSE)
					EndIf
					SelBtnPress = FALSE 'should be false already
					'
				Case IDC_BTNTopNew
					SelBtnPress = TRUE
					hNew = FTop(TopLVType) 'refernce the top listview
					hOlder = GetDlgItem(hWin,IDC_LSTTopNew)
					'
				Case IDC_BTNTopOld
					SelBtnPress = TRUE
					hNew = FTop(TopLVType) 'refernce the top listview
					hOlder = GetDlgItem(hWin,IDC_LSTTopOldSame)
					'
				Case IDC_BTNTopNF
					SelBtnPress = TRUE
					hNew = FTop(TopLVType) 'refernce the top listview
					hOlder = GetDlgItem(hWin,IDC_LSTTopNF)
					'
				Case IDC_BTNBotNew
					SelBtnPress = TRUE
					hNew = FBottom(BotLVType) 'refernce the bottom listview
					hOlder = GetDlgItem(hWin,IDC_LSTBotNew)
					'
				Case IDC_BTNBotOld
					SelBtnPress = TRUE
					hNew = FBottom(BotLVType) 'refernce the bottom listview
					hOlder = GetDlgItem(hWin,IDC_LSTBotOldSame)
					'
				Case IDC_BTNBotNF
					SelBtnPress = TRUE
					hNew = FBottom(BotLVType) 'refernce the bottom listview
					hOlder = GetDlgItem(hWin,IDC_LSTBotNF)
					'
			End Select
			If SelBtnPress Then
				'hNew points to main window listview (shared var)
				TMax = SendMessage(hNew,LVM_GETITEMCOUNT,0,0)
				'hOlder points to this window's listbox
				BMax = SendMessage(hOlder,LB_GETCOUNT,0,0)
				'unselect all
				For t = 0 To TMax-1
					LV_SetSelState(hNew,t,FALSE)
				Next
				'find and select files in listbox
				Dim As ZString * 300 ZSTR
				For b = 0 To BMax-1
					SendMessage(hOlder,LB_GETTEXT,b,Cast(LPARAM,StrPtr(ZSTR))) 'get filename
					'locate in listview
					t = lvFindItem(hNew,ZSTR) 'accepts a string, then changes it to zstring and returns item number
					LV_SetSelState(hNew,t,TRUE) 'select it
				Next
				SetFocus(hNew)
			EndIf
			'
		Case WM_CLOSE
			EndDialog(hWin, 0)
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE
End Function

'next 3 are very similar
Function PropDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
	'files only
	Dim As Integer id, Event,x
	Dim As String strTemp
	Dim As ZString * 255 ZStr
	Dim As FileStats Hold
	'
	Static As String WasNamed, ThePath
	Static As BOOL Changed, WasH, WasRO, NowH, NowRO
	Static As Integer SelCount
	Static As Integer Ptr Inx
	'
	Select Case uMsg
		Case WM_INITDIALOG
			Dim As HWND hLV
			Dim As Double TotAlloc, TotSize, S 'only used in init to calcualte total file sizes
			If strShare = "Top" Then
				ThePath = wtTop
				hLV = FTop(TopLVType)
				'Hold = FTPL(Event)
			Else
				'same as above but swapping arrays and listviews
				ThePath = wtBottom
				hLV = FBottom(BotLVType)
				'Hold = FTPR(Event)
			EndIf
			'get drive info
			Dim As UInteger SectClust,ByteSect,FreeClust,TotClust
			'can not get drive info of server
			'Will report "Unknown"
			If Not(Connected = TRUE And strShare = "Bottom") Then
				ZStr = Left(ThePath,2)
				GetDiskFreeSpace(@ZStr,@SectClust,@ByteSect,@FreeClust,@TotClust)
			EndIf
			'how many selected
			SelCount = SendMessage(hLV,LVM_GETSELECTEDCOUNT,0,0) 'how many selected
			Inx = Callocate(SelCount,SizeOf(Integer)) 'storage for indexes of file array
			'loop through selections
			x = 0
			id = ListView_GetNextItem(hLV, -1, LVNI_SELECTED)
			While id > -1
				strTemp = LVGetValue(hLV, id, 0)
				Event = -1 'array order may not be same in listview
				'find this file in array
				Do
					Event += 1
					If strShare = "Top" Then
						Hold = FTPL(Event)
					Else
						Hold = FTPR(Event)
					EndIf
				Loop While Hold.FName <> strTemp
				Inx[x] = Event
				x += 1
				'set attrib boxes
				'non-changeable attribs
				If (Hold.Att And FILE_ATTRIBUTE_COMPRESSED) Then SendMessage(GetDlgItem(hWin,IDC_CHKPropZip),BM_SETCHECK,1,0)
				If (Hold.Att And FILE_ATTRIBUTE_SYSTEM) Then SendMessage(GetDlgItem(hWin,IDC_CHKPropS),BM_SETCHECK,1,0)
				'these need to watch
				If (Hold.Att And FILE_ATTRIBUTE_HIDDEN) Then
					SendMessage(GetDlgItem(hWin,IDC_CHKPropH),BM_SETCHECK,1,0)
					WasH = TRUE
					NowH = TRUE
				EndIf
				If (Hold.Att And FILE_ATTRIBUTE_READONLY) Then
					SendMessage(GetDlgItem(hWin,IDC_CHKPropRO),BM_SETCHECK,1,0)
					WasRO = TRUE
					NowRO = TRUE
				EndIf
				'actual size
				TotSize += Hold.FSize
				'disk space alloted (4k increments) depends on file system!
				S = 0
				Do
					S += SectClust*ByteSect 'loop control
					TotAlloc += SectClust*ByteSect 'actual total size of selections
				Loop Until S > Hold.FSize
				'
				id = ListView_GetNextItem(hLV, id, LVNI_SELECTED)
			Wend
			'
			SetWindowText(GetDlgItem(hWin,IDC_STCPropLocV),ThePath)
			'actual size
			strTemp = Format(TotSize,"###,###,###,###,##0") + " bytes"
			If TotSize > 1024 Then strTemp += " (" + ToKB(TotSize) + ")"
			SetWindowText(GetDlgItem(hWin,IDC_STCPropSizeV),strTemp)
			'disk space alloted
			If Connected = TRUE And strShare = "Bottom" Then
				strTemp = "Unknown"
			Else
				strTemp = Format(TotAlloc,"###,###,###,###,##0") + " bytes (" + ToKB(TotAlloc) + ")"
			EndIf
			SetWindowText(GetDlgItem(hWin,IDC_STCPropDiskSizeV),strTemp)
			'times and dates
			If SelCount = 1 Then
				strTemp = Format(Hold.DT, "mm/dd/yyyy hh:mm:ss AM/PM")
				SetWindowText(GetDlgItem(hWin,IDC_STCPropModV),strTemp)
				strTemp = Format(Hold.Create, "mm/dd/yyyy hh:mm:ss AM/PM")
				SetWindowText(GetDlgItem(hWin,IDC_STCPropCreateV),strTemp)
				strTemp = Format(Hold.LastAccess, "mm/dd/yyyy hh:mm:ss AM/PM")
				SetWindowText(GetDlgItem(hWin,IDC_STCPropAccV),strTemp)
				'save file name for later checking
				WasNamed = Hold.FName
			Else
				strTemp = "Multiple times and dates"
				SetWindowText(GetDlgItem(hWin,IDC_STCPropModV),strTemp)
				SetWindowText(GetDlgItem(hWin,IDC_STCPropCreateV),strTemp)
				SetWindowText(GetDlgItem(hWin,IDC_STCPropAccV),strTemp)
				WasNamed = Str(SelCount)+" files selected"
				'not able to change name
				EnableWindow(GetDlgItem(hWin,IDC_EDTPropName),FALSE)
			EndIf
			'file name
			SetWindowText(GetDlgItem(hWin,IDC_EDTPropName),WasNamed)
			'getting properties at FTP site?
			If Connected = TRUE And strShare = "Bottom" Then
				EnableWindow(GetDlgItem(hWin,IDC_CHKPropH),FALSE)
				EnableWindow(GetDlgItem(hWin,IDC_CHKPropRO),FALSE)
			EndIf
			SetTimer(hWin,0,1500,0)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			Select Case id
				Case IDC_BTNPropDismiss
					SendMessage(hWin,WM_CLOSE,0,0)
					'
				Case IDC_BTNPropApply
					Changed = TRUE
					'can rename if only single selection
					GetWindowText(GetDlgItem(hWin,IDC_EDTPropName),@ZStr,255)
					If ZStr <> WasNamed Then
						strTemp = ZStr 'not sure if ftp would "like" a zstring
						If Connected = TRUE And strShare = "Bottom" Then
							FtpRenameFile(ftp.hconn, WasNamed, strTemp)
						Else
							Name ThePath + WasNamed, ThePath + strTemp
						EndIf
						WasNamed = strTemp
					EndIf
					'were Attrib changed?
					If Not(Connected = TRUE And strShare = "Bottom") Then
						'loop through array
						For x = 0 To SelCount-1
							Event = Inx[x]
							If strShare = "Top" Then
								Hold = FTPL(Event)
							Else
								Hold = FTPR(Event)
							EndIf
							id = Hold.Att
							If WasRO <> NowRO Then
								If NowRO Then
									id = (id Or FILE_ATTRIBUTE_READONLY) 'turn on Read Only
								Else
									id = (id And (&HFFFFFFFF-FILE_ATTRIBUTE_READONLY))'turn off Read Only
								EndIf
							EndIf
							If WasH <> NowH Then
								If NowH Then
									id = (id Or FILE_ATTRIBUTE_HIDDEN) 'turn on hidden
								Else
									id = (id And (&HFFFFFFFF-FILE_ATTRIBUTE_HIDDEN))'turn off hidden
								EndIf
							EndIf
							SetFileAttributes(ThePath+Hold.FName,id)
						Next
					EndIf
					WasRO = NowRO
					WasH = NowH
					'
				Case IDC_CHKPropRO
					If NowRO Then
						NowRO = FALSE
					Else
						NowRO = TRUE
					EndIf
					'
				Case IDC_CHKPropH
					If NowH Then
						NowH = FALSE
					Else
						NowH = TRUE
					EndIf
					'
			End Select
			'
		Case WM_CLOSE
			DeAllocate(Inx)
			If Changed Then
				If strShare = "Top" Then
					GetFileListTop
				Else
					GetFileListBottom
				EndIf
			EndIf
			EndDialog(hWin, Changed)
			'
		Case WM_TIMER
			GetWindowText(GetDlgItem(hWin,IDC_EDTPropName),@ZStr,255)
			If ZStr <> WasNamed Or WasRO <> NowRO Or WasH <> NowH Then
				EnableWindow(GetDlgItem(hWin,IDC_BTNPropApply),TRUE)
			Else
				EnableWindow(GetDlgItem(hWin,IDC_BTNPropApply),FALSE)
			EndIf
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE
End Function

Function Prop1DirDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
	'only one folder selected
	Dim As Integer id, Event,x
	Dim As String strTemp
	Dim As ZString * 255 ZStr
	Dim As FileStats Hold
	'
	Static As String WasNamed, ThePath
	Static As BOOL Changed, WasH, WasRO, NowH, NowRO
	Static As Integer Inx
	'
	Select Case uMsg
		Case WM_INITDIALOG
			Dim As HWND hLV
			Dim As Double TotAlloc, TotSize, S 'only used in init to calcualte total file sizes
			If strShare = "Top" Then
				ThePath = wtTop
				hLV = FTop(TopLVType)
				'Hold = FTPL(Event)
			Else
				'same as above but swapping arrays and listviews
				ThePath = wtBottom
				hLV = FBottom(BotLVType)
				'Hold = FTPR(Event)
			EndIf
			'get drive info
			Dim As UInteger SectClust,ByteSect,FreeClust,TotClust
			'can not get drive info of server
			'Will report "Unknown"
			If Not(Connected = TRUE And strShare = "Bottom") Then
				ZStr = Left(ThePath,2)
				GetDiskFreeSpace(@ZStr,@SectClust,@ByteSect,@FreeClust,@TotClust)
			EndIf
			id = ListView_GetNextItem(hLV, -1, LVNI_SELECTED)
			strTemp = LVGetValue(hLV, id, 0)
			Inx = -1 'array order may not be same in listview
			'find this file in array
			Do
				Inx += 1
				If strShare = "Top" Then
					Hold = FTPL(Inx)
				Else
					Hold = FTPR(Inx)
				EndIf
			Loop While Hold.FName <> strTemp
			'set attrib boxes
			'non-changeable attribs
			If (Hold.Att And FILE_ATTRIBUTE_COMPRESSED) Then SendMessage(GetDlgItem(hWin,IDC_CHK1DirZip),BM_SETCHECK,1,0)
			If (Hold.Att And FILE_ATTRIBUTE_SYSTEM) Then SendMessage(GetDlgItem(hWin,IDC_CHK1DirS),BM_SETCHECK,1,0)
			'these need to watch
			If (Hold.Att And FILE_ATTRIBUTE_HIDDEN) Then
				SendMessage(GetDlgItem(hWin,IDC_CHK1DirH),BM_SETCHECK,1,0)
				WasH = TRUE
				NowH = TRUE
			EndIf
			If (Hold.Att And FILE_ATTRIBUTE_READONLY) Then
				SendMessage(GetDlgItem(hWin,IDC_CHK1DirRO),BM_SETCHECK,1,0)
				WasRO = TRUE
				NowRO = TRUE
			EndIf
			If Connected = TRUE And strShare = "Bottom" Then
				'need count of folders, files, and sizes ....
				TotSize = DW_AllDir_FTP(strTemp)
				'getting properties at FTP site?
				EnableWindow(GetDlgItem(hWin,IDC_CHK1DirH),FALSE)
				EnableWindow(GetDlgItem(hWin,IDC_CHK1DirRO),FALSE)
			Else
				'walk thru
				x = DW_AllDir(ThePath,strTemp)
				'DW_Folders(0) is the root so UBound(DW_Folders) is count of subfolders
				'DW_Files(0) is empty
				For x = 1 To UBound(DW_Files)
					'get file sizes for each file
					id = FileLen(DW_Files(x))
					'actual size
					TotSize += id
					'disk space alloted (4k increments) depends on file system!
					S = 0
					Do
						S += SectClust*ByteSect 'loop control
						TotAlloc += SectClust*ByteSect 'actual total size of selections
					Loop Until S > id
				Next
			EndIf
			'
			SetWindowText(GetDlgItem(hWin,IDC_STC1DirLocV),ThePath)
			'show actual size
			strTemp = Format(TotSize,"###,###,###,###,##0") + " bytes"
			If TotSize > 1024 Then strTemp += " (" + ToKB(TotSize) + ")"
			SetWindowText(GetDlgItem(hWin,IDC_STC1DirSizeV),strTemp)
			'disk space alloted
			If Connected = TRUE And strShare = "Bottom" Then
				strTemp = "Unknown"
			Else
				strTemp = Format(TotAlloc,"###,###,###,###,##0") + " bytes (" + ToKB(TotAlloc) + ")"
			EndIf
			SetWindowText(GetDlgItem(hWin,IDC_STC1DirDiskSizeV),strTemp)
			'time and date
			strTemp = Format(Hold.DT, "mm/dd/yyyy hh:mm:ss AM/PM")
			SetWindowText(GetDlgItem(hWin,IDC_STC1DirCreateV),strTemp)
			'contains
			strTemp = Str(UBound(DW_Files))+" files, "+Str(UBound(DW_Folders))+" folders"
			SetWindowText(GetDlgItem(hWin,IDC_STC1DirContV),strTemp)
			'file name
			WasNamed = Hold.FName 'save file name for later checking
			SetWindowText(GetDlgItem(hWin,IDC_EDT1DirName),WasNamed)
			SetTimer(hWin,0,1500,0)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			Select Case id
				Case IDC_BTN1DirDismiss
					SendMessage(hWin,WM_CLOSE,0,0)
					'
				Case IDC_BTN1DirApply
					Changed = TRUE
					GetWindowText(GetDlgItem(hWin,IDC_EDT1DirName),@ZStr,255)
					If ZStr <> WasNamed Then
						strTemp = ZStr 'not sure if ftp would "like" a zstring
						If Connected = TRUE And strShare = "Bottom" Then
							FtpRenameFile(ftp.hconn, WasNamed, strTemp)
						Else
							Name ThePath + WasNamed, ThePath + strTemp
						EndIf
						WasNamed = strTemp
					EndIf
					'were Attrib changed?
					If Not(Connected = TRUE And strShare = "Bottom") Then
						If strShare = "Top" Then
							Hold = FTPL(Inx)
						Else
							Hold = FTPR(Inx)
						EndIf
						id = Hold.Att
						If WasRO <> NowRO Then
							If NowRO Then
								id = (id Or FILE_ATTRIBUTE_READONLY) 'turn on Read Only
							Else
								id = (id And (&HFFFFFFFF-FILE_ATTRIBUTE_READONLY))'turn off Read Only
							EndIf
						EndIf
						If WasH <> NowH Then
							If NowH Then
								id = (id Or FILE_ATTRIBUTE_HIDDEN) 'turn on hidden
							Else
								id = (id And (&HFFFFFFFF-FILE_ATTRIBUTE_HIDDEN))'turn off hidden
							EndIf
						EndIf
						SetFileAttributes(ThePath+Hold.FName,id)
					EndIf
					WasRO = NowRO
					WasH = NowH
					'
				Case IDC_CHK1DirRO
					If NowRO Then
						NowRO = FALSE
					Else
						NowRO = TRUE
					EndIf
					'
				Case IDC_CHK1DirH
					If NowH Then
						NowH = FALSE
					Else
						NowH = TRUE
					EndIf
					'
			End Select
			'
		Case WM_CLOSE
			If Changed Then
				If strShare = "Top" Then
					GetFileListTop
				Else
					GetFileListBottom
				EndIf
			EndIf
			ReDim DW_Folders(0),DW_Files(0)
			EndDialog(hWin, Changed)
			'
		Case WM_TIMER
			GetWindowText(GetDlgItem(hWin,IDC_EDT1DirName),@ZStr,255)
			If ZStr <> WasNamed Or WasRO <> NowRO Or WasH <> NowH Then
				EnableWindow(GetDlgItem(hWin,IDC_BTN1DirApply),TRUE)
			Else
				EnableWindow(GetDlgItem(hWin,IDC_BTN1DirApply),FALSE)
			EndIf
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE
End Function

Function PropMixDlgProc(ByVal hWin As HWND, ByVal uMsg As UINT, ByVal wParam As WPARAM, ByVal lParam As LPARAM) As Integer
	'catch all ....
	Dim As Integer id, Event,x
	Dim As String strTemp
	Dim As ZString * 255 ZStr
	Dim As FileStats Hold
	'
	Static As String ThePath
	Static As BOOL Changed, WasH, WasRO, NowH, NowRO
	Static As Integer SelCount
	Static As Integer Ptr Inx
	'
	Select Case uMsg
		Case WM_INITDIALOG
			Dim As HWND hLV
			Dim As Double TotAlloc, TotSize, S 'only used in init to calcualte total file sizes
			Dim As Integer FileCount, FolderCount
			If strShare = "Top" Then
				ThePath = wtTop
				hLV = FTop(TopLVType)
				'Hold = FTPL(Event)
			Else
				'same as above but swapping arrays and listviews
				ThePath = wtBottom
				hLV = FBottom(BotLVType)
				'Hold = FTPR(Event)
			EndIf
			'get drive info
			Dim As UInteger SectClust,ByteSect,FreeClust,TotClust
			'can not get drive info of server
			'Will report "Unknown"
			If Not(Connected = TRUE And strShare = "Bottom") Then
				ZStr = Left(ThePath,2)
				GetDiskFreeSpace(@ZStr,@SectClust,@ByteSect,@FreeClust,@TotClust)
			EndIf
			'how many selected
			SelCount = SendMessage(hLV,LVM_GETSELECTEDCOUNT,0,0) 'how many selected
			Inx = Callocate(SelCount,SizeOf(Integer)) 'storage for indexes of file array
			'loop through selections
			x = 0
			id = ListView_GetNextItem(hLV, -1, LVNI_SELECTED)
			While id > -1
				strTemp = LVGetValue(hLV, id, 0)
				Event = -1 'array order may not be same in listview
				'find this file in array
				Do
					Event += 1
					If strShare = "Top" Then
						Hold = FTPL(Event)
					Else
						Hold = FTPR(Event)
					EndIf
				Loop While Hold.FName <> strTemp
				Inx[x] = Event
				x += 1
				'set attrib boxes
				'non-changeable attribs
				If (Hold.Att And FILE_ATTRIBUTE_COMPRESSED) Then SendMessage(GetDlgItem(hWin,IDC_CHKMixZip),BM_SETCHECK,1,0)
				If (Hold.Att And FILE_ATTRIBUTE_SYSTEM) Then SendMessage(GetDlgItem(hWin,IDC_CHKMixS),BM_SETCHECK,1,0)
				'these need to watch
				If (Hold.Att And FILE_ATTRIBUTE_HIDDEN) Then
					SendMessage(GetDlgItem(hWin,IDC_CHKMixH),BM_SETCHECK,1,0)
					WasH = TRUE
					NowH = TRUE
				EndIf
				If (Hold.Att And FILE_ATTRIBUTE_READONLY) Then
					SendMessage(GetDlgItem(hWin,IDC_CHKMixRO),BM_SETCHECK,1,0)
					WasRO = TRUE
					NowRO = TRUE
				EndIf
				If (Hold.Att And FILE_ATTRIBUTE_DIRECTORY) Then
					If Connected = TRUE And strShare = "Bottom" Then
						'need count of folders, files, and sizes ....
						TotSize += DW_AllDir_FTP(strTemp)
					Else
						'walk thru
						x = DW_AllDir(ThePath,strTemp)
						'DW_Folders(0) is the root so UBound(DW_Folders) is count of subfolders
						'DW_Files(0) is empty
						For x = 1 To UBound(DW_Files)
							'get file sizes for each file
							id = FileLen(DW_Files(x))
							'actual size
							TotSize += id
							'disk space alloted increments depends on file system!
							S = 0
							Do
								S += SectClust*ByteSect 'loop control
								TotAlloc += SectClust*ByteSect 'actual total size of selections
							Loop Until S > id
						Next
					EndIf
					FileCount += UBound(DW_Files)
					FolderCount += UBound(DW_Folders)
				Else
					'actual size
					TotSize += Hold.FSize
					'disk space alloted (4k increments) depends on file system!
					S = 0
					Do
						S += SectClust*ByteSect 'loop control
						TotAlloc += SectClust*ByteSect 'actual total size of selections
					Loop Until S > Hold.FSize
					FileCount += 1
				EndIf
				'
				id = ListView_GetNextItem(hLV, id, LVNI_SELECTED)
			Wend
			'
			SetWindowText(GetDlgItem(hWin,IDC_STCMixLocV),ThePath)
			'show actual size
			strTemp = Format(TotSize,"###,###,###,###,##0") + " bytes"
			If TotSize > 1024 Then strTemp += " (" + ToKB(TotSize) + ")"
			SetWindowText(GetDlgItem(hWin,IDC_STCMixSizeV),strTemp)
			'disk space alloted
			If Connected = TRUE And strShare = "Bottom" Then
				strTemp = "Unknown"
				'getting properties at FTP site?
				EnableWindow(GetDlgItem(hWin,IDC_CHKMixH),FALSE)
				EnableWindow(GetDlgItem(hWin,IDC_CHKMixRO),FALSE)
			Else
				strTemp = Format(TotAlloc,"###,###,###,###,##0") + " bytes (" + ToKB(TotAlloc) + ")"
			EndIf
			SetWindowText(GetDlgItem(hWin,IDC_STCMixDiskSizeV),strTemp)
			'contains
			strTemp = Str(FileCount)+" files, "+Str(FolderCount)+" folders"
			SetWindowText(GetDlgItem(hWin,IDC_STCMixContV),strTemp)
			If Not(Connected = TRUE And strShare = "Bottom") Then SetTimer(hWin,0,1500,0)
			'
		Case WM_COMMAND
			id=LoWord(wParam)
			Event=HiWord(wParam)
			Select Case id
				Case IDC_BTNMixDismiss
					SendMessage(hWin,WM_CLOSE,0,0)
					'
				Case IDC_BTNMixApply
					Changed = TRUE
					'Attrib is only thing can change
					'if bottom listview and connected, these are disabled
					'loop through array
					For x = 0 To SelCount-1
						Event = Inx[x]
						If strShare = "Top" Then
							Hold = FTPL(Event)
						Else
							Hold = FTPR(Event)
						EndIf
						id = Hold.Att
						'what Attrib changed?
						If WasRO <> NowRO Then
							If NowRO Then
								id = (id Or FILE_ATTRIBUTE_READONLY) 'turn on Read Only
							Else
								id = (id And (&HFFFFFFFF-FILE_ATTRIBUTE_READONLY))'turn off Read Only
							EndIf
						EndIf
						If WasH <> NowH Then
							If NowH Then
								id = (id Or FILE_ATTRIBUTE_HIDDEN) 'turn on hidden
							Else
								id = (id And (&HFFFFFFFF-FILE_ATTRIBUTE_HIDDEN))'turn off hidden
							EndIf
						EndIf
						SetFileAttributes(ThePath+Hold.FName,id)
					Next
					WasRO = NowRO
					WasH = NowH
					'
				Case IDC_CHKMixRO
					If NowRO Then
						NowRO = FALSE
					Else
						NowRO = TRUE
					EndIf
					'
				Case IDC_CHKMixH
					If NowH Then
						NowH = FALSE
					Else
						NowH = TRUE
					EndIf
					'
			End Select
			'
		Case WM_CLOSE
			If Changed Then
				If strShare = "Top" Then
					GetFileListTop
				Else
					GetFileListBottom
				EndIf
			EndIf
			ReDim DW_Folders(0),DW_Files(0)
			EndDialog(hWin, Changed)
			'
		Case WM_TIMER
			If WasRO <> NowRO Or WasH <> NowH Then
				EnableWindow(GetDlgItem(hWin,IDC_BTNMixApply),TRUE)
			Else
				EnableWindow(GetDlgItem(hWin,IDC_BTNMixApply),FALSE)
			EndIf
			'
		Case Else
			Return FALSE
			'
	End Select
	Return TRUE
End Function
