It depends a bit what the exact use case is, but it probably can be achieved with a class derived from TMemo with the following extensions:
type
TLinkMemo = class(TMemo)
private
FLinkedMemo: TLinkMemo;
procedure WMVScroll(var Message: TMessage); message WM_VSCROLL;
procedure DoScroll(var Message: TMessage);
public
property LinkedMemo: TLinkMemo read FLinkedMemo write FLinkedMemo;
end;
procedure TLinkMemo.DoScroll(var Message: TMessage);
begin
var saveLinkedMemo := FLinkedMemo;
try
FLinkedMemo := nil;
Perform(Message.Msg, Message.WParam, Message.LParam);
finally
FLinkedMemo := saveLinkedMemo;
end;
end;
procedure TLinkMemo.WMVScroll(var Message: TMessage);
begin
inherited;
if FLinkedMemo <> nil then
FLinkedMemo.DoScroll(Message);
end;
In FormCreate you just assign both LinkedMemo properties:
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.LinkedMemo := Memo2;
Memo2.LinkedMemo := Memo1;
end;
To avoid having to register this new control TLinkMemo you can use an interposer class declared before the form, either in the same unit or in a separate unit used in the interface uses clause.
type
TMemo = class(TLinkMemo);
Note, that editing one of the memo will break sync between the controls.