问题
I'm trying to write a wrapper class around TRichEdit that can encode and decode RTF to/from plaintext.
This is what I've written so far:
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;
This seems to be working reasonably well for everything that can be represented by the user default ANSI codepage.
It fails (converts them to ?) for other characters though.
Is there an easy way to enable correct Unicode handling in my code?
I tried to use TEncoding.Unicode and TEncoding.UTF8 as the encoding for the TStringStream when the TRichEdit is set to PlainText := True, but that doesn't work.
回答1:
I think you are over-complicating this. There's no need to use the PlainText property at all. Leave it at its default setting of True. Then, to read/write RTF use LoadFromStream and SaveToStream. And to read/write plain text use the Lines.Text property.
This is about as simple as I can make it:
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;
来源:https://stackoverflow.com/questions/16902084/does-trichedit-support-unicode