Delphi动态菜单项
我有一个弹出菜单,里面有几个项目。
Option 1 - Sub1 - Sub2 Option 2 - Sub1 - Sub2 Option 3 - Sub1 - Sub2
我希望能够向选项3 sub2添加子子菜单,使其看起来像:
Option 1 - Sub1 - Sub2 Option 2 - Sub1 - Sub2 Option 3 - Sub1 - Sub2 - Dynamic Item1 - Dynamic Item2 - Dynamic Item3
我一直试图用下面的代码来解决它,我可以做到“如果”菜单选项不存在(选项3),但我不能做到这一点,如果选项3已经存在(它会创建一个副本菜单选项)
我将如何做到这一点?
谢谢
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, StdCtrls;
type
TForm2 = class(TForm)
popMenu: TPopupMenu;
gbDynamic: TGroupBox;
gbMain: TGroupBox;
popDynamic: TPopupMenu;
Option11: TMenuItem;
Option21: TMenuItem;
Option31: TMenuItem;
Sub11: TMenuItem;
Sub21: TMenuItem;
Item11: TMenuItem;
Item21: TMenuItem;
Item31: TMenuItem;
Item41: TMenuItem;
Sub12: TMenuItem;
Sub22: TMenuItem;
Sub13: TMenuItem;
Sub23: TMenuItem;
Option12: TMenuItem;
Sub24: TMenuItem;
Sub14: TMenuItem;
Option22: TMenuItem;
Sub25: TMenuItem;
Sub15: TMenuItem;
Option32: TMenuItem;
Sub26: TMenuItem;
Sub16: TMenuItem;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Procedure PopupItemClick ( Sender : TObject );
end;
var
Form2: TForm2;
stlist: TStrings;
implementation
{$R *.dfm}
procedure TForm2.FormCreate(Sender: TObject);
Var
menuItem,SubItem : TMenuItem;
I, N : Integer;
s : String;
begin
//This will be a downloaded list from a server.
stlist := TStringList.Create;
stlist.Add ( 'Item 1' );
stlist.Add ( 'Item 2' );
stlist.Add ( 'Item 3' );
SubItem := TMenuItem.Create(popDynamic);
SubItem.Caption := 'Option 3';
popDynamic.Items.Add(SubItem);
MenuItem := TMenuItem.Create(popDynamic);
MenuItem.Caption := 'Sub 1';
SubItem.Add(MenuItem);
//This would work if Option 3 menu item was not aleady a menu item.
For I := 0 To stlist.Count - 1 Do
Begin
SubItem := TMenuItem.Create ( popDynamic );
SubItem.Caption := stlist [i];
SubItem.OnClick := PopupItemClick;
//assign it a custom integer value..
SubItem.Tag := i;
MenuItem.Add(SubItem);
End;
end;
Procedure TForm2.PopupItemClick ( Sender : TObject );
Var
menuItem : TMenuItem;
Begin
menuItem := TMenuItem ( sender );
label1.caption := stlist.Strings [menuItem.Tag];
End;
end.
形成:
object Form2: TForm2 Left = 0 Top = 0 Caption = 'Form2' ClientHeight = 247 ClientWidth = 480 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object gbDynamic: TGroupBox Left = 0 Top = 0 Width = 217 Height = 247 Align = alLeft Caption = 'Dynamic' PopupMenu = popDynamic TabOrder = 0 object Label1: TLabel Left = 48 Top = 32 Width = 31 Height = 13 Caption = 'Label1' end end object gbMain: TGroupBox Left = 217 Top = 0 Width = 263 Height = 247 Align = alClient Caption = 'What I Want Dynamically Created' PopupMenu = popMenu TabOrder = 1 ExplicitLeft = 336 ExplicitTop = 72 ExplicitWidth = 185 ExplicitHeight = 105 end object popDynamic: TPopupMenu Left = 136 Top = 96 object Option12: TMenuItem Caption = 'Option 1' object Sub14: TMenuItem Caption = 'Sub 1' end object Sub24: TMenuItem Caption = 'Sub 2' end end object Option22: TMenuItem Caption = 'Option 2' object Sub15: TMenuItem Caption = 'Sub 1' end object Sub25: TMenuItem Caption = 'Sub 2' end end object Option32: TMenuItem Caption = 'Option 3' object Sub16: TMenuItem Caption = 'Sub 1' end object Sub26: TMenuItem Caption = 'Sub 2' end end end object popMenu: TPopupMenu Left = 256 Top = 112 object Option11: TMenuItem Caption = 'Option 1' object Sub13: TMenuItem Caption = 'Sub 1' end object Sub23: TMenuItem Caption = 'Sub 2' end end object Option21: TMenuItem Caption = 'Option 2' object Sub12: TMenuItem Caption = 'Sub 1' end object Sub22: TMenuItem Caption = 'Sub 2' end end object Option31: TMenuItem Caption = 'Option 3' object Sub11: TMenuItem Caption = 'Sub 1' object Item11: TMenuItem Caption = 'Item 1' end object Item21: TMenuItem Caption = 'Item 2' end object Item31: TMenuItem Caption = 'Item 3' end object Item41: TMenuItem Caption = 'Item 4' end end object Sub21: TMenuItem Caption = 'Sub 2' end end end end
最简单的方法是给Option3一个名称,然后在循环中检查它:
SubItem := nil;
for i := 0 to popdynamic.Items.Count-1 do
if SameText(popdynamic.Items[i].Name, 'mnuOption3') then
SubItem := popdynamic.Items[i];
if SubItem = nil then
begin
SubItem := TMenuItem.Create(popDynamic);
SubItem.Caption := 'Option 3';
Subitem.Name := 'mnuOption3';
popDynamic.Items.Add(SubItem);
end;
这样你就不会创建一个新的子项目,如果它已经存在。
所有你需要做的创建一个新的子菜单是引用现有的菜单项 - 如果每次都是相同的,只需直接引用该对象,否则,以某种方式找到它 - 然后用你想要的TMenuItem调用Add加上。 我在我的一个应用程序中使用类似的东西以递归方式从XML文件构建菜单。
这应该是我正在做的一个非常简洁的版本。
procedure TMainForm.AddMenuItems(XMLNode: IXMLDOMNode; Parent: TMenuItem);
var
node: IXMLNode;
item: TMenuItem;
begin
for i := 0 to XMLNode.childNodes.length - 1 do begin
node := XMLNode.childNodes.item[i];
item := NewItem(node.attributes.getNamedItem('name').nodeValue, 0, false, true, nil, 0, '');
if node.nodeName = 'group' then begin
Parent.Add(item);
AddMenuItems(node, item);
end else begin
//You probably want to add a Tag to your items so you can tell them apart.
item.OnClick := DynamicItemClick;
Parent.Add(item);
end;
end;
end;
procedure TMainForm.LoadData;
var
XMLNode: IXMLNode;
//...
begin
//Clear old dynamic items
while Set1.Count > 0 do
Set1.Items[0].Free;
//Open XML file, find right XMLNode...
AddMenuItems(XMLNode.firstChild, Set1, '');
end;
...其中Set1是我正在构建菜单项的菜单项。 在你的情况下,我猜这将是Sub26(和弹出式菜单中的Sub23)。 只需使用这种基本方法,用您需要的任何文件替换XML内容即可。
链接地址: http://www.djcxy.com/p/91067.html上一篇: Delphi Dynamic Menu Items
下一篇: How can I display the 'Send to' and 'Open With' context menus?