我们也遇到了这个问题。
我们做“邮件合并”类型的事情,我们有带有合并代码的模板,这些代码被来自外部来源的数据解析和替换。
pos(mystring, RichEdit.Text) 和使用 RichText.SelStart 在 RichEdit 文本中的定位索引之间的索引不匹配破坏了我们的合并。
我没有一个好的答案,但我想出了一个解决方法。这有点麻烦(轻描淡写!),但直到出现更好的解决方案......
解决方法是使用隐藏的 TMemo 并将 RichEdit 文本复制到其中并将 CR/LF 对更改为仅 CR。然后使用 TMemo 使用 pos(string, TMemo) 找到正确的定位,并使用它来获取要在 TRichEdit 中使用的 selstart 位置。
这真的很糟糕,但希望这种解决方法可以帮助其他人在我们的情况下,或者可能激发比我更聪明的人想出更好的解决方案。
我将展示一些示例代码...
由于我们使用 seltext 替换文本,我们需要替换 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;