1

I have a class that is a descendant of TImage32. I need to use the event like OnMouseMove, so the code assigns my OnMouseMove event in Create(). But if the user installs this component in Delphi and assigns another OnMouseMove event, my event is replaced.

My current solution is to inherit from TCustomImage32 and do not publish the OnMouseMove property (all other properties yes), but create a new OnMouseMove2 property that can be assigned by the user, and the code calls OnMouseMove2 in my assigned OnMouseMove event if OnMouseMove2 is assigned.

Is there a better solution to this problem? To keep the event name for example OnMouseMove and have my own event assigned too?

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;

2 Answers 2

8

A component should never assign handlers to its own events. That causes issues for users, as you have discovered.

The correct solution is to override the virtual methods that fire the events, eg:

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; 
Sign up to request clarification or add additional context in comments.

Comments

6

Better override MouseMove, do your code and call inherited. No need for wiring the event or introducing a second one.

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;

1 Comment

Thank you, I flaged Remy's answer as the solution, as it appeared before this post, but both solutions seem the way to go. I up-woted it though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.