在TRichEdit中加载长RTF文本不起作用

yon*_*joy 5 delphi delphi-xe4

如果将长RTF-sequenz(例如150 000个字符串)流式传输到TRichEdit控件中(在XE4中),则控件不会显示文本,而是显示原始RTF代码:

{\rtf1\ansi\ansicpg1252\deff0...
Run Code Online (Sandbox Code Playgroud)

怎么了?

procedure TForm1.Button1Click(Sender: TObject);
var
    RtfText: string;
    Stream: TStringStream;
begin
    RtfText := GenerateRtfText();

    Stream := TStringStream.Create(RtfText);
    try
        RichEdit2.PlainText := False;
        RichEdit2.Lines.LoadFromStream(Stream); //<--- ERROR: RichEdit displays raw RTF-Code
                                                //     if RtfText is too long
        if StartsText('{\rtf', RichEdit2.Lines.Text) then
        begin
            ShowMessage('Oh no, not converted!');
            //WORKAROUND: 2nd try seems to work...
            //Stream.Position := 0;
            //RichEdit2.Lines.LoadFromStream(Stream);
        end;
    finally
        Stream.Free;
    end;
end;
Run Code Online (Sandbox Code Playgroud)

例如,具有以下RTF生成功能:

function TForm1.GenerateRtfText: string;
var
    I: Integer;
    Stream: TStringStream;
const
    DOES_WORK_COUNT = 10000;
    DOES_NOT_WORK_COUNT = 15000;
begin
    //Fill
    RichEdit1.Lines.BeginUpdate;
    try
        //for I := 0 to DOES_WORK_COUNT do
        for I := 0 to DOES_NOT_WORK_COUNT do
          RichEdit1.Lines.Add(IntToStr(I));
    finally
        RichEdit1.Lines.EndUpdate;
    end;
    //Convert to RTF
    Stream := TStringStream.Create;
    try
        RichEdit1.Lines.SaveToStream(Stream);
        Result := Stream.DataString;
    finally
        Stream.Free;
    end;
end;
Run Code Online (Sandbox Code Playgroud)

编辑:即使复制和粘贴无法正常工作:

这就是我做的:

  • 我将生成的RichEdit1内容(行号1..15000,数字1..15000)复制到notpad.exe中以删除任何RTF
  • 我将记事本的内容复制到RichEdit2中

结果:

  • 只有12773行正确显示.最后一行是12
  • 如果我尝试在TRichEdit中添加另一个char,则没有任何反应
  • 如果我删除10个字符(每个退格)我之后可以添加10个字符...

TRichEdit是否有隐藏的字符限制?

kob*_*bik 5

丰富的编辑控件具有文本限制.

尝试使用EM_EXLIMITTEXTmessage,它设置用户可以键入或粘贴到富编辑控件的文本量的上限.此消息还限制了流式传输RTF(PlainText = False)时可以流式传输到富编辑控件的文本量.但是在流式传输纯文本时不限制控件.

例如:

const
  RE_MAX_TEXT_SIZE = 256000;

SendMessage(RichEdit1.Handle, EM_EXLIMITTEXT, 0, RE_MAX_TEXT_SIZE);
Run Code Online (Sandbox Code Playgroud)

要么:

SendMessage(RichEdit1.Handle, EM_EXLIMITTEXT, 0, $7FFFFFF0);
Run Code Online (Sandbox Code Playgroud)

为最大限度作为实现TRichEditStrings.LoadFromFile():RichEdit.DoSetMaxLength($7FFFFFF0); 但是,DoSetMaxLength()不正确地在源中使用的,因为它应该被称为被加载的流.此外,DoSetMaxLength()根本没有使用TRichEditStrings.LoadFromStream().雷米在他的回答评论中提到了这一点.

  • @yonojoy,欢迎.您最好在创建控件时调用它(一旦它具有有效的句柄),因为它也会影响用户输入/粘贴. (2认同)