加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

RichEdit 2.0使用单个CR字符作为linebreak抛出SelStart计算(Delp

发布时间:2020-12-15 10:09:16 所属栏目:大数据 来源:网络整理
导读:当从Delphi 2006转换到Delphi XE2时,我们学到的其中之一是RichEdit 2.0用单个CR字符替换了内部CRLF对.根据VCL方面的实际文本字符串,这样做不利于抛出所有字符索引计算. 通过VCL代码跟踪可以看到的行为如下: 发送WM_GETTEXT消息(在TControl.GetTextBuf中完成
当从Delphi 2006转换到Delphi XE2时,我们学到的其中之一是RichEdit 2.0用单个CR字符替换了内部CRLF对.根据VCL方面的实际文本字符串,这样做不利于抛出所有字符索引计算.

通过VCL代码跟踪可以看到的行为如下:

>发送WM_GETTEXT消息(在TControl.GetTextBuf中完成)将返回包含CRLF对的文本缓冲区.
>发送WM_GETTEXTLENGTH消息(在TControl.GetTextLen中完成)将返回一个值,就像文本仍然包含CRLF字符一样.
>相比之下,发送EM_SETSELEX消息(即设置SelStart)会将输入值视为文本只包含CR字符.

这导致我们的应用程序中的各种事情失败(如语法高亮).正如你所知道的,到目前为止,每一条新的线条都只有一个角色.

显然,由于这是不一致的行为,我们一定是错过了一些东西或做错事.

有没有人有从RichEdit 1.0转换到RichEdit 2.0控件的经验,您是如何解决这个问题的?最后,有没有办法强制RichEdit 2.0使用像RichEdit 1.0这样的CRLF对?

解决方法

我们也遇到了这个问题.

我们做一个“邮件合并”类型的事情,我们有模板,合并代码被解析并由外部数据源替换.

使用RichText.SelStart的pos(mystring,RichEdit.Text)和RichEdit文本中的定位索引之间的索引不匹配打破了我们的合并.

我没有一个很好的答案,但我想出了一个解决方法.这是一个有点麻烦(不满意!),但直到一个更好的解决方案来了…

解决方法是使用隐藏的TMemo并将RichEdit文本复制到其中,并将CR / LF对更改为CR.然后使用TMemo使用pos(string,TMemo)找到正确的定位,并使用它来获取在TRichEdit中使用的启动位置.

这真的很糟糕,但希望这个解决方法会帮助别人在我们的情况下,或者可能引发一些比我更聪明的人来提出一个更好的解决方案.

我会显示一些示例代码…

由于我们使用seltext替换文本,所以我们需要在BOTH中替换文本,RichEdit控件和TMemo控件以保持两者同步.

StartToken和EndToken是合并代码分隔符,是一个常量.

function TEditForm.ParseTest: boolean;
var TagLength: integer;
var ValueLength: integer;
var ParseStart: integer;
var ParseEnd: integer;
var ParseValue: string;
var Memo: TMemo;
begin
  Result := True;//Default
  Memo := TMemo.Create(nil);
  try
    Memo.Parent := self;
    Memo.Visible := False;
    try
      Memo.Lines.Clear;
      Memo.Lines.AddStrings(RichEditor.Lines);
      Memo.Text := stringreplace(Memo.Text,#13#10,#13,[rfReplaceAll]);//strip CR/LF pairs and replace with CR

      while (Pos(StartToken,Memo.Text) > 0) and (Pos(EndToken,Memo.Text) > 0) do begin
        ParseStart := Pos(StartToken,Memo.SelText);
        ParseEnd := Pos(EndToken,Memo.SelText) + Length(EndToken);
        if ParseStart >= ParseEnd then begin//oops,something's wrong - bail out
          Result := true;
          myEditor.SelStart := 0;
          exit;
        end;
        TagLength := ParseEnd - ParseStart;
        ValueLength := (TagLength - Length(StartToken)) - Length(EndToken);
        ParseValue := Copy(Memo.SelText,(ParseStart + Length(StartToken)),ValueLength);
        Memo.selstart := ParseStart - 1; //since the .text is zero based,but pos is 1 based we subtract 1
        Memo.sellength := TagLength;
        RichEditor.selstart := ParseStart - 1; //since the .text is zero based,but pos is 1 based we subtract 1
        RichEditor.sellength := TagLength;

        TempText := GetValue(ParseValue);
        Memo.SelText := TempText;
        RichEditor.SelText := TempText;
      end;

    except
       on e: exception do
          begin
          MessageDlg(e.message,mtInformation,[mbOK],0);
          result := false;
          end;
       end;//try..except
  finally
    FreeAndNil(Memo);
  end;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读