' функция получения части пути до последнего слеша
' взята из моей библиотеки window9: https://sourceforge.net/projects/guiwindow9/
Function Getpathpart(sPath As String) As String
	
	Dim As Long iPos = Instrrev(sPath , sSeparatorPath)
	
	Return Left(sPath , iPos - 1)
	
End Function

' функция проверяет , является ли путь относительным или полным
' если путь относительный , то добавляет текущий путь к имени файла
' параметр:
' sFile - имя файла (возможно с путем к нему)
function CheckPath(sFile as string) as string
	
	if len(GETPATHPART(sFile)) = 0 then ' если только имя файла без пути
		
		dim as string sCurDir = curdir ' получим текущий путь
		
		if right(sCurDir , 1) <> sSeparatorPath then ' если в конце нет разделителя
			
			sFile = sCurDir & sSeparatorPath & sFile ' то в путь с именем файла добавим разделитель
			
		else
			
			sFile = sCurDir & sFile ' путь с именем файла
			
		EndIf
		
	EndIf
	
	return sFile
	
End Function

' присваивает значение внутренней переменной для хранения текущего имени файла
' параметры:
' sFile - имя файла в однобайтовой кодировке
' pwsFile - имя файла в юникоде
Sub SetFileName(sFile As String , pwsFile As Wstring Ptr = 0)
	
	If pwsFile Then ' если указано имя файла в юникоде
		
		If Len(*pwsFile) Then ' если длина имени больше нуля
			
			If pObjFB.pszFileName Then ' если уже что-то хранится
				
				Deallocate(pObjFB.pszFileName) ' освободим буфер
				
			Endif
			
			pObjFB.pszFileName = Callocate((Len(*pwsFile)+1)) ' выделим память
			
			if pObjFB.pszFileName then
				
				' преобразуем в однобайтовую кодировку и присвоим значение внутренней переменной
				#ifdef __UNIX_SYSTEM__
					*(pObjFB.pszFileName) = Unicodetoutf8(pwsFile) ' преобразуем в UTF8
				#EndIf
				#ifdef __FB_WIN32__
					*(pObjFB.pszFileName) = UTFTOASCII(pwsFile , w32CP_ACP) ' преобразуем в ASCII
				#EndIf
				#ifdef __FB_dos__
					*(pObjFB.pszFileName) = sFile ' просто присвоим значение
				#EndIf
				
			else
				
				DrawErrorMemory() ' выводим ошибку памяти
				
			endif
			
		Endif
		
	Else
		
		If Len(sFile) Then ' если длина имени больше нуля
			
			If pObjFB.pszFileName Then ' если уже что-то хранится
				
				Deallocate(pObjFB.pszFileName) ' освободим буфер
				
			Endif
			
			pObjFB.pszFileName = Callocate(Len(sFile)+1) ' выделим память
			
			if pObjFB.pszFileName then
				
				*(pObjFB.pszFileName) = sFile ' присвоим значение внутренней переменной
				
			else
				
				DrawErrorMemory() ' выводим ошибку памяти
				
			endif
			
		Endif
		
	Endif
	
End Sub

#ifdef __UNIX_SYSTEM__
	#macro LW_LCASE(v)
		v
	#EndMacro	
#else
	#macro LW_LCASE(v)
		lcase(v)
	#EndMacro
#EndIf

' производит перечисление файлов в текущем каталоге и сохраняет в списке
Sub ExamineFiles (pRestName as wstring ptr)
	
	#ifdef __FB_DOS__
		Dim As String sFile = Dir("*.*", &h20 Or &h2 Or &h1) ' запуск перечисления по указанным параметрам
	#else	
		Dim As String sFile = Dir("*", &h20 Or &h2 Or &h1) ' запуск перечисления по указанным параметрам
	#EndIf
	
	Do While Len(sFile) > 0 'если что-то есть
		
		If sFile <> "." Andalso sFile <> ".." Then ' если строки не равны . и .. 
			
			#ifdef __UNIX_SYSTEM__
				Dim As Wstring Ptr pws = Utf8tounicode(sFile) ' преобразуем в юникод из UTF8
			#EndIf
			#ifdef __FB_WIN32__
				Dim As Wstring Ptr pws = ASCIITOUTF(sFile , w32CP_ACP) ' преобразуем в юникод из ASCII
			#EndIf
			#ifdef __fb_DOS__
				Dim As Wstring Ptr pws = callocate(len(sFile)+1) ' выделим память
				if pws then *pws = sFile ' просто присвоим не преобразуя
			#EndIf
			
			if pws then
				
				' если есть остаток пути и он совпадает
				if pRestName andalso LW_LCASE(*pRestName) = left(LW_LCASE(*pws) , len(*pRestName)) then
					
					pObjFB.pListDir.Add(pws) ' добавляем в список
					
				elseif pRestName = 0 then ' если остатка нет
					
					pObjFB.pListDir.Add(pws) ' добавляем в список
					
				endif
				
				Deallocate(pws) ' освободим память
				
			else
				
				DrawErrorMemory() ' выводим ошибку памяти
				
			endif
			
		Endif
		
		sFile = Dir() ' продолжаем перечислять
		
	Loop
	
End Sub

' производит перечисление папок в текущем каталоге и сохраняет в списке
Sub ExamineFolders (pRestName as wstring ptr)
	
	var iRetAt = 0
	
	#ifdef __FB_DOS__
		Dim As String sFile = Dir("*.*", &h20 or &h10 Or &h4 or &h2 Or &h1 , iRetAt) ' запуск перечисления по указанным параметрам
	#else	
		Dim As String sFile = Dir("*", &h20 or &h10 Or &h4 or &h2 Or &h1 , iRetAt) ' запуск перечисления по указанным параметрам
	#EndIf
	
	Do While Len(sFile) > 0 'если что-то есть
		
		If sFile <> "." Andalso sFile <> ".." Then ' если строки не равны . и .. 
			
			#ifdef __UNIX_SYSTEM__
				Dim As Wstring Ptr pws = Utf8tounicode(sFile) ' преобразуем в юникод из UTF8
			#EndIf
			#ifdef __FB_WIN32__
				Dim As Wstring Ptr pws = ASCIITOUTF(sFile , w32CP_ACP) ' преобразуем в юникод из ASCII
			#EndIf
			#ifdef __fb_DOS__
				Dim As Wstring Ptr pws = callocate(len(sFile)+1) ' выделим память
				if pws then *pws = sFile ' просто присвоим не преобразуя
			#EndIf
			
			if pws then
				
				if iRetAt and &h10 then ' нужен только вывод папок
					
					' если есть остаток пути и он совпадает
					if pRestName andalso LW_LCASE(*pRestName) = left(LW_LCASE(*pws) , len(*pRestName)) then
						
						pObjFB.pListDir.Add(pws) ' добавляем в список
						
					elseif pRestName = 0 then ' если остатка нет
						
						pObjFB.pListDir.Add(pws) ' добавляем в список
						
					endif
					
				EndIf
				
				Deallocate(pws) ' освободим память
				
			else
				
				DrawErrorMemory() ' выводим ошибку памяти
				
			endif
			
		Endif
		
		sFile = Dir(iRetAt) ' продолжаем перечислять
		
	Loop
	
End Sub

' вспомогательная функция для перечисления файлов
' параметры:
' sCurPath - текущий каталог для перечисления
' iFlagSave - флаг (1 - сохранение ; 0 - загрузка)
Function FillFiles(sCurPath As String , iFlagSave as Long , pwsAutoAdd as wstring ptr ptr) As Long
	
	if len(sCurPath) = 0 then return 0 ' если путь пустой , выходим
	
	pObjFB.pListDir.DeleteAll() ' очистим список
	
	dim as Wstring ptr pRestName ' остаток пути справа
	
	dim as Byte bFlagNoSep ' флаг активируется , если в конце пути нет разделителя
	
	#ifdef __UNIX_SYSTEM__
	#else
		if len(sCurPath) < 3 orelse mid(sCurPath , 2 , 2) <> ":\" then ' если путь на win и dos некорректный с самого начала
			
			return 0 'выходим из функции
			
		EndIf
	#EndIf
	
	' попытка сделать путь текущим 
	' если Chdir не может установить путь , тогда проверка остатка пути
	if Chdir(sCurPath) then
		
		' получим часть пути от начала , включая последний слеш
		dim as string sTempPath = GetPathPart(sCurPath)
		
		if len(sTempPath) = 0 then ' если путь пустой
			
			#ifdef __UNIX_SYSTEM__
				
				' если вначале пути есть разделитель
				if left(sCurPath , 1) = sSeparatorPath then
					
					Chdir(sSeparatorPath) ' переходим в корень
					
				else ' что-то непонятное введено
					
					return 0 'выходим из функции
					
				EndIf
				
			#EndIf
			
		else
			
			' еще попытка сделать путь текущим , но путь выше по иерархии
			' при неудаче выходим из функции            
			#ifdef __UNIX_SYSTEM__
				
				if Chdir(sTempPath) then return 0
				
			#else
				
				if len(sTempPath) = 2 andalso mid(sTempPath , 2 , 1) = ":" then ' если остаток пути примерно такой C:
					
					if Chdir(sTempPath & sSeparatorPath) then return 0 ' добавим разделитель и пробуем назначить папку текущей
					
				else
					
					if Chdir(sTempPath) then return 0 ' пробуем назначить папку текущей
					
				EndIf
				
			#EndIf
			
		EndIf
		
		' получим остаток после слеша
		dim as string sRestPath = right(sCurPath , len(sCurPath) - len(sTempPath) - 1)
		
		if len(sRestPath) then
			
			#ifdef __FB_win32__
				'на windows кодировка у файлов ascii
				pRestName = ASCIITOUTF(sRestPath , w32CP_ACP)
			#else
				'на linux и Dos вызовем для преобразования:
				pRestName = Utf8tounicode(sRestPath)
			#EndIf
			
		EndIf
		
	else ' Chdir отработала успешно
		
		' проверяем , есть ли у пути разделитель
		if right(sCurPath , 1) <> sSeparatorPath then
			
			bFlagNoSep = 1 ' активируем флаг , разделителя нет
			
		EndIf
		
	EndIf
	
	' перечисление папок
	ExamineFolders(pRestName)
	
	' сохраним сколько папок
	Dim As Long iFoldersCount = pObjFB.pListDir.GetSize()
	
	' перечисление файлов
	ExamineFiles(pRestName)
	
	ClearLine(1) ' очистим первую экранную строку
	
	ClearLine(pObj.iHeightRows-1) ' очистим предпоследнюю экранную строку
	
	' выведем подсказку об операции (сохранение или загрузка)
	FileBoxDrawTips(iFlagSave)
	
	' выведем на экран список
	DrawRowsExamineFiles(0 , iFoldersCount)
	
	if pObjFB.pListDir.GetSize() = 1 then ' если найден только один файл
		
		' выделим память
		*pwsAutoAdd = callocate((pObjFB.pListDir.GetValueLenIndex(0) + 4 )*sizeof(wstring))
		
		if *pwsAutoAdd then
			
			' если какой-то остаток пути есть
			if pRestName andalso len(*pRestName) then
				
				' выделим его и сохраним в буфере
				*(*pwsAutoAdd) = mid(*(pObjFB.pListDir.GetValueIndex(0)) , len(*pRestName)+1)
				
			else ' если остатка пути нет
				
				if bFlagNoSep then ' если в конце нет разделителя
					
					' добавим разделитель и имя файла
					*(*pwsAutoAdd) = wstr(sSeparatorPath) & *(pObjFB.pListDir.GetValueIndex(0))
					
				else
					
					' добавим имя файла
					*(*pwsAutoAdd) = *(pObjFB.pListDir.GetValueIndex(0))
					
				EndIf
				
			EndIf
			
			if iFoldersCount then ' если имя является папкой
				
				' добавим в конец разделитель
				*(*pwsAutoAdd) &= wstr(sSeparatorPath)
				
			EndIf
			
		else
			
			DrawErrorMemory() ' выводим ошибку памяти
			
		endif
		
	EndIf
	
	' если переменная использовалась , освобождаем адрес
	if pRestName then deallocate pRestName
	
	' возвратим кол-во папок
	Return iFoldersCount
	
End Function

' устанавливает курсор в зависимости от расположения в строке при движении вправо
' pwsBuf - буфер строки файлового имени
' iCursorInString - позиция курсора в строке
' iCursor - позиция курсора на экране
' iScroll - прокрутка строки (с какой позиции строка выводится)
sub FileSetRightCursor(pwsBuf As Wstring Ptr , Byref iCursorInString As Long , Byref iCursor As Long , Byref iScroll As Long)
	
	If iCursor >= pObj.iWidthSimbols-3 Then ' если экранный курсор больше размера экранной строки
		
		' получим позицию курсора на основе реальной позиции в строке
		iCursor = GetTabStopPositionFromRealPosition(pwsBuf , iCursorInString+1)
		
		dim as Long iTempPos = 1 ' позиция в строке буфера , используется для посчета скроллинга и курсора
		
		iScroll = 0 ' прокрутку на начало
		
		' пока слово не окажется в области видимости экрана
		while iCursor > pObj.iWidthSimbols - 2
			
			' получить текущую позицию с учетом табуляций
			dim as Long iCurentPos = GetTabStopPositionFromRealPosition(pwsBuf , iTempPos)
			
			' получить предыдущую позицию с учетом табуляций
			dim as Long iNextPos = GetTabStopPositionFromRealPosition(pwsBuf , iTempPos+1)
			
			iCurentPos = (iNextPos - iCurentPos) ' получим шаг между позициями
			
			iScroll += iCurentPos ' увеличим прокрутку
			
			iCursor-= iCurentPos ' уменьшаем позицию курсора
			
			iTempPos+=1 ' увеличим позицию в строке буфера
			
		Wend
		
	else ' экранный курсор в рамках размера экранной строки
		
		' получим позицию перед перемещением
		dim as long iPos1 = GetTabStopPositionFromRealPosition(pwsBuf , iCursorInString)
		
		' получим позицию после перемещения
		dim as long iPos2 = GetTabStopPositionFromRealPosition(pwsBuf , iCursorInString+1)
		
		iCursor+= (iPos2-iPos1) ' сдвинем курсор вправо на ширину шага
		
	Endif
	
End Sub

' устанавливает курсор в зависимости от расположения в строке при движении влево
' pwsBuf - буфер строки файлового имени
' iCursorInString - позиция курсора в строке
' iCursor - позиция курсора на экране
' iScroll - прокрутка строки (с какой позиции строка выводится)
sub FileSetLeftCursor(pwsBuf As Wstring Ptr , Byref iCursorInString As Long , Byref iCursor As Long , Byref iScroll As Long)
	
	' если можно сдвигать курсор без участия скроллинга
	if iCursor > 3 orelse (iScroll = 0 andalso iCursor > 1) then
		
		' получим позицию после перемещения
		dim as long iPos1 = GetTabStopPositionFromRealPosition(pwsBuf , iCursorInString+1)
		
		' получим позицию перед перемещением
		dim as long iPos2 = GetTabStopPositionFromRealPosition(pwsBuf , iCursorInString+2)
		
		iCursor-= (iPos2-iPos1) ' сдвинем курсор влево на ширину шага
		
	elseif iScroll then ' если есть скроллинг
		
		dim as Long iTempPos = 1 ' позиция в строке буфера , используется для посчета скроллинга и курсора
		
		' получим позицию курсора на основе реальной позиции в строке
		iCursor = GetTabStopPositionFromRealPosition(pwsBuf , iCursorInString+1)
		
		iScroll = 0 ' прокрутку на начало
		'
		while iCursor > 3 ' пока курсор не окажется вначале строки
			
			' получим текущую позицию 
			dim as long iPos0 = GetTabStopPositionFromRealPosition(pwsBuf , iTempPos)
			
			' получим следующую позицию
			dim as long iPos1 = GetTabStopPositionFromRealPosition(pwsBuf , iTempPos+1)
			
			iScroll+= (iPos1-iPos0) ' увеличим скроллинг на ширину шага
			
			iTempPos+=1 ' сдвинем позицию в строке буфера
			
			iCursor -= (iPos1-iPos0) ' уменьшим позицию курсора на ширину шага
			
		wend
		
	EndIf
	
End Sub

' Добавляет один символ к имени файловой строки
' параметры:
' pwsBuf - буфер строки файлового имени
' pwsSymbol - добавляемый символ
' iCursorInString - позиция курсора в строке
' iCursor - позиция курсора на экране
' iScroll - прокрутка строки (с какой позиции строка выводится)
Sub FileCommandAddSymbol(pwsBuf As Wstring Ptr , pwsSymbol As Wstring Ptr ,_
Byref iCursorInString As Long , Byref iCursor As Long = 0 , Byref iScroll As Long = 0)
	
	If iCursorInString >= Len(*pwsBuf) Then ' если позиция курсора в конце строки
		
		*pwsBuf &= *pwsSymbol ' просто добавляем символ в конце строки
		
	Else ' в других случаях
		
		' вставляем символ в строку
		*pwsBuf = Left(*pwsBuf , iCursorInString) & *pwsSymbol & Mid(*pwsBuf , iCursorInString+1)
		
	Endif
	
	' увеличим позицию курсора в строке
	iCursorInString+=1
	
	' устанавливаем курсор
	FileSetRightCursor(pwsBuf , iCursorInString , iCursor , iScroll)
	
End Sub

' удаление символа с помощью клавиши BACKSPACE в файловой строке
' параметры:
' pwsBuf - буфер строки фалового имени
' iCursorInString - позиция курсора в строке
' iCursor - позиция курсора на экране
' iScroll - прокрутка строки (с какой позиции строка выводится)
Sub FileCommandBackSpaceSymbol(pwsBuf As Wstring Ptr , Byref iCursorInString As Long ,_
Byref iCursor As Long = 0 , Byref iScroll As Long = 0)
	
	' уменьшим позицию курсора в строке
	if iCursorInString > 0 then
		
		' уменьшаем позицию в строке
		iCursorInString-=1
		
		'устанавливаем курсор
		FileSetLeftCursor(pwsBuf , iCursorInString , iCursor , iScroll)
		
		' удалим из строки символ взади курсора
		*pwsBuf = Left(*pwsBuf , iCursorInString) & Mid(*pwsBuf , iCursorInString+2)
		
	EndIf
	
End Sub

' удаление символа с помощью клавиши DELETE в файловой строке
'параметры:
' pwsBuf - буфер строки фалового имени
' iCursorInString - позиция курсора в строке
Sub FileCommandDeleteSymbol(pwsBuf As Wstring Ptr , Byref iCursorInString As Long)
	
	' просто удаляем символ в текущей позиции из строки
	*pwsBuf = Left(*pwsBuf , iCursorInString) & Mid(*pwsBuf , iCursorInString+2)
	
End Sub

' перемещение курсора влево в файловой строке
' параметры:
' iCursorInString - позиция курсора в строке
' iCursor - позиция курсора на экране
' iScroll - прокрутка строки (с какой позиции строка выводится)
Sub FileCommandLeftCursor(pwsBuf As Wstring Ptr , Byref iCursorInString As Long ,_
Byref iCursor As Long = 0 , Byref iScroll As Long = 0)
	
	' если есть возможность сдвинуть курсор влево
	if iCursorInString > 0 then 
		
		iCursorInString-=1 ' уменьшаем позицию в строке
		
		'устанавливаем курсор
		FileSetLeftCursor(pwsBuf , iCursorInString , iCursor , iScroll)
		
	EndIf
	
End Sub

' перемещение курсора вправо в файловой строке
' параметры:
' pwsBuf - буфер со строкой
' iCursorInString - позиция курсора в строке
' iCursor - позиция курсора на экране
' iScroll - прокрутка строки (с какой позиции строка выводится)
Sub FileCommandRightCursor(pwsBuf As Wstring Ptr , Byref iCursorInString As Long ,_
Byref iCursor As Long = 0 , Byref iScroll As Long = 0)
	
	' если есть возможность сдвинуть курсор вправо
	if iCursorInString < Len(*pwsBuf) Then
		
		iCursorInString+=1 ' увеличиваем позицию в строке
		
		'устанавливаем курсор
		FileSetRightCursor(pwsBuf , iCursorInString , iCursor , iScroll)
		
	EndIf
	
End Sub

' процедура проверки является ли папкой данный тип файла
' взята из моей библиотеки window9: https://sourceforge.net/projects/guiwindow9/
#ifdef __UNIX_SYSTEM__
	Function isDirExists(sFileName As String) As Long
		
		' создаем нужную структуру для функции stat
		Dim As _stat Ptr tempBuf
		
		' выделим память под структуру
		tempBuf = Callocate (Sizeof(_stat)+100)
		
		if tempBuf then
			
			' вызываем функцию для информации о файле\каталоге
			stat( Strptr(sFileName) , tempBuf)
			
			If S_ISDIR( tempBuf->st_mode ) Then ' если папка
				
				Function = 1 ' возвратим успех
				
			Endif
			
			Deallocate(tempBuf) ' освободим память
			
		else
			
			DrawErrorMemory() ' выводим ошибку памяти
			
		endif
		
	End Function
#endif

#ifdef __fb_win32__
	
	'Function isDirExists(sFileName As String) As Long
		'
		'' создаем нужную структуру для функции w32FindFirstFile
		'Dim As w32FIND_DATAA g_FileInformation
		'
		'' уберем разделители путей на конце строки с файлом
		'Dim As string sTemp = Rtrim(sFileName, Any "\/")
		'
		'' выполняем поиск в данном каталоге
		'Dim As any ptr hFind = w32FindFirstFile(Strptr(sTemp), @g_FileInformation)
		'DrawInPos(0, sTemp,1,1,4)
		'' если нет ошибки
		'If hFind <> Cast(Any Ptr, -1) Then
			'
			'' если это папка
			'If g_FileInformation.dwFileAttributes And w32FILE_ATTRIBUTE_DIRECTORY  Then				
				'
				'Function = 1 ' возвратим успех
				'
			'Endif
			'
			'w32FindClose(hFind) ' завершаем поиск
			'
		'Endif
		'
	'End Function
	
	Function isDirExists(sFileName As String) As Long
		
		dim as string sCurDir = curdir() ' получим текущий каталог
		
		if chdir(sFileName) = 0 then ' если смогли поменять каталог
			
			chdir(sCurDir) ' вернем назад сохраненный каталог
			
			return 1 ' возвратим успех
			
		EndIf
		
	End Function
	
#endif

#ifdef __fb_dos__
	
	Function isDirExists(sFileName As String) As Long
		
		dim as string sCurDir = curdir() ' получим текущий каталог
		
		if chdir(sFileName) = 0 then ' если смогли поменять каталог
			
			chdir(sCurDir) ' вернем назад сохраненный каталог
			
			return 1 ' возвратим успех
			
		EndIf
		
	End Function
	
#EndIf

' преобразование кодировки , в зависимости от выбора пользователя или автоопределение
' параметр:
' pszBuf - указатель на буфер с байтами
function EncodeFileLoad(pszBuf as byte ptr) as wstring ptr
	
	dim as wstring ptr pwsRet ' переменная буфера для возврата юникод-строки
	
	#ifdef __FB_WIN32__
		
		Dim As Long iUnicode = Cast(Long Ptr,pszBuf)[0] ' получим 4 первых байта из pszBuf
		
		if (iUnicode And &hFFFF) = &hFEFF Then ' проверим равен ли коду для UTF16
			
			pwsRet = cast(wstring ptr , pszBuf+2) ' переместим начальный буфер на пару байт
			
			dim as string sTemp = Unicodetoutf8(pwsRet) ' преобразуем в UTF8
			
			' убираем символ с кодом 13
			sTemp = Replacestring(sTemp , Chr(13) , "" , ,1)
			
			pwsRet = Utf8tounicode(sTemp) ' преобразуем текст в юникод
			
			pObjFB.szEncoding = "UTF-16" ' сохраним название кодировки
			
		Elseif (iUnicode And &hFFFFFF) = &hBFBBEF Then ' проверим равен ли коду для UTF8 (BOM)
			
			pszBuf+=3 ' переместим начальный буфер на три байта
			
			' убираем символ с кодом 13
			Dim As String sBuf = Replacestring(*Cast(Zstring Ptr  , pszBuf) , Chr(13) , "" , ,1)
			
			pwsRet = Utf8tounicode(sBuf) ' преобразуем текст в юникод
			
			pObjFB.szEncoding = "UTF-8(BOM)" ' сохраним название кодировки
			
		Else
			
			DrawEncoding(0) ' выведем подсказку о кодировках
			
			do
				
				dim as Long iKey = GetOnlyAscKey() ' получим ascii клавишу (0 или 1)
				
				if iKey = 48 then ' цифра 0 (если ASCII)
					
					' убираем символ с кодом 13
					Dim As String sBuf = Replacestring(*Cast(Zstring Ptr  , pszBuf) , Chr(13) , "" , ,1)
					
					pwsRet = ASCIITOUTF(sBuf , w32CP_ACP) ' преобразуем текст в юникод из ASCII
					
					pObjFB.szEncoding = "ASCII" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
				elseif iKey = 49 then ' цифра 1 (если UTF8)
					
					' убираем символ с кодом 13
					Dim As String sBuf = Replacestring(*Cast(Zstring Ptr  , pszBuf) , Chr(13) , "" , ,1)
					
					pwsRet = Utf8tounicode(sBuf) ' преобразуем текст в юникод из UTF8
					
					pObjFB.szEncoding = "UTF-8" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
				EndIf
				
			Loop
			
		Endif
		
	#EndIf
	
	#ifdef __UNIX_SYSTEM__
		Dim As Long iUnicode = Cast(Long Ptr,pszBuf)[0] ' получим 4 первых байта из pszBuf
		
		if iUnicode = &hFEFF Then ' проверим равен ли коду для UTF32
			
			pwsRet = cast(wstring ptr , pszBuf+4) ' переместим начальный буфер на 4 байта
			
			dim as string sTemp = Unicodetoutf8(pwsRet) ' преобразуем в utf8
			
			' убираем символ с кодом 13
			sTemp = Replacestring(sTemp , Chr(13) , "" , ,1)
			
			pwsRet = Utf8tounicode(sTemp) ' преобразуем текст в юникод
			
			pObjFB.szEncoding = "UTF-32" ' сохраним название кодировки
			
		Elseif (iUnicode And &hFFFFFF) = &hBFBBEF Then ' проверим равен ли коду для UTF8 (BOM)
			
			pszBuf+=3 ' переместим начальный буфер на три байта
			
			' убираем символ с кодом 13
			Dim As String sBuf = Replacestring(*Cast(Zstring Ptr  , pszBuf) , Chr(13) , "" , ,1)
			
			pwsRet = Utf8tounicode(sBuf) ' преобразуем текст в юникод
			
			pObjFB.szEncoding = "UTF-8(BOM)" ' сохраним название кодировки
			
		else
			
			' убираем символ с кодом 13
			Dim As String sBuf = Replacestring(*Cast(Zstring Ptr  , pszBuf) , Chr(13) , "" , ,1)
			
			pwsRet = Utf8tounicode(sBuf) ' преобразуем текст в юникод
			
			pObjFB.szEncoding = "UTF-8" ' сохраним название кодировки
			
		endif
	#EndIf
	
	#ifdef __FB_DOS__
		
		' выделим память
		pwsRet = callocate((len(*Cast(Zstring Ptr  , pszBuf))+1)*sizeof(wstring))
		
		if pwsRet then
			
			' убираем символ с кодом 13 и присвоим значение
			*pwsRet = Replacestring(*Cast(Zstring Ptr  , pszBuf) , Chr(13) , "" , ,1)
			
		else
			
			DrawErrorMemory() ' выводим ошибку памяти
			
		endif
		
	#EndIf
	
	return pwsRet ' вернем указатель на буфер
	
End Function

' сохранение файла с преобразованием кодировки
' параметры:
' fp - хендл файла
' sBuf - сохраняемый буфер
' iFlagFastSave - флаг быстрого сохранения
' iIndexKey - индекс/эмуляция клавиши
sub EncodeFileSave(fp as File ptr  , sBuf as string , iFlagFastSave as Long = 0 , iIndexKey as Long = 0)
	
	#ifdef __FB_WIN32__
		
		do
			
			dim as Long iKey
			
			if iFlagFastSave then ' если быстрое сохранение
				
				iKey = iIndexKey ' запишем имеющийся индекс (сэмулируем нажатие клавиши)
				
			else
			
				iKey = GetOnlyAscKey() ' получим ascii клавишу (0 , 1 , 2 , 3)
				
			EndIf
			
			select case iKey ' что за клавиша?
					
				Case 48 ' цифра 0 (если ASCII)
					
					dim as wstring ptr pwsBuf = Utf8tounicode(sBuf) ' из utf8 в unicode
					
					if pwsBuf then ' если указатель не нулевой
						
						dim as string s = UTFTOASCII(pwsBuf , w32CP_ACP) ' из unicode в ascii
						
						' запишем буфер в файл
						File_Write_Data(fp , strptr(s) , len(s))
						
						deallocate(pwsbuf) ' освободим память
						
					EndIf
					
					pObjFB.szEncoding = "ASCII" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
				case 49 ' цифра 1
					
					' запишем буфер в файл
					File_Write_Data(fp , strptr(sBuf) , len(sBuf))
					
					pObjFB.szEncoding = "UTF-8" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
				case 50 ' цифра 2
					
					dim as Long iUnicode = &hBFBBEF ' установим код для UTF8(BOM)
					
					' запишем BOM UTF8
					File_Write_Data(fp , @iUnicode , 3)
					
					' запишем буфер в файл
					File_Write_Data(fp , strptr(sBuf) , len(sBuf))
					
					pObjFB.szEncoding = "UTF-8(BOM)" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
				case 51 ' цифра 3
					
					dim as Long iUnicode = &hFEFF ' установим код для UTF16
					
					' запишем BOM UTF16
					File_Write_Data(fp , @iUnicode , 2)
					
					dim as wstring ptr pwsBuf = Utf8tounicode(sBuf) ' из utf8 в unicode
					
					if pwsBuf then ' если указатель не нулевой
						
						' запишем буфер в файл
						File_Write_Data(fp , pwsbuf , len(*pwsbuf)*sizeof(wstring))
						
						deallocate(pwsbuf) ' освободим память
						
					EndIf
					
					pObjFB.szEncoding = "UTF-16" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
			End Select
			
		Loop
		
	#EndIf
	
	#ifdef __UNIX_SYSTEM__
		
		do

			dim as Long iKey
			
			if iFlagFastSave then ' если быстрое сохранение
				
				iKey = iIndexKey ' запишем имеющийся индекс (сэмулируем нажатие клавиши)
				
			else
			
				iKey = GetOnlyAscKey() ' получим ascii клавишу (0 , 1 , 2)
				
			EndIf
			
			select case iKey 'что за клавиша?
					
				case 48 ' цифра 0 (если utf8)
					
					' запишем буфер в файл
					File_Write_Data(fp , strptr(sBuf) , len(sBuf))
					
					pObjFB.szEncoding = "UTF-8" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
				case 49 ' цифра 1 (если utf8(BOM))
					
					dim as Long iUnicode = &hBFBBEF
					
					' запишем BOM UTF8
					File_Write_Data(fp , @iUnicode , 3)
					
					' запишем буфер в файл
					File_Write_Data(fp , strptr(sBuf) , len(sBuf))
					
					pObjFB.szEncoding = "UTF-8(BOM)" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
				case 50 ' цифра 2
					
					dim as Long iUnicode = &hFEFF0000 ' установим код UTF32
					
					' запишем BOM UTF32
					File_Write_Data(fp , @iUnicode , 4)
					
					dim as wstring ptr pwsBuf = Utf8tounicode(sBuf) ' из utf8 в unicode  
					
					if pwsBuf then ' если указатель не нулевой
						
						' запишем буфер в файл
						File_Write_Data(fp , pwsbuf , len(*pwsbuf)*sizeof(wstring))
						
						deallocate(pwsbuf) ' освободим память
						
					EndIf
					
					pObjFB.szEncoding = "UTF-32" ' сохраним название кодировки
					
					exit do ' выходим из цикла
					
			End Select
			
		Loop
		
	#EndIf
	
	#ifdef __FB_DOS__
		
		pObjFB.szEncoding = "ASCII" ' сохраним название кодировки
		
		' запишем буфер в файл
		File_Write_Data(fp , strptr(sBuf) , len(sBuf))
		
	#EndIf
	
End sub

' получение индекса кодировки при быстром сохранении
function GetIndexEncoding() as LONG
	
	#ifdef __UNIX_SYSTEM__
		
		select case pObjFB.szEncoding
			
			Case "UTF-8"
			
				return 48
			
			case "UTF-8(BOM)"
			
				return 49
			
			case "UTF-32"
			
				return 50
			
			case else
			
				return 48
			
		End Select
		
	#endif
		
	#ifdef __FB_WIN32__
	
		select case pObjFB.szEncoding
			
			case "ASCII"
			
				return 48
			
			Case "UTF-8"
			
				return 49
			
			case "UTF-8(BOM)"
			
				return 50
			
			case "UTF-16"
			
				return 51
			
			case else
			
				return 48
			
		End Select
		
	#EndIf
	
	#ifdef __FB_DOS__
		
		return 0
		
	#EndIf
	
End Function

' загрузка файла в редактор
' параметр:
' sFile - имя файла с путем к нему
Function LoadFile(sFile As String) As Long
	
	dim as File ptr fp = File_Open(sFile , 0) ' открываем файл для чтения
	
	If fp = 0 Then ' если файл открыт неудачно
		
		ClearLine(pObj.iHeightRows) ' очищаем последнюю линию
		
		' выводим сообщение об ошибке
		DrawInPos(0 , "Error opening the file" , pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
		
		GetAnyKey() ' ожидаем любую клавишу
		
	Else ' файл открыт удачно
		
		SelectAll() ' выделим весь текст в редакторе
		
		DeleteKey() ' удалим выделенный текст
		
		tUD.ClearUndo() ' очистим стэк
		
		tUD.bFlagNotDeleteFirst = 1 ' самый первый узел не будет удаляться (изначальное содержимое файла)
		
		Dim As long iLenght = File_Size(fp) ' получим размер файла
		
		If iLenght Then ' если размер больше нуля
			
			Dim As Byte Ptr pszBuf = Callocate(iLenght+4) ' выделим память по размеру
			
			dim as Byte ptr pDeallocBuf = pszBuf ' просто сохраним указатель для освобождения памяти
			
			If pszBuf Then ' если буфер валидный
				
				File_Read_Data(fp , pszBuf , iLenght) ' получим текст из файла
				
				Dim As Wstring Ptr pwsTemp ' для буфера с преобразованной кодировкой
				
				If Len(*Cast(Zstring Ptr  , pszBuf)) Then ' если длина файла не нулевая
					
					pwsTemp = EncodeFileLoad(pszBuf)
					
					If pwsTemp Then ' если указатель не нулевой
						
						If Len(*pwsTemp) Then ' если длина не нулевая
							
							InsertText(pwsTemp) ' вставим текст в редактор
							
							SetPosition(1) ' позицию в тексте на самое начало
							
							pObjFB.iFlagSave = 1 ' флаг сохранения активируем
							
						Endif
						
						Deallocate(pwsTemp) ' освободим память
						
					Endif
					
				Endif
				
				Deallocate(pDeallocBuf) ' освободим память
				
			else
				
				DrawErrorMemory() ' выводим ошибку памяти
				
			Endif
			
		Endif
		
		File_Close(fp) ' закроем файл
		
		Return 1 ' возвращаем успешный статус
		
	Endif
	
End Function

' сохранение файла на диск
' параметр:
' sFile - имя файла с путем к нему
Function SaveFile(sFile As String , iFlagFastSave as Long = 0) As Long
	
	if File_Exitsts(sFile) then ' если файл существует
		
		' если сохраняем тот же файл
		if pObjFB.pszFileName andalso ucase(*(pObjFB.pszFileName)) = ucase(sFile) then
			
			remove(strptr(sFile)) ' удалим файл
			
		else
			
			DrawFileExists() ' выводим подсказку о существовании файла
			
			do
				
				dim as Long iKey = GetOnlyAscKey() ' получим код клавиши
				
				if iKey = 48 then ' цифра 0 (если ничего делать не нужно )
					
					ClearLine(2) ' очистим 2 строку
					
					return 0 ' выходим из процедуры
					
				elseif iKey = 49 then ' цифра 1
					
					remove(strptr(sFile)) ' удалим файл
					
					exit do ' выйдем из цикла
					
				EndIf
				
			Loop
			
		endif
		
	EndIf
	
	dim as File ptr fp = File_Open(sFile) ' открываем файл для чтения и записи
	
	If fp = 0 Then ' если файл открыт неудачно
		
		ClearLine(pObj.iHeightRows) ' очищаем последнюю линию
		
		' выводим сообщение об ошибке
		DrawInPos(0 , "Error save the file" , pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
		
		GetAnyKey() ' ожидаем любую клавишу
		
	Else ' если файл открыт удачно
		
		Dim As String sBuf = GetAllBuffer() ' получим весь текст из списка
		
		if iFlagFastSave = 0 then
			
			DrawEncoding(1) ' выводим подсказку о кодировках
			
			EncodeFileSave(fp , sBuf)
			
		else
		
			dim as long iIndexEnc = GetIndexEncoding()
			
			if iIndexEnc >=0 then
			
				EncodeFileSave(fp , sBuf , 1 , iIndexEnc)
			
			endif
			
		EndIf
		
		pObjFB.iFlagSave = 1 ' флаг сохранения активируем
		
		File_Close(fp) ' закроем файл
		
		Return 1 ' возвращаем успешный статус
		
	Endif
	
End Function

' Сохранение имени файла для быстрого запуска 
sub SaveNameForQuickRun()
	
	dim as string sPathTemp
	
	#ifdef __UNIX_SYSTEM__
		
		sPathTemp = "/tmp"
		
	#EndIf
	
	#ifdef __FB_WIN32__
		
		dim as Long iLen = 256
		
		dim as zstring*257 szTemp 
		
		w32GetTempPath(iLen , @szTemp)
		
		if right(szTemp , 1) = sSeparatorPath then
			
			sPathTemp = left(szTemp , len(szTemp)-1)
			
		else
			
			sPathTemp = szTemp
			
		EndIf
		
	#EndIf
	
	#ifdef __FB_DOS__
		
		sPathTemp = exepath & "\0_TEMP_0"
		
		mkdir sPathTemp
		
	#EndIf
	
	SetFileName(sPathTemp & sSeparatorPath & "0_TEMP_0.bas")
	
End Sub

sub ClearTempName()
	
	deallocate(pObjFB.pszFileName)

	pObjFB.pszFileName = 0
	
	pObjFB.iFlagSave = 0 ' флаг сохранения деактивируем
	
End Sub

' процедура при нажатии клавиши ENTER при выборе пути (загрузки или сохранении)
' параметры:
' pwsFilePath - имя файла вместе с путем к нему
' iFlagSave - флаг (1 - сохранение ; 0 - загрузка)
Function FileCommandEnter(pwsFilePath As Wstring Ptr , iFlagSave As Long) As Long
	
	' если указатель не нулевой и строка не нулевая
	If pwsFilePath Andalso Len(*pwsFilePath) Then
		
		' преобразуем путь в однобайтовую кодировку
		#ifdef __UNIX_SYSTEM__
			Dim As String sFile = Unicodetoutf8(*pwsFilePath)
		#Endif
		#ifdef __FB_win32__
			Dim As String sFile = UTFTOASCII(pwsFilePath , w32CP_ACP)
		#Endif
		#ifdef __FB_dos__
			Dim As String sFile = *pwsFilePath
		#Endif		
		
		
		' если загружаем файл и файл существует
		If iFlagSave = 0 Andalso File_Exitsts(sFile) andalso isDirExists(sFile) = 0 Then
			
			sFile = CheckPath(sFile) ' проверим путь на относительность и если что заменим полным путем
			
			' если загрузка успешна
			If LoadFile(sFile) Then
				
				' сохраним имя файла
				SetFileName(sFile)
				
				' возвратим успешный статус
				Return 1
				
			Endif
			
		Elseif iFlagSave = 1 Then 'если сохраняем файл
			
			' получим путь из строки с файлом
			Dim As String sDir = Getpathpart(sFile)
			
			' если путь является папкой
			If isDirExists(sDir) Then
				
				' если сохранение успешно
				If SaveFile(sFile) Then
					
					' сохраним имя файла
					SetFileName(sFile)
					
					' возвратим успешный статус
					Return 1
					
				Endif
				
			Endif
			
		Endif
		
	Endif
	
End Function

' вывод подсказки об операции (сохранение или загрузка)
' параметр:
' iFlagSave - флаг (1 - сохранение ; 0 - загрузка)
Sub FileBoxDrawTips(iFlagSave As Long)
	
	If iFlagSave Then ' если флаг активен
		
		' тогда подсказка о сохранении
		DrawInPos(0 , "  SAVE  ", 1 , pObj.iWidthSimbols-10 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
		
	Else ' если флаг не активен
		
		' тогда подсказка о загрузке
		DrawInPos(0 , "  OPEN  ", 1 , pObj.iWidthSimbols-10 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
		
	Endif
	
End Sub

' проверяет загружен ли в текущий момент какой-либо файл
' и если загружен , спрашивает о закрытии текщего файла
' после проверки вызывает процедуру загрузки нового файла или
' выходит из процедуры , позволяя работать с ранее открытым файлом
sub FileCheckLoad()
	
	if pObjFB.pszFileName then ' если какой-то файл уже открыт
		
		ClearLine(pObj.iHeightRows) ' очистка последней строки
		
		' выводим сообщение
		DrawInPos(0,"Close curent file? (ENTER - Yes \ ESC - No)",pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
		
		do
			
			dim as Long iKey = GetOnlyAscKey() ' получим любой не юникод символ
			
			if iKey = CVK_ENTER then ' старый файл закроем и откроем новый
				
				clearLine(pObj.iHeightRows)
				
				if pObjFB.iFlagSave = 0 then ' если файл не сохранен
					
					FileDlgNotSave() ' выводим диалог о запросе сохранения
					
				EndIf
				
				FileBoxOpen() ' запускаем процедуру открытия файла
				
				exit do
				
			elseif iKey = CVK_ESC then 'не станем закрывать старый файл
				
				exit do ' просто выходим
				
			EndIf
			
		Loop
		
		' если это новый файл и что-то было написано
	elseif tUD.pStack1.iSize orelse tUD.pStack2.iSize orelse tUD.pAccumBuf then
		
		FileDlgNotSave() ' выводим диалог о запросе сохранения
		
		FileBoxOpen() ' запускаем процедуру открытия файла
		
	else ' пустой редактор , никаких изменений не было
		
		FileBoxOpen() ' запускаем процедуру открытия файла
		
	EndIf
	
End Sub

' диалог выбора\редактирования имени файла для загрузки или сохранения
' параметры:
' iFlagSave - флаг (1 - сохранение ; 0 - загрузка)
' sInitString - начальная строка имени файла для вывода на экран
Sub FileBox(iFlagSave As Long , sInitString As String)
	
	Dim As Wstring*1024 wsFilePath ' буфер для строки имени файла
	
	dim as wstring ptr pwsAutoAdd ' буфер для возможного текста автодополненной строки
	
	Dim As Long iCursorInString ' курсор в строке
	
	Dim As Long iCursor = 1 ' курсор на экране
	
	Dim As Long iScroll ' прокрутка строки на экране
	
	Dim As Long iKey ' буфер для клавиши
	
	Dim As Long iIndexExamine ' индекс для вывода перечисленных файлов 
	
	Dim As Long iCountDirs ' кол-во папок в данном каталоге
	
	If Len(sInitString) Then ' если длина начальной строки имени файла не нулевая
		
		#ifdef __UNIX_SYSTEM__
			Dim As Wstring Ptr pwsTemp = Utf8tounicode(sInitString) ' преобразуем имя файла в юникод
		#EndIf
		#ifdef __FB_WIN32__
			Dim As Wstring Ptr pwsTemp = ASCIITOUTF(sInitString , w32CP_ACP) ' преобразуем имя файла в юникод
		#EndIf
		#ifdef __FB_dos__
			Dim As Wstring Ptr pwsTemp = callocate(len(sInitString)+1)
			if pwsTemp then *pwsTemp = sInitString
		#EndIf		
		
		if pwsTemp then ' если указатель валидный
			
			' сохраним юникод строку в буфер
			wsFilePath = *pwsTemp
			
			' освободим память
			Deallocate(pwsTemp)
			
		else
			
			DrawErrorMemory() ' выводим ошибку памяти
			
		endif
		
		' курсор в строке на самый конец
		iCursorInString = Len(wsFilePath)
		
		' посчитаем курсор на экране
		iCursor = GetTabStopPositionFromRealPosition(@wsFilePath , iCursorInString+1)
		
		if iCursor >= pObj.iWidthSimbols-3 Then ' если экранный курсор больше размера экранной строки
			
			'устанавливаем курсор
			FileSetRightCursor(@wsFilePath , iCursorInString , iCursor , iScroll)
			
		EndIf
		
	Endif
	
	' выведем подсказку об операции (сохранение или загрузка)
	FileBoxDrawTips(iFlagSave)
	
	' выведем буфер с именем файла на экран
	DrawRowFileCommand(@wsFilePath , iCursor , iScroll)
	
	Do
		
		Dim As Wstring Ptr pwsKeys ' буфер для получения юникод символа
		
		iKey = GetKeyUni(pwsKeys , 1) ' получим обычный или юникод символ
		
		If iKey Then ' если получили обычный символ
			
			Select Case iKey ' что это за символ
					
				Case CVK_ESC
					
					Exit Do ' выходим из диалога
					
				Case CVK_TAB
					
					' делаем перечисление файлов в каталоге и выводим их список на экран
					#ifdef __UNIX_SYSTEM__
						'на linux кодировка у файлов utf8
						iCountDirs = FillFiles(Unicodetoutf8(wsFilePath) , iFlagSave , @pwsAutoAdd)
					#EndIf
					#ifdef __FB_win32__
						'на windows кодировка у файлов ascii
						iCountDirs = FillFiles(UTFTOASCII(wsFilePath , w32CP_ACP) , iFlagSave , @pwsAutoAdd)
					#EndIf
					#ifdef __FB_DOS__
						'на dos кодировка у файлов ascii
						iCountDirs = FillFiles(wsFilePath , iFlagSave , @pwsAutoAdd)
					#EndIf
					
					if pwsAutoAdd then ' если было автодополнение имени файла
						
						' по числу букв
						for i as long = 1 to len(*pwsAutoAdd)
							
							' добавим символ в строку с именем файла
							FileCommandAddSymbol(@wsFilePath , mid(*pwsAutoAdd , i , 1) , iCursorInString , iCursor , iScroll)
							
						Next
						
						' освободим память
						deallocate(pwsAutoAdd)
						' обнулим переменную
						pwsAutoAdd = 0
						
					EndIf
					
				Case CVK_BACKSPACE
					
					' удаляем один символ
					FileCommandBackSpaceSymbol(@wsFilePath , iCursorInString , iCursor , iScroll)
					
				Case CVK_DELETE
					
					' удаляем один символ
					FileCommandDeleteSymbol(@wsFilePath , iCursorInString)
					
				Case CVK_ENTER
					
					' запускаем процедуру загрузки или сохранения
					If FileCommandEnter(@wsFilePath , iFlagSave) Then
						
						Exit Do ' выходим из цикла при удачной операции
						
					Endif
					
					' если ненужные сочетания клавиш 
				Case CVK_INSERT,CVK_HOME,CVK_END,CVK_PAGEUP,CVK_PAGEDOWN, _
					CVK_F1,CVK_F2,CVK_F3,CVK_F4,CVK_F5,CVK_F6,CVK_F7,CVK_F8,CVK_F9,CVK_F12,_
					CVK_SHIFT_LEFT,CVK_SHIFT_RIGHT,CVK_SHIFT_UP,CVK_SHIFT_DOWN,CVK_SHIFT_HOME,CVK_SHIFT_END
					
					' игнорируем
					
				Case CVK_LEFT
					
					' двигаем курсор влево
					FileCommandLeftCursor(@wsFilePath , iCursorInString , iCursor , iScroll)
					
				Case CVK_RIGHT
					
					' двигаем курсор вправо
					FileCommandRightCursor(@wsFilePath , iCursorInString , iCursor , iScroll)
					
				Case CVK_UP
					
					' если список с перечисленными файлами не пуст
					If pObjFB.pListDir.GetSize() Then
						
						' сдвигаем индекс для вывода в меньшую сторону
						If iIndexExamine-1 > -1 Then iIndexExamine-=1
						
						CursorOnOff(0) ' выключим курсор
						
						'выводим перечисленные файлы на экран
						DrawRowsExamineFiles(iIndexExamine , iCountDirs)
						
						CursorOnOff(1) ' включим курсор
						
					Endif					
					
				Case CVK_DOWN
					
					' если список с перечисленными файлами не пуст
					If pObjFB.pListDir.GetSize() Then
						
						' сдвигаем индекс для вывода в большую сторону
						iIndexExamine+=1
						
						CursorOnOff(0) ' выключим курсор
						
						'выводим перечисленные файлы на экран
						DrawRowsExamineFiles(iIndexExamine , iCountDirs)
						
						CursorOnOff(1) ' включим курсор
						
					Endif
					
				Case Else ' если другие символы
					
					If iKey = CVK_TAB Orelse iKey > 31 Then ' если это текстовый символ
						
						#ifdef Win9x
							' преобразуем символ из OEM в UNICODE
							dim as Wstring ptr pwsTemp = ASCIITOUTF(chr(iKey) , w32CP_OEM)
							if pwsTemp then
								' добавим или вставим символ в строку с именем файла
								FileCommandAddSymbol(@wsFilePath , pwsTemp , iCursorInString , iCursor , iScroll)
								deallocate(pwsTemp)
							endif
						#else
							' добавим или вставим символ в строку с именем файла
							FileCommandAddSymbol(@wsFilePath , Wchr(iKey) , iCursorInString , iCursor , iScroll)
						#endif
					Endif
					
			End Select
			
		Elseif pwsKeys Then ' если расширенный символ (юникод)
			
			' добавим или вставим символ в строку с именем файла
			FileCommandAddSymbol(@wsFilePath , pwsKeys , iCursorInString , iCursor , iScroll)
			
			' освободим память для буфера клавиши
			Deallocate(pwsKeys)
			
			' обнулим буфер клавиши
			pwsKeys = 0
			
		Endif
		
		'' выведем подсказку об операции (сохранение или загрузка)
		'FileBoxDrawTips(iFlagSave)
		
		' выведем буфер с именем файла на экран
		DrawRowFileCommand(@wsFilePath , iCursor , iScroll)
		
	Loop
	
	' очистим все линии в цикле
	for i as Long = 1 to pObj.iHeightRows
		
		ClearLine(i)
		
	Next	
	
End Sub

' вспомогательная процедура для открытия файла , чтобы определить начальный путь для вывода
Sub FileBoxOpen()
	
	Dim As String sDir ' начальная файловая строка для вывода
	
	' если путь с именем файла уже сохранен
	If pObjFB.pszFileName Andalso Len(*(pObjFB.pszFileName)) Then
		
		' начальной файловой строке будет присвоено значение пути (имя файла обрезано)
		sDir = Getpathpart(*(pObjFB.pszFileName))
		
	Else
		
		' начальной файловой строке будет присвоено значение пути текущей системной папки
		sDir = Curdir
		
	Endif
	
	' запускаем диалог открытия файла
	FileBox(0 , sDir)
	
End Sub

' вспомогательная процедура для сохранения файла, чтобы определить начальный путь для вывода
Sub FileBoxSave()
	
	Dim As String sDir ' начальная файловая строка для вывода
	
	' если путь с именем файла уже сохранен
	If pObjFB.pszFileName Andalso Len(*(pObjFB.pszFileName)) Then
		
		' начальной файловой строке будет присвоено значение этого пути
		sDir = *(pObjFB.pszFileName)
		
	Else
		
		' начальной файловой строке будет присвоено значение пути текущей системной папки
		sDir = Curdir
		
	Endif
	
	' запускаем диалог сохранения файла
	FileBox(1 , sDir)	
	
End Sub

' вывод информации о том , что файл не сохранен
Sub FileDlgNotSave()
	
	ClearLine(pObj.iHeightRows) ' очищаем последнюю линию
	
	' выводим предупреждение
	DrawInPos(0,"File not saved, save? (ENTER - Yes \ ESC - No)" , pObj.iHeightRows , 1 , (pObj.iColorBackGround shl 4) or pObj.iColorWarning)
	
	Do
		
		Dim As Long iKey = GetOnlyAscKey() ' получим клавишу
		
		If iKey = CVK_ENTER Then
			
			FileBoxSave() ' запускаем сохранение
			
			Exit Do ' выходим из цикла
			
		Elseif iKey = CVK_ESC Then
			
			Exit Do ' выходим из цикла
			
		Endif
		
	Loop
	
End Sub

' Функции ниже взяты из моей библиотеки window9: https://sourceforge.net/projects/guiwindow9/
' Встроенные файловые функции не использую по причине проблем на системе DOS.

' проверка существования файла
' Параметр:
' sFile - имя файла
function File_Exitsts(sFile as string) as long
	
	dim as FILE ptr fp = fopen(strptr(sFile), "rb")
	
	if fp then 
		
		fclose(fp)
		
		return -1
		
	EndIf
	
End Function

' Открытие файла
' Параметры:
' sFile - имя файла
' iMode - режим открытия (0 - чтение , 1 - чтение и запись)
function File_Open(sFile as string , iMode as Long = 1) as FILE ptr
	
	dim as FILE ptr fp
	
	if iMode then
		
		fp = fopen(sFile, "r+b")
		
		if fp = 0 then
			
			fp = fopen(sFile, "wb")
			
		EndIf
		
	else
		
		fp = fopen(strptr(sFile), "rb")
		
	EndIf
	
	return fp
	
End Function

' Закрытие файла
' Параметр:
' fp - хендл файла
sub File_Close(fp as File ptr)
	
	fclose(fp)
	
End Sub

' Размер файла
' Параметр:
' fp - хендл файла
function File_Size (fp as File ptr) as long
	
	dim as integer iBackupPos = ftell(fp)
	
	fseek(fp, 0, SEEK_END)
	
	function = ftell(fp)
	
	fseek(fp, iBackupPos, SEEK_SET)
	
End Function

' Чтение определенного кол-ва байт из файла
' Параметр:
' fp - хендл файла
' pMem - буфер , куда читать
' lenght - кол-во байт
Sub File_Read_Data(fp as File ptr , pMem as any ptr , lenght as Long)
	
	fread ( pMem , lenght , 1 , fp)
	
End Sub

' Чтение одной строки из файла
' Параметр:
' fp - хендл файла
function File_Read_String(fp as FILE ptr) as string
	
	Dim buf As Byte
	
	Dim iEndOfFile As Long
	
	Dim rez As String
	
	Do
		
		buf  = cast(byte,fgetc(fp))
		
		iEndOfFile = feof(fp)
		
		if iEndOfFile orelse buf=10 then exit do
		
		If buf<>13  Then
			
			rez=rez & Chr(buf)
			
		EndIf
		
	Loop
	
	Return rez	
	
End Function

' Чтение одной строки из файла
' Параметры:
' fp - хендл файла
' Buf - буфер , который надо записать
' Lenght - длина буфера
sub File_Write_Data(fp as File ptr , Buf as aNy ptr , Lenght as Long)
	
	fwrite(Buf , Lenght , 1 , fp )
	
End Sub

' Чтение одной строки из файла
' Параметры:
' fp - хендл файла
' s - строка , которую надо записать
Sub File_Write_String(fp As File ptr , s As String)
	
	If Len(s) Then
		
		fputs(s, fp)
		
	Endif
	
End Sub

' Функция-сигнализатор конца файла
' Параметр:
' fp - хендл файла
function File_Eof(fp as File ptr) as Long
	
	'the function of the C language 'feof' - shows the end of the file after not a valid read operation, therefore not suitable for this function! 
	
	dim as Long iBackupPos = ftell(fp)
	
	fseek(fp, 0, SEEK_END)
	
	function = (ftell(fp)=iBackupPos)
	
	fseek(fp, iBackupPos, SEEK_SET)
	
End Function



