5

私はグーグルで解決策を探して多くの場所をチェックしましたが、私が見つけたすべてのケースは異なっていたり、単純に行を追加または削除するよりも高度なものが含まれていました。基本的に、一種のスクロール リッチ エディットを作成したいと考えています (代わりに、キャレットを一番下に移動することもできますが、これについては既に解決策を見つけています)。

私はそれに行を追加し、リッチ編集Lines.CountのイベントをチェックしていOnChangeます.15より大きい値に達したらすぐに呼び出したいのですLines.Delete(0)が、エラーが発生します:

RichEdit line insertion error

誰かが私がここで間違っていることを教えてもらえますか?

4

1 に答える 1

5

RichEdit line insertion errorDelphi 2009 バージョンにチェックが追加されたためです。このチェックは、新しい行の挿入が成功したかどうかを検証し、このチェックでは選択位置を使用します。残念ながら、次のコードの場合:

procedure TForm1.Button1Click(Sender: TObject);
begin
  RichEdit1.Clear;
  RichEdit1.Lines.Add('1');
end;

procedure TForm1.RichEdit1Change(Sender: TObject);
begin
  if RichEdit1.Lines.Count > 0 then
    RichEdit1.Lines.Delete(0);
end;

ワークフローは次のようになります。

1. - TRichEdit.Lines.Add → TRichEdit.Lines.Insert

文字列が挿入される行の最初の文字の位置を取得し、その文字列に改行を追加し、選択範囲 (長さ 0、行頭から開始) を設定し、EM_REPLACESEL メッセージを実行して文字列を挿入します。挿入すると、選択位置も変更されます。上記のチェックはまだ実行されていません。その間、テキストの挿入によって OnChange イベントが発生し、そこで TRichEdit.Lines.Delete が呼び出されます。

2. - TRichEdit.Lines.Delete

Delete も同様のことを行います。削除された行の最初の文字インデックスを取得し、選択をセットアップして、行全体の長さを設定し、空の文字列で EM_REPLACESEL メッセージを実行します。もちろん、選択位置も変更されます。TRichEdit.Lines.Insert 関数の最後の行に戻るため、これが問題です。

3. - TRichEdit.Lines.Add → TRichEdit.Lines.Insert

ここで、TRichEdit.Lines.Insert 関数の前回の呼び出しの最後の処理が残っています。これは、選択位置だけに基づいた悪意のあるチェックです。また、その間の削除によって位置が変更されたため、期待される結果と一致せず、エラー メッセージが表示されます。

また、誰かがこの問題を修正する前に、これさえ使用しないでください。同じエラーが発生します。

procedure TForm1.Button1Click(Sender: TObject);
begin
  RichEdit1.Lines.Add('1');
end;

procedure TForm1.RichEdit1Change(Sender: TObject);
begin
  RichEdit1.SelStart := 0;
end;

この退屈な話で眠れなかった場合は、OnChange イベントの行をできる限り操作しないようにすることをお勧めします (何が起こるかを知っている場合に限ります)。

于 2012-05-07T00:55:57.063 に答える