RichEditに動的にテキストを追加する時ちらつかせないようにするには?

解決


ぱみゅ」  2013-11-28 17:50:25  No: 45627

メインフォームにRichEditが配置されています。
このRitchEditには、動作中に動的に文字列が追加されていきます。
現状だと、追加動作が行われるために再描画されると思われ、
RichEditの表示がちらつきます。これを防ぐ方法は
ないでしょうか?


Harry  2013-11-29 08:21:01  No: 45628

>現状だと、追加動作が行われるために再描画されると思われ、
あらかじめTStrings.BeginUpdateしておくと、文字列を追加しても再描画されません。
その後、TStrings.EndUpdateすれば再描画されます。

    RichEdit1.Lines.BeginUpdate;
    …
    RichEdit1.Lines.Add(Str);
//    RichEdit1.SelText:=Str+sLineBreak;
    …
    RichEdit1.Lines.EndUpdate;

これでうまくいかない場合は、ちらつきが再現できるコードを提示してみてください。


ぱみゅ  2013-11-29 18:49:36  No: 45629

Harryさん、さっそくのレスポンスありがとうございます。
さっそく組み込んでみましたが、思い通りの動作をしてくれません。
RichEdit1.Lines.BeginUpdateを発行すると、RitchEditの表示が
なされなくなってしまいます。
実現したいのは下記のような状況です。

RichEditの画面への」表示は15行です。可視の間は多少チラつきが出ても
構いません。15行を超えて、可視範囲外でテキストが追加されているる時は
ちらつきを止めたいんです。

次善の策として、文字が追加されていく様子を見せられるように
RitchEditをスクロールさせて、最新の状態を見せる、というような
方法も考えています。

どちらも難しいでしょうか?


気まぐれさん  2013-11-29 21:01:08  No: 45630

目的とは異なるかもしれませんが、

1.最初に文字列をTStringListにAddする。
2.TRitchEditのItems(Linesかな?)に先程のTStringlistをAssignすれば
ちらつきは防止されて瞬時にデータが登録されます。


気まぐれさん  2013-11-29 21:05:11  No: 45631

最新の情報を見せる場合は、
TRichEditにスクロール系のメッセージを投げれば出来ると思います。


ぱみゅ  2013-11-30 00:11:01  No: 45632

気まぐれさん、レスポンスありがとうございます。
他のオブジェクトに読み込ませて、最後にassignする方法は
既に試してみました。
最新にする、つまりスクロールさせる方法は、具体的な
コードの書き方が解らず、また速度の低下が出ないか
気になっているところです。


monaa  2013-11-30 06:21:35  No: 45633

コントロールの都合上ある程度は仕方がない気がします。
用途から察するに、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;


ぱみゅ  2013-12-02 20:21:06  No: 45634

RichEdit1にメッセージを送ってスクロールさせる方法を
試してみました。

RichEdit1 := RichEdit1 + s;
if Pos(#$0D#$0A,s) . 0 then RIchEdit1.Perform(EMSCROLL,EMPAGEDOWN,0);

結果、処理速度が大きく低下するため、不採用にしました。結局、
不可視のRcihEditで処理し、可視のRcihEditの行数に達したところで
Lines.Assignする方法を取りました。


おかぽん  2013-12-02 22:59:45  No: 45635

解決してしまったのですが・・・

> 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]);
 ...


ぱみゅ  2013-12-03 00:12:55  No: 45636

写し間違えていました。済みません。
> 単なる文字だけで、いいのなら、RichEdit1.Lines.Add(s); だけで十分だと思うのですが。
> RichEdit1.Line.Addだけでは、ちらつきませんでしたが、
> RichEdit1.Lines.Text := RichEdit1.Lines.Text + s; のようにするとちらつきました。

後者です。
ご提示いただいた方法も試してみます。ありがとうございました。


けど  2013-12-03 08:33:58  No: 45637

……AddStrings


おかぽん  2013-12-03 17:24:02  No: 45638

>……AddStrings
フォローどうもです。
"S"が、行の終了する文字列であることが保証されているのであれば、
わざわざ最終行と連結する必要はなく、RichEdit1.Lines.AddStrings(s); で
十分だと思われます。

> if Pos(#$0D#$0A,s)
こんな記載があると、例えば通信中の記録で、決まった文字数しか入ってこないのかと
思ってしまったので・・・。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加