2013-06-03 3 views
2

J'essaye d'écrire une classe de wrapper autour de TRichEdit qui peut encoder et décoder le texte brut de/à partir du texte en clair.Est-ce que TRichEdit supporte Unicode?

C'est ce que j'ai écrit jusqu'à présent:

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; 

Cela semble fonctionner assez bien pour tout ce qui peut être représenté par utilisateur par défaut ANSI codepage.

Il échoue (les convertit en ?) pour d'autres caractères.

Existe-t-il un moyen facile d'activer la gestion Unicode correcte dans mon code?

J'ai essayé d'utiliser TEncoding.Unicode et TEncoding.UTF8 comme encodage pour le TStringStream lorsque le TRichEdit est réglé sur PlainText := True, mais cela ne fonctionne pas.

+0

légèrement hors-sujet: Pourquoi ne vous héritez de la 'TRichEdit' à la place? –

+1

@JerryDodge: Alors ça deviendrait un contrôle. –

+0

@AndreasRejbrand Eh bien oui, c'était mon point. Je me demandais juste pourquoi ce n'est pas un contrôle hérité. –

Répondre

2

Je pense que vous êtes trop compliquer cela. Il n'est pas nécessaire d'utiliser la propriété PlainText. Laissez-le à son réglage par défaut de True. Ensuite, pour lire/écrire RTF utiliser LoadFromStream et SaveToStream. Et pour lire/écrire du texte brut, utilisez la propriété Lines.Text.

C'est à peu près aussi simple que je peux le faire:

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; 
+1

En aparté, je ne suis pas convaincu par 'TRichEdit.CreateParented (HWND_MESSAGE)'. Quand je l'ai utilisé, je trouve que le formatage peut être altéré lors de l'émission RTF. J'utiliser 'TRichEdit.Create (nil)', puis assigner les contrôles 'ParentWindow' à' Application.Handle'. –

+1

L'utilisation de 'LoadFromStream' pour le texte en clair Unicode ne fonctionne donc pas du tout? –

+0

Concernant le parent: Que voulez-vous utiliser dans une application console? –