3

我有一个弹出菜单,我希望其中一个项目打开一个带有动态创建列表的子菜单(它是用户定义的标志列表)。这是我创建菜单项的方式(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;

这些项目被完美地添加,但是当我点击它们时它们不会被检查。事件处理程序被称为EDIT: 并且 Sender 是正确的菜单项,但是下次我打开菜单时不会出现复选标记。

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

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

4

4 回答 4

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;
于 2009-02-16T11:43:31.693 回答
2

顺便说一句(我知道你已经找到原因了)

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

另外,是否有理由不使用 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;
于 2009-02-17T01:44:27.677 回答
0

这是我的错误——我的另一部分代码正在修改Checked我忘记的状态。我现在觉得很傻。对不起,浪费时间...

于 2009-02-16T11:46:15.007 回答
0

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

于 2009-02-16T11:48:52.117 回答