【问题标题】:Does TRichEdit support Unicode?TRichEdit 是否支持 Unicode?
【发布时间】:2013-05-29 22:03:56
【问题描述】:

我正在尝试围绕TRichEdit 编写一个包装类,它可以将RTF 编码和解码到/从纯文本。

这是我目前写的:

type
  TRTF = class
  private
    FRichEdit : TRichEdit;
    procedure SetText(const AText: string);
    function GetText: string;
    class function Convert(const AInput: string; AEncode: Boolean): string; inline; static;
  public
    constructor Create;
    destructor Destroy; override;
    class function Decode(const AInput: string): string; static;
    class function Encode(const AInput: string): string; static;
  end;

constructor TRTF.Create;
begin
  FRichEdit := TRichEdit.CreateParented(HWND_MESSAGE);
end;

destructor TRTF.Destroy;
begin
  FRichEdit.Free;
  inherited;
end;

function TRTF.GetText: string;
var
  Stream: TStringStream;
begin
  if FRichEdit.PlainText then begin
    Stream := TStringStream.Create('', TEncoding.ANSI);
  end else begin
    Stream := TStringStream.Create('', TEncoding.ASCII);
  end;
  try
    FRichEdit.Lines.SaveToStream(Stream, Stream.Encoding);
    Result := Stream.DataString;
  finally
    Stream.Free;
  end;
end;

procedure TRTF.SetText(const AText: string);
var
  Stream: TStringStream;
begin
  if FRichEdit.PlainText then begin
    Stream := TStringStream.Create(AText, TEncoding.ANSI);
  end else begin
    Stream := TStringStream.Create(AText, TEncoding.ASCII);
  end;
  try
    Stream.Seek(0, TSeekOrigin.soBeginning);
    FRichEdit.Lines.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

class function TRTF.Convert(const AInput: string; AEncode: Boolean): string;
var
  RTF: TRTF;
begin
  RTF := TRTF.Create;
  try
    RTF.FRichEdit.PlainText := AEncode;
    RTF.SetText(AInput);
    RTF.FRichEdit.PlainText := not AEncode;
    Result := RTF.GetText;
  finally
    RTF.Free;
  end;
end;

class function TRTF.Encode(const AInput: string): string;
begin
  Result := Convert(AInput, True);
end;

class function TRTF.Decode(const AInput: string): string;
begin
  Result := Convert(AInput, False);
end;

对于用户默认 ANSI 代码页可以表示的所有内容,这似乎工作得相当好。

但对于其他字符,它会失败(将它们转换为?)。

有没有一种简单的方法可以在我的代码中启用正确的 Unicode 处理?

TRichEdit 设置为PlainText := True 时,我尝试使用TEncoding.UnicodeTEncoding.UTF8 作为TStringStream 的编码,但这不起作用。

【问题讨论】:

  • 有点题外话:你为什么不从TRichEdit 继承呢?
  • @JerryDodge:那么它就会变成一个控件。
  • @AndreasRejbrand 好吧,这就是我的观点。我只是想知道为什么它不是继承控件。
  • @Jerry 因为 Jens 想要一个非可视类来执行与 RTF 之间的文本处理。
  • @DavidHeffernan:那么 Jens 根本不应该使用 TRichEdit。 Jens 应该改用Windowless RichEdit control

标签: delphi unicode delphi-xe2 rtf richtext


【解决方案1】:

我认为你过于复杂了。根本不需要使用 PlainText 属性。将其保留为默认设置 True。然后,要读/写 RTF,请使用 LoadFromStreamSaveToStream。要读取/写入纯文本,请使用 Lines.Text 属性。

这是我能做到的最简单的:

type
  TRTF = class
  strict private
    class function CreateRichEdit: TRichEdit; static;
  public
    class function Decode(const AInput: string): string; static;
    class function Encode(const AInput: string): string; static;
  end;

class function TRTF.CreateRichEdit: TRichEdit;
begin
  Result := TRichEdit.CreateParented(HWND_MESSAGE);
end;

class function TRTF.Encode(const AInput: string): string;
var
  RichEdit: TRichEdit;
  Stream: TStringStream;
begin
  RichEdit := CreateRichEdit;
  try
    RichEdit.Lines.Text := AInput;
    Stream := TStringStream.Create;
    try
      RichEdit.Lines.SaveToStream(Stream);
      Result := Stream.DataString;
    finally
      Stream.Free;
    end;
  finally
    RichEdit.Free;
  end;
end;

class function TRTF.Decode(const AInput: string): string;
var
  RichEdit: TRichEdit;
  Stream: TStringStream;
begin
  RichEdit := CreateRichEdit;
  try
    Stream := TStringStream.Create(AInput);
    try
      RichEdit.Lines.LoadFromStream(Stream);
      Result := RichEdit.Lines.Text;
    finally
      Stream.Free;
    end;
  finally
    RichEdit.Free;
  end;
end;

【讨论】:

  • 顺便说一句,我不相信TRichEdit.CreateParented(HWND_MESSAGE)。当我使用它时,我发现在发出 RTF 时它的格式可能会被破坏。我会使用TRichEdit.Create(nil),然后将控件ParentWindow 分配给Application.Handle
  • 那么使用LoadFromStream 处理Unicode 明文根本不起作用?
  • 关于父母:你会在控制台应用程序中使用什么?
  • @JensMühlenhoff LoadFromStream 与 Unicode 纯文本由代码提供。老实说,我并没有试图理解你的代码哪里出错了。我只是从头开始编写自己的版本。
  • 在非视觉作品中使用带窗口的TRichEdit 是不正确的。微软为非可视 RTF 工作提供了一个完全独立的 API:Windowless RichEdit controls;
猜你喜欢
  • 1970-01-01
  • 2016-11-04
  • 1970-01-01
  • 1970-01-01
  • 2020-03-22
  • 2011-08-15
  • 2012-03-18
  • 1970-01-01
相关资源
最近更新 更多