首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在运行时使用TRichEdit而不定义父级

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

Stack Overflow用户
提问于 2010-07-12 19:07:39
回答 4查看 9.8K关注 0票数 20

我需要在运行时使用TRichEdit来执行here所讨论的从rtf到文本的转换。我成功地做到了这一点,但我必须将一个虚拟窗体设置为父窗体,否则我无法填充TRichedit.Lines。(错误:缺少父级)。我在下面粘贴了我的函数,有没有人能建议一种避免定义父级的方法?你能否对此发表评论,并告诉我你是否找到了更好的想法?

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

代码语言:javascript
复制
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;

更新:在回答之后,我更新了函数,并将其写在这里以供参考:

代码语言:javascript
复制
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;
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-07-12 21:49:33

在Windows中,TRichEdit控件是RichEdit控件的包装。Windows的控件是...好吧..。窗口,它们需要一个窗口句柄才能工作。Delphi需要调用CreateWindow或CreateWindowEx来创建句柄,并且这两个例程都需要一个有效的父窗口句柄才能工作。Delphi尝试使用控件父控件的句柄(这是有意义的!)。幸运的是,人们可以使用另一种构造函数( CreateParanted(HWND)构造函数),微软的好心人编写了HWND_MESSAGE,用作实际上不需要“窗口”(仅限消息传递)的窗口的父窗口。

此代码的工作方式与预期一致:

代码语言:javascript
复制
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;
票数 33
EN

Stack Overflow用户

发布于 2010-07-12 19:25:36

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

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

票数 8
EN

Stack Overflow用户

发布于 2010-07-12 21:40:28

我在没有RichEdit控件的情况下使用DrawRichText来绘制RTF。(IIRC这称为Windowless Rich Edit Controls。)也许你也可以用这个来转换--但是我从来没有尝试过这个。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3227899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档