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

Delphi 如何在MDI应用程序中合并两个菜单,delphi,delphi-7,Delphi,Delphi 7,任何人都知道如何在MDI应用程序中合并两个同名菜单 更确切地说,在MDI主窗体中,我有一个名为“文件”的菜单,它有一个名为“加载项目”的子菜单。 在MDI子窗体中,我有一个名为“文件”的菜单,其中包含一个名为“保存项目”的子菜单 如何强制应用程序在“文件”菜单下同时显示“加载”和“保存”子菜单 - PS:设置相同的GoupIndex值将不起作用。手动合并是调用FormMain.MainMenu.Merge(SubForm.MainMenu)及其对应的FormMain.MainMenu.UnMer

任何人都知道如何在MDI应用程序中合并两个同名菜单

更确切地说,在MDI主窗体中,我有一个名为“文件”的菜单,它有一个名为“加载项目”的子菜单。 在MDI子窗体中,我有一个名为“文件”的菜单,其中包含一个名为“保存项目”的子菜单

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

-


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

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

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

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

根据GroupIndex帮助(和两个实验),子表单中的菜单项使用相同的GroupIndex替换主表单中的项。仅当子窗体上菜单项的GroupIndex位于主窗体上的GroupIndex值之间时,才会插入菜单。因此,子窗体上的文件菜单将始终替换主窗体上的文件菜单。只有给文件菜单的不同GroupIndex值时,主窗体的文件菜单才会保留,但此时您有两个文件菜单的

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


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

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

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;

如果两个不同的主菜单具有同名的菜单项,则该功能将正常工作。另外,请注意,如果您的DstMenu没有所有者(但我猜它有所有者,并且它是您的MDICHildForm),则可能存在内存问题。

“子表单中的菜单项使用相同的GroupIndex替换主表单中的项”。所以,从字面上说,Delphi中的菜单合并不能合并菜单。sigh@IanBoyd:事实上,主菜单合并不可能以您直觉上希望的方式进行。不幸的是,VCL的设计者们用他们所有的智慧将大多数方法保持为私有或非虚拟的,使得扩展不可能或成为真正的PITA。