在运行时使用 TRichEdit 而不定义父级 [英] Using TRichEdit at runtime without defining a parent

查看:22
本文介绍了在运行时使用 TRichEdit 而不定义父级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在运行时使用 TRichEdit 来执行 rtf 到文本的转换,正如所讨论的 此处.我成功地做到了这一点,但如果不是我无法填充 TRichedit.Lines,我必须将一个虚拟表单设置为父表单.(错误:父母失踪).我在下面粘贴了我的函数,有人可以建议一种避免定义父级的方法吗?您能否对此发表评论并告诉我您是否发现了更高效的想法?

I need to use a TRichEdit at runtime to perform the rtf to text conversion as discussed here. I succeded in doing this but I had to set a dummy form as parent if not I cannot populate the TRichedit.Lines. (Error: parent is missing). I paste my funciton below, can anyone suggest a way to avoid to define a parent? Can you also comment on this and tell me if you find a more performant idea?

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

Note: I need a string, not TStrings as output, this is why it has been designed like this.

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;

更新:回答完我更新了函数,写在这里供参考:

UPDATE: After the answer I updated the function and write it here for reference:

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;

推荐答案

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

TRichEdit control is an wrapper around the RichEdit control in Windows. Windows's controls are... well.. Windows, and they need an Window Handle to work. Delphi needs to call CreateWindow or CreateWindowEx to create the Handle, and both routines need an valid parent Window Handle to work. Delphi tries to use the handle of the control's parent (and it makes sense!). Happily one can use an alternative constructor (the CreateParanted(HWND) constructor) and the nice people at Microsoft made up the HWND_MESSAGE to be used as parent for windows that don't actually need a "window" (messaging-only).

此代码按预期工作:

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	ext.rtf');
    R.PlainText := True;

    Memo1.Lines.Text := R.Lines.Text;
  finally 
    R.Free;
  end;
end;

这篇关于在运行时使用 TRichEdit 而不定义父级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆