Как объединить два меню в приложении MDI - PullRequest
1 голос
/ 28 мая 2010

Кто-нибудь знает, как объединить два меню с одинаковыми именами в приложении MDI.

Точнее говоря, в основной форме MDI у меня есть меню «Файл», в котором есть подменю «Загрузить проект». В дочерней форме MDI у меня также есть меню «Файл», которое содержит подменю «Сохранить проект».

Как заставить мое приложение отображать подменю «Загрузить» и «Сохранить» в меню «Файл»?

-

PS: установка того же значения GoupIndex не будет работать.

Ответы [ 2 ]

1 голос
/ 28 мая 2010

Чтобы объединить ваши меню, используйте следующую процедуру:

procedure MergeMenus(var SrcMenu, DstMenu: TMainMenu);
var
  i, i2, i3: Integer;
  Menu: TMenuItem;
begin
  for i := 0 to SrcMenu.Items.Count - 1 do
  begin
    for i2 := 0 to DstMenu.Items.Count - 1 do
    begin
      if (SrcMenu.Items[i].Name = DstMenu.Items[i2].Name) and
        (SrcMenu.Items[i].Count > 0) and (DstMenu.Items[i].Count > 0) then
      begin
        for i3 := 0 to SrcMenu.Items[i].Count - 1 do
        begin
          Menu := TMenuItem.Create(DstMenu.Owner);
          // copy another properties if necessery
          Menu.Name := SrcMenu.Items[i].Items[i3].Name;
          Menu.Caption := SrcMenu.Items[i].Items[i3].Caption;
          Menu.ShortCut := SrcMenu.Items[i].Items[i3].ShortCut;
          Menu.OnClick := SrcMenu.Items[i].Items[i3].OnClick;
          DstMenu.Items[i].Add(Menu);
        end;
      end;
    end;
  end;
end;

Вызовите его в событии OnCreate вашей MDIChildForm следующим образом:

procedure TMDIChild.FormCreate(Sender: TObject);
begin
  MergeMenus(YourMainForm.MainMenu1, Self.MainMenu1);
end;

Это будет работать, если два разных MainMenus будут иметь MenuItems с одинаковым именем. Также обратите внимание, что возможен обмен данными в памяти, если у вашего DstMenu нет владельца (но я думаю, что он есть, и это ваш MDICHildForm).

1 голос
/ 28 мая 2010

Слияние вручную - это вызов FormMain.MainMenu.Merge (SubForm.MainMenu) и его аналога FormMain.MainMenu.UnMerge (SubForm.MainMenu).

Вам это не нужно, потому что, если для FormStyles ваших форм правильно установлены fsMDIForm и fsMDIChild, объединение меню должно быть автоматическим.

Сказав это, я не уверен, что то, что вы хотите, возможно с помощью встроенного меню слияния.

Согласно справке GroupIndex (и нескольким экспериментам), пункты меню из дочерних форм заменяют пунктов в главной форме тем же GroupIndex. Только когда GroupIndex элемента меню в дочерней форме попадает между значениями GroupIndex в главной форме, меню будет вставлено. Таким образом, меню «Файл» в вашей дочерней форме всегда будет заменять меню «Файл» в основной форме. Только если вы зададите различные значения GroupIndex в меню «Файл», меню «Файл» в главной форме останется, но тогда у вас будет два меню «Файл» ...

Итак, я думаю, что единственным решением было бы вручную вставлять и удалять пункты меню подчиненной формы или постоянно размещать их в главном меню и включать / отключать их в соответствии с активным MDIChild. Возможно даже показать / скрыть их.

Лично я бы предпочел иметь их все время включенными и включать / отключать их в соответствии с активным MDIChild, поскольку мне не нравятся пункты меню, которые "подпрыгивают" (смена позиции).

...