在OnChange事件中调用Delete时,为什么会出现RichEdit行插入错误? [英] Why am I getting RichEdit line insertion error when I call Delete in OnChange event?

查看:220
本文介绍了在OnChange事件中调用Delete时,为什么会出现RichEdit行插入错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在Google上搜索并检查了很多地方,找到了解决方案,但是我发现的所有情况都比简单地添加或删除行有所不同或涉及更高级的内容.基本上,我想进行一种滚动丰富的编辑(另一种方法是将插入符号移到底部,这已经为我找到了解决方案).

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

我正在向其中添加行,并通过丰富编辑的OnChange事件检查Lines.Count,并且当它达到大于15的值时,我想调用Lines.Delete(0),但是出现错误:

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 ?

推荐答案

由于添加到Delphi 2009版本中的支票,您将获得RichEdit line insertion error.此检查将验证是否成功插入了新行,并且此检查使用了选择位置.不幸的是,对于下面的代码:

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;

工作流程如下:

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

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

获取将要插入字符串的行的第一个字符的位置,将换行符添加到该字符串,设置选择(0长度,从行首开始),然后通过执行EM_REPLACESEL消息来插入字符串,这是什么?除文本插入外,还更改选择位置.上面提到的检查尚未执行,与此同时,文本插入导致OnChange事件被触发,在该事件中调用了TRichEdit.Lines.Delete.

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

删除功能类似.它获取已删除行的第一个字符索引,设置选择,现在整个行长,并使用空字符串执行EM_REPLACESEL消息.但这当然也会改变选择位置.这就是问题所在,因为我们现在要回到TRichEdit.Lines.Insert函数的最后一行.

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

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

现在,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;

如果您没有从这个无聊的故事中入睡,那么我建议您尽可能地避免对OnChange事件中的行进行操作(最好是,仅在您知道会发生什么情况时).

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

这篇关于在OnChange事件中调用Delete时,为什么会出现RichEdit行插入错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆