任何人都知道如何在MDI应用程序中合并两个具有相同名称的菜单。
更确切地说,在MDI主窗体中,我有一个名为'File'的菜单,它有一个名为'Load project'的子菜单。 在MDI子窗体中,我有一个名为'File'的菜单,其中包含一个名为'Save project'的子菜单。
如何强制我的应用程序在“文件”菜单下显示“加载”和“保存”子菜单?
-
PS:设置相同的GoupIndex值将不起作用。
答案 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),可能会有内存韭菜。