自定义组件TImage事件导致错误"不存在"

Jak*_*ays 1 delphi vcl delphi-2010

我有一个自定义组件,包含以下事件

 private
    { Private declarations }
    ...
    fOnImageClick: TNotifyEvent;
    fOnImageMouseUp: TMouseEvent;
    fOnImageMouseDown: TMouseEvent;
    fOnImageMouseMove:  TMouseMoveEvent;
    fOnImageMouseEnter: TNotifyEvent;
    fOnImageMouseLeave: TNotifyEvent;
    fOnImageSelect: TNotifyEvent;
    fOnImageDblClick: TNotifyEvent;
  protected
    ...
  public
    { Public declarations }
     ...
  published
     ...
     property OnImageClick: TNotifyEvent read  fOnImageClick write  fOnImageClick;
     property OnImageSelect: TNotifyEvent read  fOnImageSelect write  fOnImageSelect;
     property OnImageDblClick: TNotifyEvent read  fOnImageDblClick write  fOnImageDblClick;
     property OnImageMouseDown: TMouseEvent read  fOnImageMouseDown write  fOnImageMouseDown;
     property OnImageMouseUp: TMouseEvent read  fOnImageMouseUp write  fOnImageMouseUp;
     property OnImageMouseMove:  TMouseMoveEvent read  fOnImageMouseMove write  fOnImageMouseMove;
     property OnImageMouseLeave: TNotifyEvent read  fOnImageMouseLeave write  fOnImageMouseLeave;
     property OnImageMouseEnter: TNotifyEvent read  fOnImageMouseEnter write  fOnImageMouseEnter;
  end;
Run Code Online (Sandbox Code Playgroud)

我将它们分配给一个TImage,其父级是TPanel,父级是TScrollBox

 img:= TImage.Create(ThumbPnl);
 img.Parent:= ThumbPnl;
 img.Tag:= I;
 img.Align:= alClient;
 img.Stretch:= true;
 img.OnClick:= fOnImageClick;
 img.OnDblClick:= fOnImageDblClick;
 img.OnMouseEnter:= fOnImageMouseEnter;
 img.OnMouseLeave:= fOnImageMouseLeave;
 img.OnMouseDown:= fOnImageMouseDown;
 img.OnMouseUp:= fOnImageMouseUp;
 img.OnMouseMove:= fOnImageMouseMove;
Run Code Online (Sandbox Code Playgroud)

该组件编译和bulds就好了.使用此组件的应用程序也可以编译并运行jus fine.如果我分配一个OnClick事件,它的工作原理.所有其他事件,如果我分配它们并尝试运行应用程序,我会收到错误消息,说明该事件不存在

谁知道为什么会这样?

Nic*_*ges 6

你正在为新组件创建者犯一个相当常见的错误.你违反了这个规则:

组件用户编写事件处理程序,组件编写器"触发"事件

在您的情况下,您正在做的是在您作为组件开发人员不应该这样做时分配事件.它是由组件用户分配代码的出现OnClick,OnDblClick等事件.

这足以让您将事件声明为已发布和TNotifyEvent类型.

property OnSomeEvent: TNotifyEvent read FOnSomeEvent write FOnSomeEvent;
Run Code Online (Sandbox Code Playgroud)

这就是创建事件所需要做的一切.你的工作是"解雇"他们; 也就是说,让它们发生.

这是在适当的时候在您的组件中完成的.通常,你要做的是创建一个方法DoXXXXX,其中XXXXX就是正在发生的事情.所以你要创造

procedure TMyImage.DoSomeEvent;
begin
  if Assigned(FOnSomeEvent) then FOnSomeEvent(Self);
end;  
Run Code Online (Sandbox Code Playgroud)

然后,在您的代码中,当事件应该被触发时,您只需调用DoSomeEvent.

现在,如果要增强默认事件的功能,则需要覆盖触发事件的方法.

我讨厌这样做,但我的经典组件TSmiley简单而清楚地说明了这一点:

http://tsmiley.svn.sourceforge.net/viewvc/tsmiley/

看一下这个例子,你应该看看如何创建事件.