无法在Delphi中销毁动态创建的菜单项

Cannot Destroy Dynamically created Menu Item in Delphi

首先,是的,我已经遍布网络,但仍然无法破坏动态创建的菜单项。使用Delphi XE。我创建了这些项目(为了练习,SubMenuName是'Test1':

1
2
3
4
5
6
7
MenuItemCreated := TMenuItem.Create(PopupMenu1);
MenuItemCreated.Caption:= SubMenuCaption
MenuItemCreated.Hint := SubMenuHint;
MenuItemCreated.Name := SubMenuName;
MenuItemCreated.OnClick :=  SubMenuClick;
MenuItemCreated.AutoHotkeys := maManual;
MySubMenu.Add(MenuItemCreated);

使用创建的子菜单没有问题。 SubMenuClick过程正常工作,我确定了正确的subMenu项,因此没有问题。我接下来要做的是一个应用程序注销,它应该使用这个代码释放动态创建的子菜单(虽然我尝试了很多变化):

1
2
3
4
5
6
  // Get rid of the menu items created
  While MySubMenu.Count > 0 do
  begin
    Itemtodelete := MySubMenu.Items[0];
    FreeandNil(ItemtoDelete);
  end;

我已经放入showmessage()调试行,显示菜单项的组件名称是freeandnil'd,它们是我所期望的,即。 'Test1'和我创造的任何其他人。然后我重新登录我的应用程序(它仍然在运行,但是我退出了)。然后,软件尝试重新创建具有相同名称的相同子菜单(就我的应用程序而言,没有任何改变,并且它们之前被处理掉了(据说))。我立刻得到了异常:

错误:名为Test1的组件已存在

我完全不知道如何处理子菜单项,以便我以后可以用相同的名称重新创建它们。

任何帮助非常感谢。

谢谢,
KB


你没有说出来,所以我不得不假设MySubMenu是PopupMenu1的MenuItem。如果没有请澄清。

要从MySubMenu中删除项目以便以后再次重新创建它们,最简单的方法是调用Clear方法:

1
2
3
4
procedure TForm5.Button2Click(Sender: TObject);
begin
  MySubMenu.Clear;
end;

它删除了MySubMenu的所有菜单项并释放了它们的记忆。

为了以后重新创建项目,您不能使用Delete()或Remove(),也不能释放内存,因为它们不会释放项目的内存。这在帮助中有记录:

http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.Menus.TMenuItem.Delete
http://docwiki.embarcadero.com/Libraries/XE7/en/Vcl.Menus.TMenuItem.Remove

使用这些方法,您必须在重新创建菜单项之前自行释放内存。但是,没有必要甚至调用删除或删除,你只需简单地释放项目:

1
2
3
4
5
6
7
8
9
10
procedure TForm5.Button2Click(Sender: TObject);
var
  mi: TMenuItem;
begin
  while MySubMenu.Count > 0 do
  begin
    mi := MySubMenu.Items[0];
    mi.Free;
  end;
end;

没有必要调用FreeAndNil。
最后一个选项看起来与您的一样,在重新创建菜单项时遇到问题。我无法重现错误,除非使用Delete()或Remove()而不释放。


由于Popup菜单拥有这些项目,因此您不会将其释放。而不是FreeAndNil使用MySubMenu.Delete(0)或更合适的MySubMenu.Items.Clear而不是整个While例程。

在应用程序关闭时,弹出菜单将清除它,除非您正在重建菜单,否则无需手动执行此操作。