C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
PopupMenu1 считываем меню с ini файла
Riva
Отправлено: 20.02.2007, 16:03


Ученик-кочегар

Группа: Участник
Сообщений: 14



Подскажите, как считать меню с ini файла?
Termi_uc
Отправлено: 20.02.2007, 16:44


Дежурный стрелочник

Группа: Участник
Сообщений: 61



Точно тагже, как и обычно, когда что-то читаеш из ini
Пример:
CODE
       TIniFile* Ini = new TIniFile(IniName);
//        eServer->Text = Ini->ReadString("LOGIN", "server", "oracle");
       eServer->Text = Ini->ReadString("connection", "service", "oracle");
       delete Ini;


Но если тебе нужно сохранять меню со ссылками на события, и вообще, для культурного сохранения VCL объектов используй классы TWriter и TReader.
Пример прислать?
Riva
Отправлено: 20.02.2007, 18:27


Ученик-кочегар

Группа: Участник
Сообщений: 14



Если можна, то пришли
Termi_uc
  Отправлено: 20.02.2007, 19:28


Дежурный стрелочник

Группа: Участник
Сообщений: 61



В файле About.txt всё описывается.
Когда запустиш проект, выбери "Загрузить Edit" и открой файл EDIT.rrr.

Если хочеш сохранять в файл много компонентов, то записывать надо сначало в поток, потом в файл (один из вариантов). А когда читать будеш, надо разные компоненты различать.
Где-то была функция специальная, поищу... rolleyes.gif
Termi_uc
Отправлено: 20.02.2007, 19:29


Дежурный стрелочник

Группа: Участник
Сообщений: 61



Тьфу блин...

Вот

Отредактировано Termi_uc — 20.02.2007, 19:29

User Attached Image Скачать файл
Save_Load_Components.zip


Riva
Отправлено: 21.02.2007, 16:44


Ученик-кочегар

Группа: Участник
Сообщений: 14



Что-то не по верному пути пошли.

Всё равно ошибки

TIniFile *ini;
ini = new TIniFile(
ChangeFileExt( Application->ExeName, ".ini" ) );
ini->ReadSections(ListBox1->Items);
for( int i = 0; i < ListBox1->Items; i++ ) // Cannot convert 'int' to 'TStrings *'
{
PopupMenu1->Items->Add(new TMenuItem(ListBox1->Items[i])); // Could not find a match for 'TMenuItem::TMenuItem(TStrings)'
}
delete ini;
Termi_uc
Отправлено: 21.02.2007, 18:21


Дежурный стрелочник

Группа: Участник
Сообщений: 61



У тебя ошибки чисто в правописании
Вместо ListBox1->Items пиши ListBox1->Items->Count

Вместо
CODE
PopupMenu1->Items->Add(new TMenuItem(ListBox1->Items[i]));

CODE
TMenuItem * mi = new TMenuItem(PopupMenu1);
mi->Caption = "saDF";
PopupMenu1->Items->Add(mi);
Riva
Отправлено: 22.02.2007, 14:39


Ученик-кочегар

Группа: Участник
Сообщений: 14



Значит что у меня получилось, из файла .ini считываются данные в StringGrid1, затем эти данные из StringGrid1 должны помещатся в PopupMenu1 а этого как раз и не происходит

CODE

for (unsigned int z=0; z<StringGrid1->RowCount; z++)
 {if(StringGrid1->Cells[0][z+1]=="")
 {
 TIniFile *ini;
    ini = new TIniFile(
    ChangeFileExt( Application->ExeName, ".ini" ) );
    StringGrid1->Cells[0][z+1]=ini->ReadString ( "Topics", z+1, "" );
 delete ini;
 }}
for( int z=0; z<StringGrid1->RowCount; z++ )
{
TMenuItem *menuItem;
menuItem = new TMenuItem(PopupMenu);
menuItem->Caption = StringGrid1->Cells[0][z+1];
PopupMenu1->Items->Add(menuItem);
delete menuItem;


Или вот таже самое только на основе ListBox1

CODE

      TIniFile *ini;
           ini = new TIniFile(
           ChangeFileExt( Application->ExeName, ".ini" ) );
           ini->ReadSectionValues("Topics", ListBox1->Items);
 delete ini;
      for( int i = 0; i < ListBox1->Items->Count; i++ )
    {
      TMenuItem *menuItem;
      menuItem = new TMenuItem(PopupMenu);
      menuItem->Caption = ListBox1->Items->Strings[i];
      PopupMenu1->Items->Add(menuItem);
      delete menuItem;
         }


Тоесть первая часть считывает из файла нормально, а вторая в меню не добавляет! Что не правильно? Или может напрямую как то считать файл в меню без промежуточных компонентов StringGrid или ListBox?
Riva
Отправлено: 22.02.2007, 16:35


Ученик-кочегар

Группа: Участник
Сообщений: 14



Ух разобрался, это вообще лишняя строка

delete menuItem;
Riva
Отправлено: 22.02.2007, 16:41


Ученик-кочегар

Группа: Участник
Сообщений: 14



Ещё два маленьких вопросика:

1. У меня задано StringGrid1->RowCount=20; (Количество строк в StringGrid). А как получить это значение с самого .INI сколько там реально этих строк?

2. После формирования меню, все пункты с .INI добавляются в конец уже существующего меню, а как поместить их в начало, т.е. в верхнюю часть?

CODE

 StringGrid1->Canvas->Font->Style << fsBold;
 StringGrid1->Cells[0][0]="Раздел";
 for (unsigned int z=0; z<StringGrid1->RowCount; z++)
 {if(StringGrid1->Cells[0][z+1]=="")
 {
 TIniFile *ini;
    ini = new TIniFile(
    ChangeFileExt( Application->ExeName, ".ini" ) );
    StringGrid1->Cells[0][z+1]=ini->ReadString ( "Topics", z+1, "" );
   delete ini;
 }}
for( int z=0; z<StringGrid1->RowCount; z++ )
{
TMenuItem *menuItem;
menuItem = new TMenuItem(PopupMenu);
menuItem->Caption = StringGrid1->Cells[0][z+1];
StringGrid1->RowCount=20;
PopupMenu1->Items->Add(menuItem);
 }
Termi_uc
Отправлено: 22.02.2007, 20:15


Дежурный стрелочник

Группа: Участник
Сообщений: 61



QUOTE (Riva @ 22.02.2007, 14:39)
Или может напрямую как то считать файл в меню без промежуточных компонентов StringGrid или ListBox?

Можно.
Пользуй TStringList * StringList = new TStringList(this);

QUOTE
2. После формирования меню, все пункты с .INI добавляются в конец уже существующего меню, а как поместить их в начало, т.е. в верхнюю часть?

PopupMenu1->Items->Insert(0, menuItem);
Riva
Отправлено: 22.02.2007, 22:15


Ученик-кочегар

Группа: Участник
Сообщений: 14



Termi_uc ты просто чародей!!! Респект, ты уже не впервой мне помогаешь

PopupMenu1->Items->Insert(0, menuItem);  — РАБОТАЕТ СУПЕР

Но есть одно но, список в меню считывается в обратном порядке.

В файле так:
----------------
[Topics]
1=Значение1
2=Значение2
...
N=ЗначениеN

В меню так:
---------------
ЗначениеN
...
Значение2
Значение1
Termi_uc
Отправлено: 25.02.2007, 16:04


Дежурный стрелочник

Группа: Участник
Сообщений: 61



Riva извени, что заставил ждать. Выходные большие, а инет у меня только на работе. Вот от брата вышел и решил темы просмотреть.

QUOTE
Но есть одно но, список в меню считывается в обратном порядке.

По-моему так:
PopupMenu1->Items->Insert(PopupMenu1->Items->Count — N, menuItem);
где N — номер считываемой строки.

Впринципе разобратся во всём этом не сложно, просто вызываеш список функций и свойств для компонента, и ищеж подходящий по смыслу. Но я уверен ты уже сам разобрался. Если будут вопросы — зайду в понедельник, после 14:00.

Да кстати, если не PopupMenu1->Items->Count, то PopupMenu1->Items->Items->Count. Т.к. у некоторых компонентов свойство Items двойное. Проверить не могу — Builder тоже на работе.
Riva
Отправлено: 26.02.2007, 00:00


Ученик-кочегар

Группа: Участник
Сообщений: 14



Супер, ты Гений. Тема закрыта

Отредактировано Riva — 26.02.2007, 00:00
Riva
Отправлено: 26.02.2007, 02:05


Ученик-кочегар

Группа: Участник
Сообщений: 14



О забыл про второй вопрос,

У меня задано StringGrid1->RowCount=20; (Количество строк в StringGrid). А как получить это значение с самого .INI сколько там реально этих строк?
Termi_uc
  Отправлено: 26.02.2007, 17:03


Дежурный стрелочник

Группа: Участник
Сообщений: 61



А это братец кролик, возложено на плечи програмиста...
Примерно так:

1. Перебираеш имена типа так. Имя = Преффикс + Номер
2. В цикле инкрементируеш Номер и ищеш в INI полученное Имя.
3. Если Имя типа ПреффиксНомер не найдено в INI, то цикл прерывается и ты нашел все пункты меню.
Стоит заметить, что пункты менб в INI должны распологатся в специальной секции и представлять собой массив:
Преффикс1
Преффикс2
...
ПреффиксN.
Вроде всё.


Ещё раз выражаю своё недоумение, по поводу того, что ты не используеш для твоей цели класс TStringList и методы SaveToFile и LoadFromFile?
Хотя, всё зависит от поставленно задачи...
Кстати используй TStringList вместо TStringGrid, т.к. применительно к конкретной задачи тебе не нужен компонент с окном.
xTrim
Отправлено: 26.02.2007, 21:21


Машинист паровоза

Группа: Участник
Сообщений: 208



Немного уточню. Можно сделать ini->ReadSection("Topics", someStingList) и получить в someStingList список и количество всех ключей в данной секции.

Вернуться в Вопросы программирования в C++Builder