Форум » GUI » Как записать в INI-файл массив ? » Ответить

Как записать в INI-файл массив ?

Andrey: Столкнулся с непоняткой.... Раньше использовал свою обработку INI-файлов. Перешел на стандартный Харборовский.... Не могу понять, как записать в секцию МАССИВ - например список файлов ? И как потом считать его в массив ? BEGIN INI File cFileIni GET cPubPathFrom SECTION "SETTINGS" ENTRY "From" DEFAULT "C:\XLS-2009" GET cPubPathTo SECTION "SETTINGS" ENTRY "To" DEFAULT "C:\DBF-2009" GET cPubFileMaska SECTION "SETTINGS" ENTRY "MASK" DEFAULT "*.xls" GET aDim SECTION "FILE_LIST" ??????? END INI И еще, можно ли записывать и считывать 2-3 мерный массив.... У меня было можно, например: [Список_файлов] Файл_1 = { "spiski.xls", .T., "обработан ", 20, NIL } Файл_2 = { "centr.xls", .F., "не обработан", 12, NIL }

Ответов - 25, стр: 1 2 All

SADSTAR2: 1. для более гибкой работы с ИНИ-файлами лучше пользоваться исходными функциями в их числе есть такие *-----------------------------------------------------------------------------* Function _GetSectionNames(cIniFile) Return ( aSectionList ) *-----------------------------------------------------------------------------* Function _GetSection( cSection, cIniFile ) Return ( aKeyValueList ) 2. У меня массивы из текстового вида преобразуются в нормальный так aFromClipBoard:=&(cTxt)

Andrey: SADSTAR2 пишет: У меня массивы из текстового вида преобразуются в нормальный так aFromClipBoard:=&(cTxt) А более подробней можно ?

Петр: Andrey пишет: Раньше использовал свою обработку INI-файлов. Перешел на стандартный Харборовский.... BEGIN INI File cFileIni GET cPubPathFrom SECTION "SETTINGS" ENTRY "From" DEFAULT "C:\XLS-2009" GET cPubPathTo SECTION "SETTINGS" ENTRY "To" DEFAULT "C:\DBF-2009" GET cPubFileMaska SECTION "SETTINGS" ENTRY "MASK" DEFAULT "*.xls" GET aDim SECTION "FILE_LIST" ??????? END INI Это не Путь Воина. Я укажу вам Истинный путь [pre2]/** */ #define INIFILE_SAVE_OK 0 #define INIFILE_RESTORE_OK 0 #define INIFILE_NOT_EXISTS -1 #define INIFILE_NOT_VALID -2 #define INIFILE_SECTION_NOT_VALID -3 #define INIFILE_CANNOT_WRITE -4 #define INIFILE_KEY_NOT_VALID -5 /** */ REQUEST HB_CODEPAGE_RU866 REQUEST HB_CODEPAGE_RU1251 REQUEST HB_LANG_RU866 REQUEST HB_LANG_RUWIN /** */ PROCEDURE main() LOCAL cFile LOCAL aFile1, aFile2, e, nErrCode := -5 // hb_cdpSelect( "RU1251" ) hb_langSelect( "RUWIN" ) hb_setTermCP( "RU866", "RU1251", .f. ) hb_fNameSplit( hb_progName(), , @cFile ) cFile := hb_dirBase() + cFile + ".ini" IF ! hb_fileExists( cFile ) CreateMyIniFile( cFile ) ENDIF aFile1 := RestoreFromIni( cFile, "FILES" , "MyFile1", @nErrCode ) IF nErrCode == INIFILE_RESTORE_OK IF hb_isArray( aFile1 ) FOR EACH e IN aFile1 QOut(e) NEXT ENDIF ENDIF nErrCode := 0 aFile2 := RestoreFromIni( cFile, "FILES" , "MyFile2", @nErrCode ) IF nErrCode == INIFILE_RESTORE_OK IF hb_isArray( aFile2 ) FOR EACH e IN aFile2 QOut(e) NEXT ENDIF ENDIF // RETURN /** */ FUNCTION CreateMyIniFile( cFileName ) LOCAL aFile1 := { "spiski.xls", .T., "обработан", 20, NIL } LOCAL aFile2 := { "centr.xls", .F., "не обработан", 12, NIL } LOCAL nResult nResult := SaveToIni( aFile1, cFileName, "FILES" , "MyFile1", .f. ) IF nResult <> INIFILE_SAVE_OK RETURN .f. ENDIF nResult := SaveToIni( aFile2, cFileName, "FILES" , "MyFile2", .t. ) IF nResult <> INIFILE_SAVE_OK RETURN .f. ENDIF // RETURN .t. /** */ FUNCTION SaveToIni( aFile, cIniName, cSectionName, cKeyName, lExists ) LOCAL hIni, cString /* проверка на существование файла */ IF ! hb_fileExists( cIniName ) IF lExists RETURN INIFILE_NOT_EXISTS ENDIF hIni := hb_Hash() hIni[ cSectionName ] := hb_Hash() ELSE hIni := hb_IniRead( cIniName ) ENDIF /* существующий .ini файл имеет правильный формат? */ IF Empty( hIni ) RETURN INIFILE_NOT_VALID //Not a valid .ini file! ENDIF /* проверка на существование в файле нужной секции если ее нет, то создаем; если что-то есть, то должна быть обязательно секция, не ключ */ IF ! hb_hHasKey( hIni, cSectionName ) hIni[ cSectionName ] := hb_Hash() ELSEIF ! hb_isHash( hIni[ cSectionName ] ) RETURN INIFILE_SECTION_NOT_VALID ENDIF /* поскольку hb_serialize может возвратить непечатаемые символы, применяем к записываемой строке base64 кодирование */ cString := hb_serialize( @aFile ) hIni[ cSectionName ][ cKeyName ] := hb_base64encode( cString ) // наконец добрались до записи в файл IF ! hb_IniWrite( cIniName, hIni, "#Generated file; don't touch", "#End of file") RETURN INIFILE_CANNOT_WRITE ENDIF RETURN INIFILE_SAVE_OK /** */ FUNCTION RestoreFromIni( cIniName, cSectionName, cKeyName, nErrCode ) LOCAL hIni, hSection LOCAL cString, xResult hIni := hb_IniRead( cIniName ) /* нет файла или неправильный формат */ IF Empty( hIni ) IF PCount() > 3 nErrCode := INIFILE_NOT_VALID ENDIF RETURN Nil ENDIF /* нет подходящей секции */ IF ! hb_hHasKey( hIni, cSectionName ) IF PCount() > 3 nErrCode := INIFILE_SECTION_NOT_VALID ENDIF RETURN Nil ENDIF hSection := hIni[ cSectionName ] IF ! hb_isHash( hSection ) IF PCount() > 3 nErrCode := INIFILE_SECTION_NOT_VALID ENDIF RETURN NIL ENDIF // нет ключа IF ! hb_hHasKey( hSection, cKeyName ) IF PCount() > 3 nErrCode := INIFILE_KEY_NOT_VALID ENDIF RETURN Nil ENDIF /* читаем и обработываем строку; здесь можно/нужно(?) проводить дополнительные проверки */ cString := hSection[ cKeyName ] cString += ( Repl( "=", 4 - Len( cString ) % 4 ) ) cString := hb_base64decode( cString ) IF ! Empty( cString ) xResult := hb_deserialize( @cString ) nErrCode := INIFILE_RESTORE_OK ENDIF // RETURN xResult[/pre2]


SADSTAR2: пример из передачи описания объекта через Клипборд записываешь массив в текст в таком же виде как при написании программы живой пример {7,"GRID","GRID_1",{{"ALLOWEDIT","L",".F.",.T.,.F.},{"BACKCOLOR","AC","Nil",.F.,.T.,1},{"BREAK","L",".F.",.T.,.F.},{"COL","N","10",.T.,.T.,1},{"COLUMNCONTROLS","AT","Nil",.T.,.F.},{"COLUMNVALID","AT","Nil",.T.,.F.},{"COLUMNWHEN","AT","Nil",.T.,.F.},{"DYNAMICBACKCOLOR","C","Nil",.F.,.F.},{"DYNAMICFORECOLOR","C","Nil",.F.,.F.},{"FONTBOLD","L",".F.",.T.,.T.,1},{"FONTCOLOR","AC","Nil",.F.,.T.,1},{"FONTITALIC","L",".F.",.T.,.T.,1},{"FONTNAME","C","Arial",.T.,.T.,1},{"FONTSIZE","N","10",.T.,.T.,1},{"FONTSTRIKEOUT","L",".F.",.T.,.T.,1},{"FONTUNDERLINE","L",".F.",.T.,.T.,1},{"HEADERS","AT",'{"Type","Qty","Last key with this DataType"}',.T.,.F.},{"HEIGHT","N","280",.T.,.T.,1},{"HELPID","N","Nil",.T.,.F.},{"IMAGE","AT","Nil",.T.,.F.},{"INPLACEEDIT","AM","{}",.T.,.F.},{"ITEMCOUNT","N","Nil",.T.,.T.,1},{"ITEMS","AM",'{{"Row1Col1","Row1Col2", "33"}}',.T.,.F.},{"JUSTIFY","AN","{,1,}",.T.,.T.,2},{"MULTISELECT","L",".F.",.T.,.T.,2},{"NOLINES","L",".F.",.T.,.T.,2},{"ONCHANGE","E","Nil",.T.,.F.},{"ONDBLCLICK","E","Nil",.T.,.F.},{"ONGOTFOCUS","E","Nil",.T.,.F.},{"ONHEADCLICK","C","Nil",.T.,.F.},{"ONLOSTFOCUS","E","Nil",.T.,.F.},{"ONQUERYDATA","E","Nil",.T.,.F.},{"ROW","N","110",.T.,.T.,1},{"SHOWHEADERS","L",".T.",.T.,.T.,1},{"TOOLTIP","C","Nil",.T.,.F.},{"VALUE","N","Nil",.T.,.F.},{"VIRTUAL","L",".F.",.T.,.T.,1},{"WIDTH","N","750",.T.,.T.,1},{"WIDTHS","AN","{140,70,500}",.T.,.F.}},{110,10,390,760}} потом восстанавливаешь как показано ранее если записать этот текст в ИНИ-файл в одну строку в значение какого либо ключа то при чтении будет прочитано все от знака "=" до конца строки

Andrey: Петр пишет: Я укажу вам Истинный путь Что-то не работает..... Error BASE/1132 Переполнение массива: Неверное количество аргументов Called from HB_INIWRITE(0) Called from SAVETOINI(111) Called from CREATEMYINIFILE(63) Called from MAIN(32) Вываливается на строчке: IF ! hb_IniWrite( cIniName, hIni, "#Generated file; don't touch", "#End of file") Боюсь править, т.к. хочется увидеть правильный код МАСТЕРА !

Петр: Andrey пишет: Error BASE/1132 Переполнение массива: Неверное количество аргументов Called from HB_INIWRITE(0) Called from SAVETOINI(111) Called from CREATEMYINIFILE(63) Called from MAIN(32) Код работает исправно - только что скопи-пастил откомпилировал-запустил - никаких ошибок (Harbour SVN) Andrey пишет: Боюсь править, т.к. хочется увидеть правильный код МАСТЕРА ! Не бойтесь А правильный - не правильный : у меня работает. Теперь относительно Пути Воина и Истинного пути. MiniGUI использует собственные функции для работы с ini файлами. В основе их лежит использование WinAPI, а не встроенные функции языка для работы с конфигурационными файлами (Это не Путь Воина ). Смешивать эти два подхода я никому не рекомендую, во избежание ошибок. Так что выбор "Истинного пути" (если он конечно есть) всегда остается за вами

SADSTAR2: Может я не понял проблемы, но по моему все делается проще Пример. Мои отступы 1 табуляция = 4 пробела. ----Proba01.prg----------------------------- [pre2]#include <minigui.ch> Procedure Main private aFiles:={{ "spiski.xls", .T., "обработан ", 20, NIL },; { "centr.xls", .F., "не обработан", 12, NIL }} private aRest:={} private cIniFile:=GetExeFileName() cIniFile:=substr(cIniFile,1,rAt('.',cIniFile))+'ini' Load Window wForm_1 wForm_1.EditBox_1.Value:="" wForm_1.Center wForm_1.Activate Return //------------------------------------------ function SaveIni() local n, i, j, s:='', t //открыть ИНИ-файл if 0#_BeginIni( cIniFile ); return Nil; endif //перегнать массив в текстовые строки и записать for i:=1 to len(aFiles) s:='{' for j:=1 to len(aFiles[ i ]) t:=aFiles[i,j] if ValType(t)='C' s:=s+'"'+t+'",' elseif ValType(t)='L' s:=s+if(t,'.T.','.F.')+',' elseif ValType(t)='N' s:=s+alltrim(str(t))+',' elseif ValType(t)='U' s:=s+'NIL,' endif next if(right(s,1)=','); s:=left(s,len(s)-1); endif s:=s+'}' //записать if !(_SetIni( 'FileList', 'File_'+strzero(i,3,0), s)) MsgExclamation('Ошибка записи в ИНИ-файл'+HB_OsNewLine()+; 'файл:<'+cIniFile+'>'+HB_OsNewLine()+; s) endif next _EndIni() msgbox('готово') return Nil //------------------------------------------ function RestIni() local n, i, j, s:='', t //получить секцию aR:=_GetSection( 'FileList', cIniFile ) if len(aR)=0; return Nil; endif //восстановить массив for i:=1 to len(aR) t:=aR[i,2] aAdd(aRest,&(t)) next //показать wForm_1.EditBox_1.Value:='' for i:=1 to len(aRest) for j:=1 to len(aRest[ i ]) t:='aRest['+str(i,3)+']['+str(j,2)+']=' if ValType(aRest[i,j])='C' t:=t+aRest[i,j] elseif ValType(aRest[i,j])='L' t:=t+if(aRest[i,j],'.T.','.F.') elseif ValType(aRest[i,j])='N' t:=t+alltrim(str(aRest[i,j])) elseif ValType(aRest[i,j])='U' t:=t+'Nil' endif wForm_1.EditBox_1.Value:=wForm_1.EditBox_1.Value+t+HB_OsNewLine() next next msgbox('готово') return Nil //=========================================================== -----wForm_1.fmg------------------------------------------- DEFINE WINDOW TEMPLATE AT 171,371 HEIGHT 415 WIDTH 648 TITLE "Array to Ini test" MAIN FONT "Arial" SIZE 9 DEFINE EDITBOX EDITBOX_1 COL 20 ROW 50 WIDTH 600 HEIGHT 320 VALUE "New EditBox" READONLY .F. FONTNAME "Arial" FONTSIZE 10 FONTBOLD .F. FONTITALIC .F. FONTUNDERLINE .F. FONTSTRIKEOUT .F. TOOLTIP Nil BACKCOLOR Nil FONTCOLOR Nil MAXLENGTH Nil ONGOTFOCUS Nil ONCHANGE Nil ONLOSTFOCUS Nil HELPID Nil VISIBLE .T. TABSTOP .T. NOVSCROLLBAR .F. NOHSCROLLBAR .F. END EDITBOX DEFINE BUTTON BUTTON_1 COL 20 ROW 10 WIDTH 130 HEIGHT 30 CAPTION "Сохранить в ИНИ" PICTURE Nil ICON Nil ACTION SaveIni() FONTNAME "Arial" FONTSIZE 10 FONTBOLD .F. FONTITALIC .F. FONTUNDERLINE .F. FONTSTRIKEOUT .F. FONTCOLOR Nil ONGOTFOCUS Nil ONLOSTFOCUS Nil HELPID Nil FLAT .F. TABSTOP .T. TRANSPARENT .F. TOOLTIP Nil VISIBLE .T. DEFAULT .F. END BUTTON DEFINE BUTTON BUTTON_2 COL 190 ROW 10 WIDTH 140 HEIGHT 30 CAPTION "Восстановить из ИНИ" PICTURE Nil ICON Nil ACTION RestIni() FONTNAME "Arial" FONTSIZE 10 FONTBOLD .F. FONTITALIC .F. FONTUNDERLINE .F. FONTSTRIKEOUT .F. FONTCOLOR Nil ONGOTFOCUS Nil ONLOSTFOCUS Nil HELPID Nil FLAT .F. TABSTOP .T. TRANSPARENT .F. TOOLTIP Nil VISIBLE .T. DEFAULT .F. END BUTTON END WINDOW[/pre2] ------------------------------------------------------ замечу Преобразование массива в текст здесь сделано для частного случая. У меня есть функция для более общего случая. Т.е. -массив любой ветвистости -символьные данные правильно сохраняются с любой комбинацией кавычек внутри если есть нужда - могу поделиться

SADSTAR2: вдруг обнаружил что кто-то восстановил табуляции (правда у меня в редакторе 1таб=4пробела) и что сообщения можно редактировать. Исправил предыдущее и заменил это. я правильно сделал?

SkyNET:

Петр: Мдя ...

Andrey: Разбирался с хХарборовскими функциями работы с ИНИ-файлами... Там вроде удобней. Но так как пишу прогу на МиниГуи, то нужно использовать Гуевые... Как можно проверить, есть ли такая СЕКЦИЯ и есть ли такая ПЕРЕМЕННАЯ ? В хэлпе что-то мало всего.... в хХарборе больше....

Andrey: Что-то наверно затерялась моя просьба.... Как можно проверить на МиниГуи, есть ли такая СЕКЦИЯ и есть ли такая ПЕРЕМЕННАЯ в ИНИ-файле ? В хелпе вообще ничего толком нет...

sergey5703: Может быть вместо INI-файла записывать массив в MEMO-поле dbf-файла? В HwGUI есть две функции для этого: ARRAY2STRING и STRING2ARRAY. Библиотека PROCMISC.LIB.

wad1: MEMO-поля не самый надежный инструмент: периодически бывает сбой ссылок при сжатии таблиц. В своих проектах от MEMO отказались после серии потерь данных. С INI-файлами тоже не все гладко. Периодически они рушатся из-за некорректного завершения программ (для изменения одной строки нужно ведь переписать весь файл). На сегодняшний день считаю лучшим выходом для хранения настроек DBF-файл. Структура примерно такая: {{'K_PART','N',3,0}, {'K_VAR','N',4,0}, {'NAME','C',15,0}, {'RNAME','C',50,0},{'TYPE','C',1,0},{'LEN_VAR','N',3,0},{'LEN_DEC','N',1,0},; {'VAR',C,1000},{'K_HELP','N',5,0}} Поиск переменных с помощью индекса происходит быстро. Одновременное изменение с разных станций разруливается блокировками. Написаны две функции: READ_VAR() n PUT_VAR(), которые приводят переменные к нужному виду перед записью (в строку) и обратно. Доступ к настройкам выполняется в специальном режиме, чтобы абы кто не испортил. Использую несколько лет, и очень доволен.

Andrey: sergey5703 пишет: В HwGUI есть две функции для этого wad1 пишет: С INI-файлами тоже не все гладко Вы чего ? Совсем запраздновались .... Я конкретно спрашиваю: Как можно проверить на МиниГуи, есть ли такая СЕКЦИЯ и есть ли такая ПЕРЕМЕННАЯ в ИНИ-файле ? А что лучше, и хуже не надо обсуждать... Вот мне не нравиться хранить настройки в DBF-файле. Непрактично ! У меня свои взгляды на это. У меня 600Кб ини-файл занимает и все поля, меню, печать, блоки кода,... все в ини-файле. А тут я спрашиваю про функции работы с ини-файлами через МиниГуи ! И все, никаких гвоздей !

wad1: Andrey пишет: Вот мне не нравиться Мягкий знак тут не нужен. И еще: тут вообще ничего нельзя обсуждать?

Dima: wad1 пишет: И еще: тут вообще ничего нельзя обсуждать? Можно и нужно !

PSP: Петр пишет: MiniGUI использует собственные функции для работы с ini файлами. В основе их лежит использование WinAPI, а не встроенные функции языка для работы с конфигурационными файлами Андрей! Думаю, это означает, что средствами MiniGUI твою задачу (массивы в ini) не решить. Можно использовать те функции, которые Петр в начале темы привел. Найди сообщение со словами: "Я укажу вам Истинный путь." :)

krutoff: А может просто использовать функции перевода массива в строку с разделителями (AtoC) и потом назад CtoA() //--------------------------------------------------------------------------// // creates a list string with or without separators from an array // It's part of my personal Udf's collection. // It's not used by Debug.prg but I incude it as a complement of CtoA function Static Function AtoC( aArr, cType, cSep ) Local nEle := 1, ; cStr := '' Default cType := ValType( aArr[ 1 ] ), ; cSep := "|" If ValType( cSep ) != "N" For nEle := 1 To Len( aArr ) cType := ValType(aArr[nEle]) If cType == "D" cStr += ( DtoC( aArr[ nEle ] ) + cSep ) ElseIf cType == "N" cStr += ( LTStr( aArr[ nEle ] ) + cSep ) ElseIf cType == "L" cStr += ( If( aArr[ nEle ], "T", "F" ) + cSep ) ElseIf cType == "A" // "A" means Ascii (not Array) // cStr += ( Chr( aArr[ nEle ] ) + cSep ) cStr += ( AtoC(aArr[nEle], ,cSep) + cSep ) Else //fdebug('AtoC','nEle,aArr,Type',{nEle,aArr[ nEle ],cType},7) cStr += ( iif(aArr[nEle]=NIL,'NIL',aArr[nEle]) + cSep ) EndIf Next Else // numeric "cSep" means fixed lenght elements with no separators For nEle := 1 To Len( aArr ) If cType == "D" cStr += DtoS( aArr[ nEle ] ) ElseIf cType == "N" cStr += Str( aArr[ nEle ], cSep ) ElseIf cType == "L" cStr += If( aArr[ nEle ], "1", "0" ) ElseIf cType == "B" .and. cSep == 2 // "B" means Binary (not Block) cStr += I2Bin( aArr[ nEle ] ) ElseIf cType == "B" .and. cSep == 4 cStr += L2Bin( aArr[ nEle ] ) ElseIf cType == "B" .and. cSep == 8 cStr += L2Bin( aArr[ nEle ] ) Else cStr += PadR( aArr[ nEle ], cSep ) EndIf Next EndIf Return cStr //--------------------------------------------------------------------------- //--------------------------------------------------------------------------// // creates an array from a string with or without separators // It's part of my personal Udf's collection. Static Function CtoA( cString, cType, cSeparator, bBlock ) Local cToken, nEle, lNum, ; aArr := {} Default cSeparator := "|", ; cType := "C" If ValType( cSeparator ) != "N" .and. cSeparator >= Chr( 32 ) nEle := 1 While ! Empty( cToken := ExtractWord( nEle++, cString, {cSeparator} )) If cType == "N" AAdd( aArr, Val( cToken ) ) ElseIf cType == "D" AAdd( aArr, CtoD( cToken ) ) ElseIf cType == "L" AAdd( aArr, "T" $ cToken ) ElseIf cType == "B" AAdd( aArr, EVAL( cToken ) ) Else AAdd( aArr, cToken ) EndIf EndDo Else nEle := 1 lNum := ValType( cSeparator ) == "N" While nEle <= Len( cString ) Do Case Case cType == "N" .and. lNum AAdd( aArr, Val( SubStr( cString, nEle, cSeparator ) ) ) nEle += cSeparator Case cType == "N" .and. ! lNum .and. cSeparator == "" AAdd( aArr, Val( SubStr( cString, nEle++, 1 ) ) ) Case cType == "B" .and. lNum .and. cSeparator == 2 // "B" means Binary (not Block) AAdd( aArr, Bin2I( SubStr( cString, nEle, cSeparator ) ) ) nEle += cSeparator Case cType == "B" .and. lNum .and. cSeparator == 4 AAdd( aArr, Bin2L( SubStr( cString, nEle, cSeparator ) ) ) nEle += cSeparator Case cType == "B" .and. lNum .and. cSeparator == 8 AAdd( aArr, Bin2L( SubStr( cString, nEle, cSeparator ) ) ) nEle += cSeparator Case cType == "C" .and. lNum AAdd( aArr, SubStr( cString, nEle, cSeparator ) ) nEle += cSeparator Case cType == "D" .and. lNum AAdd( aArr, StoD( SubStr( cString, nEle, 8 ) ) ) nEle += 8 Case cType == "D" .and. ! lNum .and. cSeparator == "" AAdd( aArr, CtoD( SubStr( cString, nEle, 8 ) ) ) nEle += 8 Case cType == "L" AAdd( aArr, SubStr( cString, nEle++, 1 ) $ "T1" ) Case cType == "A" // "A" means Ascii (not Array) AAdd( aArr, Asc( SubStr( cString, nEle++, 1 ) ) ) OtherWise AAdd( aArr, SubStr( cString, nEle++, 1 ) ) EndCase EndDo EndIf If bBlock != Nil For nEle := 1 To Len( aArr ) aArr[ nEle ] := Eval( bBlock, aArr[ nEle ] ) Next EndIf Return aArr

Andrey: PSP пишет: Думаю, это означает, что средствами MiniGUI твою задачу (массивы в ini) не решить. Народ !!! Вы все запраздновались .... Не нужно мне писать массив, с этим разобрались. Пишу последний конкретный вопрос: Как можно проверить на МиниГуи, есть ли такая СЕКЦИЯ и есть ли такая ПЕРЕМЕННАЯ в ИНИ-файле ?



полная версия страницы