因为我的菜单是动态生成的..
所以的它事件也是动态生成的...
用的是循环....生成事件..........

解决方案 »

  1.   

    呵呵,可以先设置好然后visible=false啊。
      

  2.   

    比如说你生成的菜单名字是N1,而你给N1准备的事件的方法名称是N1Click,那么就这样写就行了
    N1.OnClick := N1Click;
    只要两个的参数是一样就行了
      

  3.   

    动态生成菜单,那你要事先写好要执行的事件了,
    如:procedure myclick(sender:Tobject);
       begin
         showmessage('scuess!');
       end;
    在菜单生成后:
      N1.onclick:=myclick(sender);
      

  4.   

    用菜单的NAME或TAG属性来区分事件吧。procedure TForm1.TMenuItem1Click(Sender: TObject);
    begin
      case TMenuItem(Sender).Tag of
        0://打开出库单 
        1://打开入库单
      end;
    end;
      

  5.   

    procedure TfrmMain.MnuClick(Sender: TObject);
    var
      mnuTemp : TCustomMenuItem;
    begin
      mnuTemp := Sender as TCustomMenuItem;
      if mnuTemp.RoleID <> '' then
        DistributeIt(mnuTemp.RoleID, mnuTemp.RoleKey, nil);
    end;
      

  6.   

    兄弟们的那些方法,我也知道。。但
    问题是我的菜单是一个菜单数组。
    我想循环为它付上事件。
    怎么办?
     for j:=0 to book.q3.Recordcount-1 do
         begin
           childitems[j]:=tmenuitem.Create(items[i]);
           childitems[j].Caption:=trim(book.q3.fieldbyname('memu').asstring);
          items[i].Add(childitems[j]);
         //childitems[j].OnClick=//怎么办?;
          end;
                 book.q3.next;
      

  7.   

    那么多菜单项你都要设置不同的事件吗? 能否设置一个公用事件, 再根据具体情况加以区别处理呢? 如果真的差别很大, 能否确定Recordcount呢? 如果不能就不好办了. 事件无论如何是要提前编好的, 只是动态分配给相应的对象罢了, 不能动态生成的, 除非是个编程软件...
      

  8.   

    贴点原代码给你参考procedure TMainForm.SetupMenu;
    var
      MenuItem: TMenuItem;
      ParentMenu: TComponent;
      i: Integer;
      comp: TComponent;  procedure updateMenuItem(index: integer; pMenuItem: TMenuItem);
      begin
        with pMenuItem do
        begin
         {1=Name,Parent,Caption,Hint,Shortcut,ID,WindowName,ExeName}
          Name := UserTitle(AddonMenu[index], ',', 1);
          if CaptionHandler1.LangChanger.LanguageMode = lmEnglish then
          begin
            Caption := UserTitle(AddonMenu[index], ',', 3);
            Hint := UserTitle(AddonMenu[index], ',', 4);
          end
          else
          begin
            Caption := UserTitle(AddonMenu[index], ',', 9);
            Hint := UserTitle(AddonMenu[index], ',', 10);
          end;
          if UserTitle(AddonMenu[index], ',', 5) <> EmptyStr then
            Shortcut := TextToShortCut(UserTitle(AddonMenu[index], ',', 5));
        end;
      end;
    begin
      for i := 0 to AddonMenu.Count - 1 do
      begin
        // by rex on 2 mar 2001
        comp := Self.FindComponent(UserTitle(AddonMenu[i], ',', 1));
        if Assigned(comp) then begin
          TComponent(MenuItem) := comp;
          updateMenuItem(i, MenuItem);
          continue;
        end
        else begin
          MenuItem := TMenuItem.Create(Self);  {create an item on the fly}
          updateMenuItem(i, MenuItem);
        end;
        // by rex on 2 mar 2001 end    with MenuItem do
        begin
          Enabled := True;
          Visible := True;
          Tag := i;
          OnClick := MenuOnClick;  {assign OnClick event}
          if UserTitle(AddonMenu[i], ',', 2) = EmptyStr then
            ParentMenu := nil
          else
            ParentMenu := Self.FindComponent(UserTitle(AddonMenu[i], ',', 2));
        end;
        if ParentMenu = nil then
          mnuMain.Items.Add(MenuItem)
        else
        begin
          if ParentMenu is TMainMenu then
            TMainMenu(ParentMenu).Items.Add(MenuItem)
          else if ParentMenu is TPopupMenu then
            TPopupMenu(ParentMenu).Items.Add(MenuItem)
          else
            TMenuItem(ParentMenu).Add(MenuItem);
        end;
      end;
    end;
      

  9.   

    同意
    那么多菜单项你都要设置不同的事件吗? 能否设置一个公用事件, 再根据具体情况加以区别处理呢? 如果真的差别很大, 能否确定Recordcount呢? 如果不能就不好办了. 事件无论如何是要提前编好的, 只是动态分配给相应的对象罢了, 不能动态生成的, 除非是个编程软件...
    在公用事件里面利用sender的tag属性区分就好了
      

  10.   

    我曾经做过一个决策分析方面的系统,
    菜单也是动态生成的,
    事件处理也是动态处理的,
    我是用一个ID号来关联的。
    用了NAME和TAG属性。如果菜单动态成,而事件又要固定每项一个,
    那你应该重新考虑一下你的设计了。
    建议集中处理。
      

  11.   

    一个动态生成菜单的例子,挺简单的,unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Menus;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        procedure mypopuphandler(sender:tobject); //定义菜单命令处理过程
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure show(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      myMainMenu: TMainMenu;
      myPopupMenu: TPopupMenu;
      mysubitems:array[0..3] of tmenuitem;
      mypopupitems:array[0..3] of tmenuitem;
      i:integer;
      y:integer;
      
    implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
    myitem:array[0..2] of tmenuitem;
    begin
    //创建主菜单
      mymainmenu:=tmainmenu.create(self);
    //创建三个子菜单
      for i:=0 to 2 do begin
        myitem[i]:=tmenuitem.Create(self);
        myitem[i].Caption:='子菜单'+inttostr(i)+'(&'+inttostr(i+1)+')';
        mymainmenu.items.add(myitem[i]);
      end;
    //创建主菜单中第一个子菜单的下拉菜单
      for i:=0 to 3 do begin
        mysubitems[i]:=tmenuitem.Create(self);
        mysubitems[i].Caption :='主菜单项'+inttostr(i)+'(&'+inttostr(i+1)+')';
        mymainmenu.items[0].add(mysubitems[i]);
    //调用mypopuphandler事件
        mysubitems[i].OnClick:=mypopuphandler;
      end;
    //第二个菜单设为分隔符
      mysubitems[1].Caption :='-';
    //第三个菜单设置竖向分隔条
      mysubitems[3].Break :=mbbarbreak;
    end;
    procedure tform1.mypopuphandler(sender:tobject);
    begin
      with sender as tmenuitem do
        begin
          showmessage(caption);
        end;
    end;
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      y:=1;
      mypopupmenu:=tpopupmenu.create(self);
    //创建弹出式菜单
      for i:=0 to 3 do begin
        mypopupitems[i]:=tmenuitem.Create(self);
        mypopupitems[i].Caption :='弹出式菜单项'+inttostr(i)+'(&'+inttostr(i+1)+')';
        mypopupmenu.items.add(mypopupitems[i]);
        mypopupitems[i].OnClick :=mypopuphandler;
      end;
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
    if y=0 then exit;
    //定点击活popupmenu
    mypopupmenu.popup(form1.Left +60,form1.Top +60);
    end;procedure TForm1.show(Sender: TObject);
    begin
    y:=0;
    end;end.
      

  12.   

    唉..没办法....我开始是想到...不知道Delphi有没有事件数据数组....如果有的话...就不必那么麻烦了..
    看来现在只好写一个公共函数了...
    不知那个公共函数...怎么写...
      是不是这样写..
      if (serner with tmemuitem).name(或caption)='菜单名' then
             (semder as tmemuitme).onclick=某个事件
      else if...
    ..................................
     
      

  13.   

    给你找了一个别人写的:
    unit DataTree;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, DB, ADODB, ComCtrls, StdCtrls, Buttons;type
      PNode = ^TNode;
      TNode = record
        FID:integer;                 // 记录的ID号
        FBM:TBookMark;        // 定位记录的指针(书签)
    end;type
      TDataTreeForm = class(TForm)
        ADOConnection1: TADOConnection;
        TreeView1: TTreeView;
        BitBtn1: TBitBtn;
        ADODataSet1: TADODataSet;
        Button1: TButton;
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      DataTreeForm: TDataTreeForm;function BuildTree(DataSet: TADODataSet; TV: TTreeView;
      SelfField,SelfName,ParentField:String):boolean;implementation{$R *.dfm}function BuildTree(DataSet: TADODataSet; TV: TTreeView;
      SelfField,SelfName,ParentField:String):boolean;
      { 以下子函数为在表中查找第一个PNode=AIndex的记录}
      function FindKey(AIndex: integer; FFirst:boolean): boolean;
      begin
        Result:=DataSet.Locate(ParentField,AIndex,[loCaseInsensitive]);
      end;
      { 以下函数在FindKey的基础上找出下一个符合的记录}
      function FindNext(AIndex: integer): boolean;
      begin
        DataSet.Next;
        if DataSet.Eof then
          Result:=false
        else
          Result:=DataSet.FieldValues[ParentField]=AIndex;
        if not Result then DataSet.Prior;
      end;
      { 以下函数据构造当前结点的一级子树 }
      function GetChildNode(index: integer; ANode: TTreeNode):integer;
      var
        MyNode:PNode;
        Node:TTreeNode;
      begin
        if FindKey(index,true) then
        begin
          new(MyNode);
          with DataSet do
          begin
            MyNode^.FID :=FieldValues[SelfField];
            MyNode^.FBM :=GetBook;
          end;
          Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
          Node.Data:=MyNode;
          Result:=1;
          while FindNext(index) do
          begin
            new(MyNode);
            with DataSet do
            begin
              MyNode^.FID :=FieldValues[SelfField];
              MyNode^.FBM :=GetBook;
            end;
            Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
            Node.Data:=MyNode;
            Result:=Result+1;
          end;
        end
        else
          Result:=0;
      end;
      { 以下函数据以ANode 为结当,构造一棵属于自己的子树}
      procedure BuildMe(AIndex: integer; ANode: TTreeNode);
      var
        NodeNum:integer;
        Node:TTreeNode;
        i:integer;
      begin
        NodeNum:=GetChildNode(AIndex,ANode);
        if NodeNum>0 then
        begin
          if ANode=nil then Node:=TV.Items.GetFirstNode
          else
            Node:=ANode.getFirstChild;
          for i:=1 to NodeNum do
          begin
            BuildMe(PNode(Node.Data)^.FID,Node);
            Node:=ANode.GetNextChild(Node);
          end;
        end;
      end;
      // 组合部份
    begin
      if (DataSet=nil) or (DataSet.Active =false) then
        Result:=false
      else if (TV=nil) then
        Result:=false
      else begin
        TV.Items.Clear;
        BuildMe(0,nil);
        Result:=true;
      end;
    end;procedure TDataTreeForm.BitBtn1Click(Sender: TObject);
    begin
      BuildTree(ADODataSet1, TreeView1, 'F_NodeID', 'F_NodeName', 'F_ParentNodeID');
    end;end.
      

  14.   

    qiume(走好每一步)你这个例子,要把树的节点换成菜单的ITEMS也太麻烦了吧,是不是想的太复杂了