unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    procedure Button1Click(sender: TObject);
    procedure TooBig1(sender: TObject);
    procedure FormCreate(sender: TObject);
  private
    { Private declarations }
    val1,val2,res:integer;
    FTooBig : TNotifyEvent;  
  public
    { Public declarations }
  published
    property OnTooBig:TNotifyevent read FTooBig write FTooBig;   //事件属性
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(sender: TObject);
begin
  val1 := StrToInt(Edit1.Text);
  val2 := StrToInt(Edit2.Text);
  if(val1< 100)and(val2< 100) then
    begin
      res := val1*val2;
      Edit3.Text := IntToStr(res);
    end
  else
    if assigned(ontoobig) then      //事件驱动
      OnTooBig(self);
end;procedure TForm1.TooBig1(sender: TObject);
begin
  Application.MessageBox('Too Big',' Test Event! ',MB_OK);
end;procedure TForm1.FormCreate(sender: TObject);
begin
 Ftoobig:=TooBig1;
end;end.
注:这段代码运行无误。续:在这段代码中我去掉Ftoobig方法指针,把formcreate方法的实现部分改写成ontoobig:=toobig1,为什么会报错。[error]:incompatible types   错误指示位置是在属性事件ontoobig声明那一行。小弟是delphi初学者,请各位高手指点一下,这是什么原因?
另外希望能提供一个可以仿真源代码行为的软件,谢谢了!!!

解决方案 »

  1.   

    property OnTooBig:TNotifyevent;
    你写成这样了吗?
      

  2.   

    procedure DoToolBig(Sender: TObject);procedure TForm1.FormCreate(Sender: TObject);
    var
      Simpledict: TDxDictLib;
      item: TDxRvSimpleItemInfo;
      bmp: TBitmap;
    begin
      OnTooBig := DoToolBig;
    end;procedure TForm1.DoToolBig(Sender: TObject);
    beginend;好像我写来没问题,不晓得楼主问的是个啥问题
    还有自己定义的事件自己又在内部制定,这不是一个号的习惯哈
      

  3.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Edit2: TEdit;
        Edit3: TEdit;
        procedure Button1Click(sender: TObject);
        procedure TooBig1(sender: TObject);
        procedure FormCreate(sender: TObject);
      private
        { Private declarations }
        val1,val2,res:integer;
      {  FTooBig : TNotifyEvent;  }   //去掉的部分
      public
        { Public declarations }
      published
        property OnTooBig:TNotifyevent read TooBig1 write TooBig1;   //事件属性
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(sender: TObject);
    begin
      val1 := StrToInt(Edit1.Text);
      val2 := StrToInt(Edit2.Text);
      if(val1< 100)and(val2< 100) then
        begin
          res := val1*val2;
          Edit3.Text := IntToStr(res);
        end
      else
        if assigned(OnTooBig) then       //事件驱动
          OnTooBig(self);
    end;procedure TForm1.TooBig1(sender: TObject);
    begin
      Application.MessageBox('Too Big',' Test Event! ',MB_OK);
    end;procedure TForm1.FormCreate(sender: TObject);
    begin
     onTooBig:=TooBig1;
    end;end.谢谢各位的回复,多说无益,还是把改后的代码发给你们调试.另外3楼的说到"自己定义的事件自己又在内部制定,这不是一个好的习惯",我是delphi初学者,请指教!还有就是关于事件驱动机制我没有有关的资料去学习,我想深入一下,甚至想知道在内存中的映射,从而跟踪代码的行为。
      

  4.   

    首先,read后面的可以是一个函数或者一个变量
    变量的话就是你刚开始定义的那样
    如果是个函数的话必须是Function,如:    function GetToolBig: TNotifyevent;
    必须要有返回值它才可以读write后是函数的时候,必须是如下格式的    procedure SetTooBig(value: TNotifyevent);
    后面必须有一个该属性类型的参数但是对于事件类型来说,我们通常不会使用函数这种方法,只要先定义个
    FToolBigEvent: TNotifyEvent;
    然后属性这样定义 就可以了
    property OnTooBig:TNotifyevent read FToolBigEvent write FToolBigEvent;  //事件属性
    和你开始的一样然后我们调用的时候就这样调用就行了
    Obj.OnToolBig := ToolBigProc(XXXX);
    Obj是拥有该事件属性的对象,
    给OnToolBig赋值的同时,write后的FToolBigEvent同时也指向这个指针了
    在obj中触发事件的代码:
    // 先判断一下FToolBigEvent是不是为空,即OnToolBig有没有被赋值
    if Assigned(FToolBigEvent) then
      FToolBigEvent(XXXX);3楼的意思是
    如果你这个事件并不为在外部触发,只是在你这个对象内使用
    你完全可以定义一个函数来做,不要用事件来驱动了
    比如你那个代码就可以改成如下:procedure TForm1.Button1Click(Sender: TObject);
    begin
      val1 := StrToInt(Edit1.Text);
      val2 := StrToInt(Edit2.Text);
      if(val1 < 100)and(val2 < 100) then
        begin
          res := val1*val2;
          Edit3.Text := IntToStr(res);
        end
      else
        ToolBigProc(Sender);
    end;procedure ToolBigProc(Sender: TObject);
    begin
      Application.MessageBox('Too Big',' Test Event! ',MB_OK);
    end;
      

  5.   

    是不是read和write后面如果是变量必须类型与属性类型相同,如果是函数则参数必须和属性类型相同?因为write后面如果换成TOOBIG1则报错,换成FTOOBIG这个指向TOOBIG1的方法指针就可以了呢?属性ONTOOBIG是和FTOOBIG一样也是方法指针,那为什么直接把TOOBIG1的地址付给属性ONTOOBIG却不行呢?
      

  6.   

    是不是read和write后面如果是变量必须类型与属性类型相同,如果是函数则参数必须和属性类型相同?
    对TOOBIG1是个没有返回值的函数,所以只能放到write里,但是他的参数不应该是Sender: TOBject,而已该是
    Value: TNotifyEvent
      

  7.   

    read write后面如果是函数的话,他操作的对象应该是你的那个属性变量,即一个TNotifyEvent类型的变量
    而和TNotifyEvent的原形无关,先把TNotifyEvent是如何定义的忘掉,就当他是个Integer
      

  8.   

    read write后面要不跟个变量,要不跟个函数实例用于实现对属性的读、写,你跟的是属性的实现实例,当然会出错啦!
      

  9.   

    我已经测试了一下,事件属性必须是方法指针类型,属性名称实际没有作用,并不是指针,属性读写的方法必须是一个指向事件处理器的方法指针,所以事件既是类,它封装了read和write后面的方法指针,使之指向事件处理器。