如何在MDI应用程序中合并两个菜单

时间:2010-05-27 20:25:25

标签: delphi delphi-7

任何人都知道如何在MDI应用程序中合并两个具有相同名称的菜单。

更确切地说,在MDI主窗体中,我有一个名为'File'的菜单,它有一个名为'Load project'的子菜单。 在MDI子窗体中,我有一个名为'File'的菜单,其中包含一个名为'Save project'的子菜单。

如何强制我的应用程序在“文件”菜单下显示“加载”和“保存”子菜单?

-

PS:设置相同的GoupIndex值将不起作用。

2 个答案:

答案 0 :(得分:1)

手动合并是调用FormMain.MainMenu.Merge(SubForm.MainMenu)及其对应的FormMain.MainMenu.UnMerge(SubForm.MainMenu)。

你不应该需要它,因为如果你的表单的FormStyles被正确设置为fsMDIForm和fsMDIChild,那么菜单合并应该是自动的。

话虽如此,我不确定使用内置菜单合并你想要什么。

根据GroupIndex帮助(以及一些实验),来自子项的菜单项在主窗体上使用相同的GroupIndex形成替换项。仅当子窗体上的菜单项的GroupIndex落在主窗体上的GroupIndex值之间时,才会插入菜单。因此,子窗体上的“文件”菜单将始终替换主窗体上的“文件”菜单。只有当你给File菜单的不同GroupIndex值时,Main表单的File菜单才会保留,但是你有两个File菜单...

因此,我认为唯一的解决方案是手动插入和删除子窗体的菜单项,或者始终将它们放在主菜单上,并根据活动的MDIChild启用/禁用它们。甚至可能显示/隐藏它们。

就我个人而言,我会选择让它们随时使用并根据活动的MDIChild启用/禁用它们,因为我不喜欢“反弹”的菜单项(更改位置)。

答案 1 :(得分:1)

要合并菜单,请使用以下步骤:

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;

在MDIChildForm的OnCreate事件中调用它,如下所示:

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

如果两个不同的MainMenus具有相同名称的MenuItem,它将起作用。另请注意,如果您的DstMenu没有所有者(但我猜它有,并且它是您的MDICHildForm),可能会有内存韭菜。