我现在做的一个程序中涉及到了动态菜单的问题,特向各位高人求教。
我从数据库里读一个记录(SQL语句文件名),然后根据这个记录生成动态菜单,再通过点击这个动态菜单调用相关SQL语句进行查询。现在读取记录这些已经做好了,调用SQL语句进行查询的过程也做好了。但是就是不知道如何将两部分连起来。在大富翁的离线包里看到了某达人的一段代码。
里面有:procedure TForm1.FileOpen(Sender: TObject);
  begin
  if OpenDialog1.Execute then
  begin
    //PerformFileOpen(OpenDialog.FileName);
    richEdit1.lines.loadfromfile(OpenDialog1.filename);
  end;
  end;  …
 Newitem.Onclick:=fileopen;    里面将一个过程赋给了一个菜单项(NEWITEM)的ONCLICK事件。 于是效仿写了一段
 
 submenu[i].OnClick:=tform1.query(i);    
  其中SUBMENU[I]为菜单项的一个数组,QUERY为相应的一个调用SQL语句的过程
  但是总是报错。报错号为
[Error] Unit1.pas(604): This form of method call only allowed for class methods如果改为
 submenu[i].OnClick:=query(i);
则报错为
[Error] Unit1.pas(604): Incompatible types: 'TNotifyEvent' and 'procedure, untyped pointer or untyped parameter'请高手赐教。   
 报错号位604,

解决方案 »

  1.   

    type
     
    tForm1 = class(TForm)
      procedure myOnclick(sender:TObject);
    end;procedure tForm1.myOnclick(sender:TObject);
    begin
    ...
    end;procedure tForm1.FormCreate(sender:TObject);
    begin
      btn1.Onclick := MyOnclick;
    end;
      

  2.   

    付给onclick的函数必须是procedure (sender:TObject) of Object这样的方法才行
      

  3.   

    你需在菜单创建时给其的OnClick 赋值;另你给OnClick 赋值的过程的参数须与OnClick一致,在过程中可以通过Sender来区别,以下是我的一段代码:
    procedure TfrmMain.AddTeleVaryItem;
    var
       i,n:integer;
    begin
       for i:=0 to High(OprtTypes) do
       begin
          ChildItem:=TMenuItem.Create(Nil);
          ChildItem.Caption:=OprtTypes[i].OprtType;
          fmTeleVary.MainMenu1.Items.Add(ChildItem);
          ChildItem.Name:='O1'+inttostr(i);
          ChildItem.OnClick:=NewMenuItemClick;
       end;
    end;procedure TfrmMain.NewMenuItemClick(Sender: TObject);
    var
       TreeNode:TTreeNode;
       str:String;
       i:integer;
    begin
       str:=(Sender as TMenuItem).Caption;
       if str='1' then
       beign
          //
       end;
       if str='2' then
       beign
          //
       end;
       .......end;
      

  4.   

    原理:你不能把一个过程指针赋值给一个方法指针,而OnClick事件属于方法指针。
    分析:你想要实现对OnClick事件赋值,并且是根据下标对应赋值。那么可以使用一个基本类型为TNotifyEvent类型的数组,记住OnClick事件属于TNotifyEvent类型。
    伪码:
    type
      TMethodArray = array[1..2] of TNotifyEvent;
    private
        procedure Method1(Sender : TObject);
        procedure Method2(Sender : TObject);
    var
      MethodArray : TMethodArray;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      MethodArray[1] := Method1;
      MethodArray[2] := Method2;
      submenu[1].OnClick:= MethodArray[1];
      submenu[2].OnClick:= MethodArray[2];
    end;
    procedure TForm1.Method1(Sender: TObject);
    begin
      ShowMessage('ok');
    end;procedure TForm1.Method2(Sender: TObject);
    begin
      ShowMessage('ko');
    end;
    基本原理就是这样,你要实现动态的效果,就要根据业务自己修改了。