DelphiのVCLでTMemoを使って大量の文字列の読み込みをするときに書くコードは一般に以下のようになります。
procedure StringToMemo(AMemo:TMemo;AString:String); // Memo1にAStringをコピーする
begin
AMemo.Lines.BeginUpdate;
AMemo.Lines.Text:=AString;
AMemo.Lines.EndUpdate;
end;
あるいは,TStringListを介して巨大な文字列を渡すときには次のようになります。
procedure StringToMemo(AMemo:TMemo;AString:String); // Memo1にAStringをコピーする
var
lSL:TStringList;
begin
lSL:=TStringList.Create;
lSL.Text:=AString;
AMemo.Lines.Assign(lSL);
lSL.Free;
end;
Assignで渡すときには,BeginUpdate/EndUpdateは必要ないです。Assignのコードの内部で利用されています。
しかし,TMemoに渡す文字列が大きくなると,低速になってしまいます。
ネットで調べてみるとTMemoのLoadFromFileでテキストファイルを渡したときには高速に表示されることにがわかりました。それならば,LoadFromStreamを使って文字列を渡せばよいのではないかと考えました。
そこで考えたのが以下のコードです。
procedure StringToMemo(AMemo:TMemo;AString:String); // Memo1にAStringをコピーする
var
lStrStream: TStringStream;
begin
lStrStream:=TStringStream.Create(Astring, TEncoding.Unicode);
AMemo.Lines.LoadFromStream(lStrStream, TEncoding.Unicode);
lStrStream.Free;
end;
LoadFromStreamもBeginUpdate/EndUpdateは必要ないです。
これでVCLのTMemoでも高速に大量の文字列を読み込むことができるようになりました。
2022/06/24 追記
Delphi11でTWinControlにLockDrawingメソッドが追加されました。
参考: RAD Studio 11で追加されたTWinControlのLockDrawingメソッド Embaracadero
TMemoでも利用できます。例えば以下のようなコードになります。
procedure StringToMemo(AMemo:TMemo;AString:String); // Memo1にAStringをコピーする
begin
AMemo.LockDrawing;
AMemo.Lines.Text:=AString;
AMemo.UnLockDrawing;
end;
時間を計測してみると,BeginUpdateとEndUpdateを使ったものとあまり変わりませんでした。
しかし,BeginUpdateやEndUpdateを持たないTwinControlではLackDrawingやunLockDrawingは役に立つのではないかと思います。
2023/07/24 追記
TStringStream.Create は エンコードのデフォルトが ANSI になり,SJISにない文字が?表示になってしまうことに気づきました。
lStrStream:=TStringStream.Create(Astring, TEncoding.Unicode);
とすべきではないかと思ったのですが,正しく表示することができませんでした。
TStringStreamの中身がTEncoding.Unicodeなら,TMemoへの読み込みにもTEncoding.Unicodeを指定する必要があります。@pik(Jun HOSOKAWA)様 アドバイスをありがとうございます!