【问题标题】:Main Menu SubItem主菜单子项
【发布时间】:2017-01-14 14:56:23
【问题描述】:

我尝试在运行时创建 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

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

文件 -> 另存为.. -> 文本

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

更新:我尝试创建另一个Procedure 来做到这一点,所以Procedure 搜索 另存为.. Item ,当他找到它时,将其他项目添加到它。

注意:我使用的是Delphi 10 seattle

【问题讨论】:

  • 请在您对 Q 投反对票后发表评论,以了解哪里出了问题,哪些地方不清楚。

标签: delphi delphi-10-seattle


【解决方案1】:

如果您有一个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;

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

【讨论】:

  • 例如?可以举个例子吗?
  • 我尝试创建另一个Procedure 来做到这一点
  • 如果我正确理解了您的更新,我的更新应该会回答它。
  • 好的,谢谢。
  • 注意:对于你使用的变量 I ,第一个? function FindMenuItemByCaption(AMainMenu : TMainMenu; const Caption : String) : TMenuItem; var i : Integer; // For what ? remove it. function FindItemInner(Item : TMenuItem; const Caption : String) : TMenuItem; var i : Integer;
【解决方案2】:

所以Procedure搜索Save as..Item,当他找到时,添加其他项目。

这是一个相当奇怪的想法。为什么要搜索您已经知道的项目?或者换一种说法——你为什么会忘记你仍然必须使用的项目?

按标题再次搜索既多余、又慢又容易出错(拼写错误或本地化)。

在你需要的时候保留它,在你不再搜索它之后才忘记它。

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');

附言。你的程序也缺少设置HintOnClick 属性....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 2015-09-08
    相关资源
    最近更新 更多