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

查看:122
本文介绍了在运行时使用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 用作实际上不需要窗口(仅消息)的窗口的父级。

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

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

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

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