Since the user cannot enter text in a label any change of the label caption occurs under control of your code where you can react.
If you - for whatever reason - nevertheless absolutely need an OnChange event you must write a specialized Label component. Every TLabel has a protected TextChanged method which you can override to fire an OnChange event handler:
type
TNewLabel = class(TLabel)
private
FOnChange: TNotifyEvent;
protected
procedure TextChanged; override;
public
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
procedure TNewLabel.TextChanged;
begin
inherited;
if Assigned(FOnChange) then FOnChange(self);
end;
Since this feature probably is needed only for a few labels I'd replace these labels on the fly by the new label.
procedure TForm1.FormCreate(Sender: TObject);
var
Lbl: TNewLabel;
begin
Lbl := TNewLabel.Create(Self);
Lbl.Parent := Label1.Parent;
Lbl.CloneLabel(Label1);
Lbl.OnChange := @<your event handler for the OnChange event of the new label>
Label1.Free; // Destroy the old label
Label1 := Lbl; // and replace by the new one
end;
The method CloneLabel saves some typing if there are several labels to be replaced:
procedure TNewLabel.CloneLabel(ALabel: TLabel);
begin
Parent := ALabel.Parent;
SetBounds(ALabel.Left, ALabel.Top, ALabel.Width, ALabel.Height);
Caption := ALabel.Caption;
AutoSize := ALabel.AutoSize;
Font := ALabel.Font;
// plus any more properties that you change from default...
end;
See the attached project.