メインフォームにRichEditが配置されています。
このRitchEditには、動作中に動的に文字列が追加されていきます。
現状だと、追加動作が行われるために再描画されると思われ、
RichEditの表示がちらつきます。これを防ぐ方法は
ないでしょうか?
>現状だと、追加動作が行われるために再描画されると思われ、
あらかじめTStrings.BeginUpdateしておくと、文字列を追加しても再描画されません。
その後、TStrings.EndUpdateすれば再描画されます。
RichEdit1.Lines.BeginUpdate;
…
RichEdit1.Lines.Add(Str);
// RichEdit1.SelText:=Str+sLineBreak;
…
RichEdit1.Lines.EndUpdate;
これでうまくいかない場合は、ちらつきが再現できるコードを提示してみてください。
Harryさん、さっそくのレスポンスありがとうございます。
さっそく組み込んでみましたが、思い通りの動作をしてくれません。
RichEdit1.Lines.BeginUpdateを発行すると、RitchEditの表示が
なされなくなってしまいます。
実現したいのは下記のような状況です。
RichEditの画面への」表示は15行です。可視の間は多少チラつきが出ても
構いません。15行を超えて、可視範囲外でテキストが追加されているる時は
ちらつきを止めたいんです。
次善の策として、文字が追加されていく様子を見せられるように
RitchEditをスクロールさせて、最新の状態を見せる、というような
方法も考えています。
どちらも難しいでしょうか?
目的とは異なるかもしれませんが、
1.最初に文字列をTStringListにAddする。
2.TRitchEditのItems(Linesかな?)に先程のTStringlistをAssignすれば
ちらつきは防止されて瞬時にデータが登録されます。
最新の情報を見せる場合は、
TRichEditにスクロール系のメッセージを投げれば出来ると思います。
気まぐれさん、レスポンスありがとうございます。
他のオブジェクトに読み込ませて、最後にassignする方法は
既に試してみました。
最新にする、つまりスクロールさせる方法は、具体的な
コードの書き方が解らず、また速度の低下が出ないか
気になっているところです。
コントロールの都合上ある程度は仕方がない気がします。
用途から察するに、ListViewとかオリジナルコンポーネントで作ったほうが
楽な気がします。
procedure TForm1.Timer1Timer(Sender: TObject);
var
aStr:string;
i: Integer;
begin
aStr := DateTimeToStr(Now);
//LockWindowUpdate(RichEdit1.Handle);
RichEdit1.SelStart := RichEdit1.GetTextLen;
RichEdit1.SelText := #$D#$A;
for i := 1 to Length(aStr) do
begin
case Word(aStr[i]) of
48: RichEdit1.SelAttributes.Color := clBlue;
49: RichEdit1.SelAttributes.Color := clRed;
50: RichEdit1.SelAttributes.Color := clGreen;
51: RichEdit1.SelAttributes.Color := clPurple;
else
RichEdit1.SelAttributes.Color := clBlack;
end;
RichEdit1.SelText := aStr[i];
end;
//LockWindowUpdate(0);
end;
RichEdit1にメッセージを送ってスクロールさせる方法を
試してみました。
RichEdit1 := RichEdit1 + s;
if Pos(#$0D#$0A,s) . 0 then RIchEdit1.Perform(EMSCROLL,EMPAGEDOWN,0);
結果、処理速度が大きく低下するため、不採用にしました。結局、
不可視のRcihEditで処理し、可視のRcihEditの行数に達したところで
Lines.Assignする方法を取りました。
解決してしまったのですが・・・
> RichEdit1 := RichEdit1 + s;
これ、RichEdit1.Lines.Text := RichEdit1.Lines.Text + s; ですかね?
単なる文字だけで、いいのなら、RichEdit1.Lines.Add(s); だけで十分だと思うのですが。
RichEdit1.Line.Addだけでは、ちらつきませんでしたが、
RichEdit1.Lines.Text := RichEdit1.Lines.Text + s; のようにするとちらつきました。
"s"が、行単位ではなく、改行コード込みの文字列なのであれば、以下のようにTStringListに
一度入れて、行数チェックしてから追加したらいいのかなと。
var
sl: TStringList;
i: Integer;
begin
sl := TStringList.Create;
sl.Text := s;
RichEdit1.Lines[RichEdit1.Lines.Count-1] := RichEdit1.Lines[RichEdit1.Lines.Count-1] + sl[0];
for i := 1 to sl.Count-1 do RichEdit1.Line.Add(sl[i]);
...
写し間違えていました。済みません。
> 単なる文字だけで、いいのなら、RichEdit1.Lines.Add(s); だけで十分だと思うのですが。
> RichEdit1.Line.Addだけでは、ちらつきませんでしたが、
> RichEdit1.Lines.Text := RichEdit1.Lines.Text + s; のようにするとちらつきました。
後者です。
ご提示いただいた方法も試してみます。ありがとうございました。
……AddStrings
>……AddStrings
フォローどうもです。
"S"が、行の終了する文字列であることが保証されているのであれば、
わざわざ最終行と連結する必要はなく、RichEdit1.Lines.AddStrings(s); で
十分だと思われます。
> if Pos(#$0D#$0A,s)
こんな記載があると、例えば通信中の記録で、決まった文字数しか入ってこないのかと
思ってしまったので・・・。
ツイート | ![]() |