Why am I getting RichEdit line insertion error when I call Delete in OnChange event?

StackOverflow https://stackoverflow.com/questions/10474883

  •  06-06-2021
  •  | 
  •  

سؤال

I've googled and checked many places for a solution, but all cases I found differed or involved something more advanced than simply adding or deleting lines. Basically, I want to make a sort of scrolling rich edit (alternative would be moving the caret to the bottom, which I already found a solution for).

I'm adding lines to it and checking Lines.Count with the OnChange event of the rich edit and as soon as it reaches value greater 15 I want to call Lines.Delete(0), however I get the error:

RichEdit line insertion error

Can someone tell me what am I doing wrong here ?

هل كانت مفيدة؟

المحلول

You are getting the RichEdit line insertion error because of check added to the Delphi 2009 version. This check verifies if the insertion of a new line has been successful and this check uses for it the selection position. Unfortunately, for the following piece of code:

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;

The workflow looks like this:

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

Get the position of the first char for the line where the string will be inserted, add the linebreak to that string, setup the selection (0 length, starting at the line beginning) and insert the string by performing EM_REPLACESEL message, what except the text insertion, changes also the selection position. The check mentioned above has not been performed yet, and in the meantime that text insertion causes the OnChange event to fire, where the TRichEdit.Lines.Delete is called.

2. - TRichEdit.Lines.Delete

Delete does something similar. It gets the first character index of the deleted line, setup the selection, now in the whole line length and performs the EM_REPLACESEL message with the empty string. But it also changes the selection position of course. And that's the problem, because we are now going back to the last line of the TRichEdit.Lines.Insert function.

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

Now the last thing of a previous call of the TRichEdit.Lines.Insert function remains to be done, the evil check based just on the selection position. And since the position has been changed by the meantime deletion, it doesn't match to the expected result and you are getting the error message.

Also, before someone fix this issue, don't use even this, it will cause the same error:

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

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

If you didn't fell asleep from this boring story, then I can suggest you just to avoid the manipulation with the lines in OnChange event as much as you can (better to say, only when you know what can happen).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top