主菜单子项

时间:2017-01-14 14:56:23

标签: delphi delphi-10-seattle

我尝试在运行时创建MainMenu,因此我为此创建了两个Procedure

程序1:

Procedure AddMenuItem ( Const Menu : TMenu ; Caption : String );
  Var MenuItem : TMenuItem;
Begin
  MenuItem := TMenuItem.Create(Menu);
  MenuItem.Caption := Caption;
  Menu.Items.Add(MenuItem);
End;

程序2:

Procedure MenuAddSubItem ( Const Menu : TMenu ; Index : Integer ; Caption : String ) ;
  Var Item : TMenuItem;
Begin
  Item := TMenuItem.Create(Menu);
  Item.Caption := Caption;
  Menu.Items[Index].Add(Item);
End;

第一个Procedure创建Items,第二个创建SubItems

这两个Procedure的来电是:

AddMenuItem(MainMenu1,'File');
MenuAddSubItem(MainMenu1,0,'Open');
MenuAddSubItem(MainMenu1,0,'Save');
MenuAddSubItem(MainMenu1,0,'Save as..');
MenuAddSubItem(MainMenu1,0,'-');
MenuAddSubItem(MainMenu1,0,'Exit');

我想将Items添加到另存为 Item,例如:

档案 - >另存为... - > PDF

档案 - >另存为... - >文件

档案 - >另存为... - > TXT

所以,我的问题是:如何将Items添加到另存为... Item

更新:我尝试创建另一个Procedure来执行此操作,因此Procedure 搜索另存为.. Item,当找到它时,添加其他项目。

注意:我正在使用Delphi 10 seattle

2 个答案:

答案 0 :(得分:4)

如果您有TMenuItem,则可以使用其Add方法向其中添加其他菜单项。然后,可以通过其Items属性访问它们。

下面的代码显示了如何执行此操作,以及如何通过菜单进行递归搜索以查找具有指定标题的菜单项,并将新菜单项添加到其子菜单中。

function FindMenuItemByCaption(AMainMenu : TMainMenu; const Caption : String) : TMenuItem;


  function FindItemInner(Item : TMenuItem; const Caption : String) : TMenuItem;
  var
    i : Integer;
  begin
    Result := Nil;
    if Item.Caption = Caption then begin
      Result := Item;
      exit;
    end
    else begin
      for i := 0 to Item.Count - 1 do begin
        Result := FindItemInner(Item.Items[i], Caption);
        if Result <> Nil then
          Break;
      end;
    end;
  end;

begin
  Result := FindItemInner(AMainMenu.Items, Caption);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  FileItem,
  SaveItem,
  SaveAsItem,
  OtherItem,
  QuitItem : TMenuItem;
  i : integer;
  ItemToFind,
  ExtraItem : TMenuItem;
begin
  FileItem := TMenuItem.Create(Self);
  FileItem.Caption := 'File';
  MainMenu1.Items.Add(FileItem);

  SaveItem := TMenuItem.Create(Self);
  SaveItem.Caption := 'Save';
  FileItem.Add(SaveItem);

  SaveAsItem := TMenuItem.Create(Self);
  SaveAsItem.Caption := 'Save as';
  FileItem.Add(SaveAsItem);

  for i := 1 to 3 do begin
    OtherItem := TMenuItem.Create(Self);
    OtherItem.Caption := 'Other ' + IntToStr(i);
    SaveasItem.Add(OtherItem);
  end;

  QuitItem := TMenuItem.Create(Self);
  QuitItem.Caption := 'Quit';
  FileItem.Add(QuitItem);

  Caption := SaveAsItem.Items[2].Caption;

  ItemToFind := FindMenuItemByCaption(MainMenu1, 'Save as');
  Assert(ItemToFind <> Nil);
  ExtraItem := TMenuItem.Create(Self);
  ExtraItem.Caption := 'Extra';
  ItemToFind.Add(ExtraItem);
end;

当然,您可以以类似的方式填充TPopUpMenu;

答案 1 :(得分:0)

  

因此,程序搜索另存为..项目,当他找到它时,添加其他项目。

这是一个相当奇怪的想法。你为什么要搜索你已经知道的物品?换句话说 - 为什么你会忘记你仍然需要使用的项目?

通过标题再次搜索既冗余又慢,且容易出错(拼写错误或本地化)。

只需在您需要时保留该值,只有在您不再搜索它之后才会忘记它。

function MenuAddSubItem ( Const Menu : TMenuItem ; Const Caption : String ): TMenuItem; overload;
  Var Item : TMenuItem;
Begin
  Item := TMenuItem.Create(Menu);
  Item.Caption := Caption;
  Menu.Add(Item);
  Result := Item;
End;

function MenuAddSubItem ( Const Menu : TMenu ; Const Index : Integer ; Const Caption : String ): TMenuItem; overload;
Begin
  Result := MenuAddSubItem( Menu.Items[Index], Caption );
End;


var miSaveAs: TMenuItem;

AddMenuItem(MainMenu1,'File');
MenuAddSubItem(MainMenu1,0,'Open');
MenuAddSubItem(MainMenu1,0,'Save');
miSaveAs := MenuAddSubItem(MainMenu1,0,'Save as..');
MenuAddSubItem(MainMenu1,0,'-');
MenuAddSubItem(MainMenu1,0,'Exit');

MenuAddSubItem(miSaveAs,'in PDF format');
MenuAddSubItem(miSaveAs,'in MS Word format');
MenuAddSubItem(miSaveAs,'in Plain Text format');

PS。您的程序也缺少设置HintOnClick属性....