Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.07.2014, 14:29   #1
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
Сообщение Создание меню опираясь на ini

Доброго времени суток! Создаю меню, опираясь на данные INI-файла
Код:
...
type
  TExtensionsArray = record
    sFile: string;
    sPath: string;
    Hash: string;
    iMenuItem: Integer;
    MenuItemCaption: string;
    iSubMenuItem: Integer;
    SubMenuItemCaption: string;
  end;

var
  FormMain: TFormMain;
  ExtensionsArray: array of TExtensionsArray;
...
procedure TFormMain.FormCreate(Sender: TObject);
var
  SL: TStringList;
  INIFile: TINIFile;
  i, i2: Integer;
  Item: TMenuItem;
begin
  SL := TStringList.Create;
  INIFile := TINIFile.Create(ExtractFilePath(Application.ExeName) + ExtensionsFile);
  INIFile.ReadSections(SL);

  SetLength(ExtensionsArray, 0);

  for i := 0 to SL.Count - 1 do
  begin
    i2 := High(ExtensionsArray) + 2;
    SetLength(ExtensionsArray, i2);
    ExtensionsArray[i2 - 1].sFile := SL.Strings[i];
    ExtensionsArray[i2 - 1].sPath := INIFile.ReadString(SL[i], 'Path', '');
    ExtensionsArray[i2 - 1].Hash := INIFile.ReadString(SL[i], 'Hash', '');
    ExtensionsArray[i2 - 1].iMenuItem := INIFile.ReadInteger(SL[i], 'MenuItem', 0);
    ExtensionsArray[i2 - 1].MenuItemCaption := INIFile.ReadString(SL[i], 'MenuItemCaption', '');
    ExtensionsArray[i2 - 1].iSubMenuItem := INIFile.ReadInteger(SL[i], 'SubMenuItem', 0);
    ExtensionsArray[i2 - 1].SubMenuItemCaption := INIFile.ReadString(SL[i], 'SubMenuItemCaption', '');
  end;

  FreeAndNil(SL);
  FreeAndNil(INIFile);

  for i := 0 to Length(ExtensionsArray) - 1 do
  begin
    // Добавление Item
    Item := TMenuItem.Create(Self); // Создаём новый Item
    Item.Caption := ExtensionsArray[i].MenuItemCaption; // Задаём описание Item
    Item.ImageIndex := 3; // Присваиваем картинку Item
    if ExtensionsArray[i].SubMenuItemCaption = '' then Item.OnClick := MyClick; // Назначаем процедуру Item
    MainMenu.Items[ExtensionsArray[i].iMenuItem].Add(Item); // Добавляем Item
    // Добавление SubItem
    if ExtensionsArray[i].SubMenuItemCaption <> '' then
    begin
      Item := TMenuItem.Create(Self); // Создаём новый Item
      Item.Caption := ExtensionsArray[i].SubMenuItemCaption; // Задаём описание Item
      Item.ImageIndex := 3; // Присваиваем картинку Item
      Item.OnClick := MyClick; // Назначаем процедуру Item
      MainMenu.Items[ExtensionsArray[i].iMenuItem].Items[ExtensionsArray[i].iSubMenuItem].Add(Item); // Добавляем Item
    end;
  end;
end;
PHP код:
[1.bat]
Path=1\
Hash=
MenuItem=2
MenuItemCaption
=Общее
SubMenuItem
=0
SubMenuItemCaption
=Общее 100
[2.bat]
Path=2\
Hash=
MenuItem=2
MenuItemCaption
=Система
SubMenuItem
=1
SubMenuItemCaption
=Система 200
[3.bat]
Path=3\
Hash=
MenuItem=2
MenuItemCaption
=Система
SubMenuItem
=1
SubMenuItemCaption
=Система 300
[4.bat]
Path=4\
Hash=
MenuItem=2
MenuItemCaption
=Разное
SubMenuItem
=
SubMenuItemCaption
Получаю эффект дублеката пунктов меню, если для одного пункта меню имеется несколько подпунктов.
Как избежать этого эффекта?
Изображения
Тип файла: png Untitled-2.png (11.9 Кб, 56 просмотров)
Shouldercannon вне форума Ответить с цитированием
Старый 28.07.2014, 14:54   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Мне кажется что лучше делать не так.
Я бы сделал так:
Код:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses  inifiles,
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus;

type

  { TForm1 }

  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var i:TIniFile;

 procedure addmenu(section:String;mitm:TMenuItem);
 var st:TStringList;  j:integer; itm:TMenuItem;
 begin
   st:=TStringList.Create;
    i.ReadSectionValues(section,st);
    //if mitm=nil then mitm;
    for j:=0 to st.Count-1 do begin
      itm:=TMenuItem.Create(mitm);
      itm.Caption:=st.ValueFromIndex[j];
      if mitm=nil then MainMenu1.Items.Add(itm)
      else mitm.Add(itm);
      addmenu(st.ValueFromIndex[j],itm);
    end;
   st.Free;
 end;

begin
  i:=TIniFile.Create(ExtractFilePath(ParamStr(0))+'menu.ini');
   addmenu('main',nil);
  i.free;
end;

end.
И ИНИ файл:
Цитата:
[main]
1=система
2=Разное
[система]
1=подсистема1
2=подсистема=2
[Разное]
1=Разное1
2=Разное2
[Разное1]
1=Разное11
2=Разное12
т.е. подменюшки в отдельные секции с именами родительских элементов.
ИМХО проще будет.

И массив динамический зачем там вообще?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 28.07.2014, 15:01   #3
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,543
По умолчанию

проверять наличие родителя по его идентифицирующим свойствам задаваемым в файле.(Caption ???)
Код:
function FindItem(.....): TMemuItem;
begin
  for j:=0 to 
end;
Код:
for j:=0 to ...
  item:=FindItem(...);
  if item=nil then begin
    item:=TmeniItem.Create....
  end;
  end;
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 28.07.2014, 15:10   #4
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
И массив динамический зачем там вообще?
Массив нужен для поиска выбранного пункта меню и запуска соответствующего файла, найденного по этому пункту
Shouldercannon вне форума Ответить с цитированием
Старый 28.07.2014, 15:20   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Тогда тебе нужен не массив а дерево объектов, которые будут хранить эти параметры, считанные из ИНИ файла.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 28.07.2014, 15:40   #6
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Решение с devshed, хорошие люди функцией поделились
Код:
function TFPrincipal.ProcuraItem(menuG: TMenuItem; str: String): TMenuItem;
var
  j: Integer;
  item,itemAux: TMenuItem;
  teste: String;
begin
  j:=0;

  //first level
  item:= menuG.Find(str);
  if item <> nil then
  begin
      //ShowMessage('find in the first level');
      Result:= item;
      Exit;
  end;

  //sub-levels
  while j < menuG.Count do
  begin

    teste := menuG.Items[j].Caption;

    item:= menuG.Items[j].Find(str);
    if item <> nil then
    begin
      //ShowMessage('find in the midle');
      //ShowMessage(item.Caption);
      Result:= item;
      Exit;
    end;

    itemAux :=  ProcuraItem(menuG.Items[j],str);
    //ShowMessage(item.Caption);
    if itemAux <> nil then
    begin
        Result := itemAux;
        Exit;
    end;
    Inc(j);
  end;

  //if not found, return nil
  Result:= nil;
end;

Последний раз редактировалось Shouldercannon; 28.07.2014 в 15:56.
Shouldercannon вне форума Ответить с цитированием
Старый 28.07.2014, 15:59   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Решение с devshed
Но это поиск а не наполнение...
Или я чегоент непонимайтен?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 28.07.2014, 16:32   #8
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Задача заключалась в недопускании создания дублекатов пунктов меню при моей реализации построения меню
Shouldercannon вне форума Ответить с цитированием
Старый 28.07.2014, 18:50   #9
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

ИМХО, для Меню нужно использовать что-то из разряда сериализации, типа JSON или XML.
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание ini файлов countteran Общие вопросы Delphi 8 15.01.2012 21:24
Vista. Права. Создание INI-файлов BOBAH13 Общие вопросы Delphi 6 24.05.2009 11:04
Создание и считывание .ini файлов Патрон Общие вопросы Delphi 4 21.04.2008 03:25
Создание меню на С KsandR Общие вопросы C/C++ 5 13.12.2007 21:34
Сохранение StringGrid, создание .ini! Nemesisking Общие вопросы Delphi 5 24.09.2007 08:23