在 Delphi 组件中同时使用和发布事件

3de*_*ite 1 delphi events

我有一个类是 TImage32 的后代。我需要使用像 OnMouseMove 这样的事件,因此代码在 Create() 中分配我的 OnMouseMove 事件。但是如果用户在Delphi中安装这个组件并分配另一个OnMouseMove事件,我的事件就会被替换。

我当前的解决方案是继承自TCustomImage32,并且不发布OnMouseMove属性(所有其他属性都是),而是创建一个可以由用户分配的新OnMouseMove2属性,并且如果分配了OnMouseMove2,则代码在我分配的OnMouseMove事件中调用OnMouseMove2 。

对于这个问题有更好的解决方案吗?要保留事件名称(例如 OnMouseMove)并也分配我自己的事件?

type
    TAudioBezierCurvesInteractive = class (TCustomImage32)
    private
        FOnMouseMove2: TImgMouseMoveEvent;
        procedure ImgMouseMoveEvent(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    public
        Constructor Create(AOwner: TComponent); override;
    published
        property OnMouseMove2: TImgMouseMoveEvent read FOnMouseMove2 write FOnMouseMove2;
        //* Original published properties
        property Align;
        property Anchors;
        property AutoSize;
        etc. ...

constructor TAudioBezierCurvesInteractive.Create(AOwner: TComponent);
begin
    inherited;
    OnMouseMove := ImgMouseMoveEvent;
end;

procedure TAudioBezierCurvesInteractive.ImgMouseMoveEvent(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
    ...my code here...
    if Assigned(FOnMouseMove2) then begin
        FOnMouseMove2(Sender, Shift, X, Y, Layer);
    end;
end;
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 8

组件永远不应该将处理程序分配给它自己的事件。正如您所发现的,这会给用户带来问题。

正确的解决方案是重写触发事件的虚拟方法,例如:

type
  TAudioBezierCurvesInteractive = class (TImage32)
  protected
    procedure MouseMove(Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer); override;
  end;

procedure TAudioBezierCurvesInteractive.MouseMove(Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer;
begin
  ...my code here...
  inherited;
end; 
Run Code Online (Sandbox Code Playgroud)


Uwe*_*abe 6

更好地重写MouseMove,执行代码并调用继承。无需连接该事件或引入第二个事件。

type
    TAudioBezierCurvesInteractive = class (TCustomImage32)
    protected
        procedure MouseMove(Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer); override;
    published
        //* Original published properties


procedure TAudioBezierCurvesInteractive.MouseMove(Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
    { ...my code here... }
    inherited;
end;
Run Code Online (Sandbox Code Playgroud)