在运行时使用TRichEdit而不定义父级

LaB*_*cca 18 delphi rtf trichedit

我需要使用TRichEdit在运行时所讨论的执行RTF文本转换这里.我成功完成了这个但是我不得不设置一个虚拟形式作为父级,如果不能我不能填充TRichedit.Lines.(错误:缺少父级).我在下面粘贴我的功能,有人可以建议一种避免定义父母的方法吗?您是否也可以对此发表评论并告诉我您是否找到了更高效的想法?

注意:我需要一个字符串,而不是TStrings作为输出,这就是为什么它的设计是这样的.

function RtfToText(const RTF: string;ReplaceLineFeedWithSpace: Boolean): string;
var
  RTFConverter: TRichEdit;
  MyStringStream: TStringStream;
  i: integer;
  CustomLineFeed: string;

begin
  if ReplaceLineFeedWithSpace then
    CustomLineFeed := ' '
    else
    CustomLineFeed := #13;
  try
    RTFConverter := TRichEdit.Create(nil);
    try
      MyStringStream := TStringStream.Create(RTF);
      RTFConverter.parent := Form4; // this is the part I don't like
      RTFConverter.Lines.LoadFromStream(MyStringStream);
      RTFConverter.PlainText := True;
      for i := 0 to RTFConverter.Lines.Count - 1 do
      begin
        if i < RTFConverter.Lines.Count - 1 then
          Result := Result + RTFConverter.Lines[i] + CustomLineFeed
          else
          Result := Result + RTFConverter.Lines[i];
      end;
    finally
      MyStringStream.Free;
    end;
  finally
    RTFConverter.Free;
  end;

end;
Run Code Online (Sandbox Code Playgroud)

更新:在答案之后我更新了函数并在此处写入以供参考:

function RtfToText(const RTF: string;ReplaceLineFeedWithSpace: Boolean): string;
var
  RTFConverter: TRichEdit;
  MyStringStream: TStringStream;
begin
  RTFConverter := TRichEdit.CreateParented(HWND_MESSAGE);
  try
    MyStringStream := TStringStream.Create(RTF);
    try
      RTFConverter.Lines.LoadFromStream(MyStringStream);
      RTFConverter.PlainText := True;
      RTFConverter.Lines.StrictDelimiter := True;
      if ReplaceLineFeedWithSpace then
        RTFConverter.Lines.Delimiter := ' '
        else
        RTFConverter.Lines.Delimiter := #13;
      Result := RTFConverter.Lines.DelimitedText;
    finally
      MyStringStream.Free;
    end;
  finally
    RTFConverter.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

Cos*_*und 30

TRichEdit控件是Windows中RichEdit控件的包装器.Windows的控件是......好...... Windows,他们需要一个Window Handle才能工作.Delphi需要调用CreateWindow或CreateWindowEx来创建Handle,并且这两个例程都需要一个有效的父窗口句柄才能工作.Delphi尝试使用控件父级的句柄(这很有意义!).令人高兴的是,可以使用另一种构造函数(CreateParanted(HWND)构造函数),并且Microsoft的好人组成了HWND_MESSAGE用作不需要"窗口"(仅限消息传递)的Windows的父级.

此代码按预期工作:

procedure TForm2.Button2Click(Sender: TObject);
var R:TRichEdit;
    L:TStringList;
begin
  R := TRichEdit.CreateParented(HWND_MESSAGE);
  try
    R.PlainText := False;
    R.Lines.LoadFromFile('C:\Temp\text.rtf');
    R.PlainText := True;

    Memo1.Lines.Text := R.Lines.Text;
  finally 
    R.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

  • 是否可以以线程安全的方式进行此类转换?我假设(并且经过测试)试图在工作线程中执行此操作非常危险. (2认同)

Mas*_*ler 8

这是VCL工作方式的一部分,如果没有一些繁重的解决方法,你就不会让它以不同的方式工作.但是您不需要将虚拟表单定义为父表单; 只需使用您当前的表格并visible := false;在TRichEdit上设置即可.

但是,如果你真的想提高性能,你可能会抛弃你用来构建结果字符串的循环.它必须重新分配和复制内存.使用TrichEdit.Lines的Text属性在每一行之间获取CRLF,使用DelimitedText获取其他一些内容,例如空格.它们使用仅分配一次的内部缓冲区,如果您正在使用大量文本,这将加快连接速度.