【问题标题】:How to merge two menus in a MDI application如何在 MDI 应用程序中合并两个菜单
【发布时间】:2010-05-27 20:25:25
【问题描述】:

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

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

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

-

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

【问题讨论】:

    标签: delphi delphi-7


    【解决方案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 具有相同名称的 MenuItems,它将起作用。另请注意,如果您的 DstMenu 没有所有者(但我猜它有并且它是您的 MDICHildForm),则可能存在内存泄漏。

    【讨论】:

      【解决方案2】:

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

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

      话虽如此,我不确定使用内置菜单合并是否可以实现您想要的。

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

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

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

      【讨论】:

      • "子窗体中的菜单项用相同的 GroupIndex 替换主窗体上的项"。所以,从字面上看,Delphi 中的菜单合并不能合并菜单。 叹息
      • @IanBoyd:确实,主菜单合并不可能以您直观希望的方式工作。不幸的是,VCL 设计者尽其智慧,将大多数方法保持为私有或非虚拟,使得扩展成为不可能或真正的 PITA。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 2019-09-02
      相关资源
      最近更新 更多