我有一个类是 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)
组件永远不应该将处理程序分配给它自己的事件。正如您所发现的,这会给用户带来问题。
正确的解决方案是重写触发事件的虚拟方法,例如:
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)
更好地重写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)