unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, msghandler,
LCLType, LCLIntf, Buttons, Messages;
type
TMemo=class(StdCtrls.TMemo) // Just to add things to TMemo class only for this unit
private
BusyUpdating:Boolean; // To avoid circular stack overflow
SyncMemo:TMemo; // To remember the TMemo to be sync
Old_WindowProc:TWndMethod; // To remember old handler
procedure New_WindowProc(var Mensaje:TMessage); // The new handler
public
constructor Create(AOwner:TComponent);override; // The new constructor
destructor Destroy;override; // The new destructor
end;
{ TForm1 }
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
procedure FormCreate(Sender: TObject);
private
procedure pnlMemo2Resize(Sender: TObject);
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
procedure TMemo.New_WindowProc(var Mensaje:TMessage);
begin
Old_WindowProc(Mensaje); // Call the real handle before doing anything
if (WM_PAINT<>Mensaje.Msg) // If not when need to be repainted to improve speed
or
BusyUpdating // To avoid circular stack overflow
or
(not Assigned(SyncMemo)) // If not yet set (see TForm1.FormCreate bwlow)
then Exit; // Do no more and exit the procedure
BusyUpdating:=True; // Set that object is busy in our special action
SyncMemo.Perform(WM_HSCROLL,SB_THUMBPOSITION+65536*GetScrollPos(Handle,SB_HORZ),0); // Send to the other TMemo a message to set its horizontal scroll as it is on this TMemo
BusyUpdating:=False; // Set that the object is no more busy in our special action
end;
constructor TMemo.Create(AOwner:TComponent); // The new constructor
begin
inherited Create(AOwner); // Call real constructor
BusyUpdating:=False; // Initialize as not being in use, to let enter
Old_WindowProc:=WindowProc; // Remember old handler
WindowProc:=New_WindowProc; // Replace handler with new one
end;
destructor TMemo.Destroy; // The new destructor
begin
WindowProc:=Old_WindowProc; // Restore the original handler
inherited Destroy; // Call the real destructor
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.SyncMemo:=Memo2; // Tell Memo1 what TMemo must sync (Memo2)
Memo2.SyncMemo:=Memo1; // Tell Memo2 what TMemo must sync (Memo1)
end;
procedure TForm1.pnlMemo2Resize(Sender: TObject);
begin
//Memo2.Height:=pnlMemo2.Height+20; // Make height enough big to cause horizontal scroll bar be out of TPanel visible area, so it will not be seen by the user
end;
end.