在Delphi中动态创建子菜单

时间:2009-02-16 11:22:02

标签: delphi event-handling menu

我有一个弹出菜单,我希望其中一个项目打开一个带有动态创建列表的子菜单(它是用户定义标志的列表)。这是我创建菜单项的方式(FlagAs是我要将子菜单附加到的菜单项):

lNewMenuItems: array[0..flagCount] of tMenuItem;

for I := 0 to flagCount do
begin
  { Create a new menu item }
  lNewMenuItems[I] := tMenuItem.Create(FlagAs);
  lNewMenuItems[I].Caption := FlagNames[I];
  lNewMenuItems[I].Tag := I; { Tag with the flag number }
  lNewMenuItems[I].OnClick := miFlagClick;
end;

FlagAs.Add(lNewMenuItems);

miFlagClick处理程序只是切换其发件人的已检查状态:

procedure TMyForm.miFlagClick(Sender: TObject);
begin
  (Sender as tMenuItem).Checked := not (Sender as tMenuItem).Checked;
end;

项目添加完美,但点击它们时不会检查它们。事件处理程序被称为编辑:发件人是正确的菜单项,但下次打开菜单时不会出现复选标记。

我做错了什么?或者我是否以错误的方式创建菜单? (注意flagCount将来可能会改变,但在代码中被定义为常量)

编辑:以上确实有效 - 请参阅下面的答案

4 个答案:

答案 0 :(得分:4)

我在Delphi 2009中尝试了以下内容,它运行良好:

procedure TForm5.FormCreate(Sender: TObject);
var
  i : Integer;
  mis : array[0..3] of TMenuItem;
begin
  for i := 0 to 3 do begin
    mis[i] := tMenuItem.Create(SubMenu);
    NewMenu(mis[i]);
  end;
  SubMenu.Add(mis);
end;

procedure TForm5.NewMenu(var mi: TMenuItem);
begin
  mi.Caption := 'Test';
  mi.OnClick := TestClick;
end;

procedure TForm5.TestClick(Sender: TObject);
begin
 (Sender as tMenuItem).Checked := not (Sender as tMenuItem).Checked;
end;

答案 1 :(得分:2)

撇开(我知道你找到了原因)

为什么使用lNewMenuItems:tMenuItem的array [0..flagCount];而不是使用单个变量?

另外,是否有理由不使用AutoCheck属性?

 var
    NewMenuItem: TMenuItem;
    I : Integer;
  begin
    for I := 0 to flagCount do
    begin
      { Create a new menu item }
      NewMenuItem := TMenuItem.Create(FlagAs);
      NewMenuItem.Caption := FlagNames[I];
      NewMenuItem.Tag := I; { Tag with the flag number }
      // NewMenuItem.OnClick := miFlagClick;
      NewMenuItem.AutoCheck := True;
      FlagAs.Add(NewMenuItem);
    end;
  end;

答案 2 :(得分:0)

这是我的错误 - 我的另一部分代码正在修改我忘记的Checked状态。我现在觉得很蠢。抱歉浪费时间......

答案 3 :(得分:0)

你是否有一个附加到FlagAs的事件处理程序来清除你的已检查标志?