在运行时使用 TRichEdit 而不定义父级 [英] Using TRichEdit at runtime without defining a parent
问题描述
我需要在运行时使用 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屋!