kien_coi_1997
kien_coi_1997

Reputation: 131

Event OnChange doesn't fired when I call method LoadFromFile of TSynEdit.Lines

I have a project using TSynEdit. I found that when I call SynEdit1.Lines.LoadFromFile(), event OnChange doesn't be fired.

For instance:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    SynEdit1: TSynEdit;
    procedure Button1Click(Sender: TObject);
    procedure SynEdit1Change(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  SynEdit1.Lines.LoadFromFile('unit1.pas');
end;

procedure TForm1.SynEdit1Change(Sender: TObject);
begin
  Caption:=Caption + '!';
end;

end.

In above example, I created a form which have a button and a SynEdit.

How can I make event OnChange be fired when SynEdit1.Lines.LoadFromFile() was called?

Upvotes: 1

Views: 556

Answers (1)

Abstract type
Abstract type

Reputation: 1921

If you try to assign all the events handler of a synedit, the best you can get is a notification when the editor is cleared. For example if you test the following code the form caption will be set to 'cleared' after the button click event:

uses
  Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
  StdCtrls, LazSynEditText;

type
  TSynEditEx = class helper for TSynEdit
    function getTextBuffer: TSynEditStrings;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    SynEdit1: TSynEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure textCleared(sender: TObject);
    procedure textHistoryModified(sender: TObject);
    procedure textBuffChanged(sender: TObject);
    procedure textLineChanged(sender: TObject);
    procedure textEditAction(sender: TObject);
    procedure textModdChanged(sender: TObject);
  end;

var
  Form1: TForm1;

implementation
{$R *.lfm}

function TSynEditEx.getTextBuffer: TSynEditStrings;
begin
  exit(TextBuffer);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SynEdit1.getTextBuffer.AddNotifyHandler(senrCleared, @textCleared);
  SynEdit1.getTextBuffer.AddNotifyHandler(senrUndoRedoAdded, @textHistoryModified);
  SynEdit1.getTextBuffer.AddNotifyHandler(senrTextBufferChanged, @textBuffChanged);
  SynEdit1.getTextBuffer.AddNotifyHandler(senrLineChange, @textLineChanged);
  SynEdit1.getTextBuffer.AddNotifyHandler(senrModifiedChanged, @textModdChanged);
end;

procedure TForm1.textModdChanged(sender: TObject);
begin
  Caption := Caption + ' ModdChanged';
end;

procedure TForm1.textEditAction(sender: TObject);
begin
  Caption := Caption + ' EditAction';
end;

procedure TForm1.textLineChanged(sender: TObject);
begin
  Caption := Caption + ' LineChanged';
end;

procedure TForm1.textBuffChanged(sender: TObject);
begin
  Caption := Caption + ' BuffChanged';
end;

procedure TForm1.textCleared(sender: TObject);
begin
  Caption := Caption + ' Cleared';
end;

procedure TForm1.textHistoryModified(sender: TObject);
begin
  Caption := Caption + ' HistoryModified';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SynEdit1.Lines.LoadFromFile('unit1.pas');
end;

So the only solution is to subclass TSynEdit and introduce a custom LoadFromFile method and then trigger the onChange event inside. AFAIK, based on a short investigation, this is the only way, a bit like this:

uses
  Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
  StdCtrls, LazSynEditText;

type
  TSynEditEx = class helper for TSynEdit
    procedure LoadFromFile(const aFilename: string);
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    SynEdit1: TSynEdit;
    procedure Button1Click(Sender: TObject);
    procedure SynEdit1Change(Sender: TObject);
  private
  end;

var
  Form1: TForm1;

implementation
{$R *.lfm}

procedure TSynEditEx.LoadFromFile(const aFilename: string);
begin
  Lines.LoadFromFile('unit1.pas');
  if assigned(onChange) then
    onChange(self);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SynEdit1.LoadFromFile('unit1.pas');
end;

procedure TForm1.SynEdit1Change(Sender: TObject);
begin
  caption := caption + '!';
end;

In the real world you wouldn't use a class helper but you'd rather subclass, but I think you should get the idea.

Upvotes: 1

Related Questions