У меня проблемы с отображением RTF-форматированного текста между двумя версиями delphi.
Кажется, что TDBRichEdit-Control и TRichEdit-Control возникают проблемы с анализом предоставленного RTF-текста.
Иногда этокажется, чтобы заставить его работать в XE8, вам просто нужно подключить TDBRichEdit к соответствующему полю в наборе данных, но тот же метод может испортить версию Delphi 7.
Итак, мы решили, что справимся с этим черезКод.По сути, мы заменили TDBRichEdits на обычные TRichEdits и поставили RTF через поток.
textstream:=TStringStream.Create(CDS.FieldByName('TEXT').AsString);
try
RichEditFAPLAN.Lines.Clear();
RichEditFAPLAN.Lines.LoadFromStream(textStream);
finally
textstream.Free();
end;
это работало нормально примерно до 1 часа назад, когда я решил переместить приведенный выше код в его собственную глобально доступную функцию.
procedure StreamRichTextTo(ARichEdit:TCustomRichEdit; ADataSet:TDataSet; AFieldName:String);
var
ws:WideString;
Stream:TStringStream;
begin
ARichEdit.Lines.Clear();
if (ADataSet=nil) or (ADataSet.FindField(AFieldName)=nil) or (ADataSet.FieldByName(AFieldName).IsNull) then exit;
ws:=UTF8Decode(ADataSet.FieldByName(AFieldName).AsString);
Stream:=TStringStream.Create(ws);
try
Stream.Position:=0;
ARichEdit.Lines.LoadFromStream(Stream);
finally
Stream.Free();
end;
end;
Я пробовал разные варианты этого кода.С MemoryStream, Widestring, кодировкой UTF8, AnsiString и чем-то еще.
procedure StreamRichTextTo(ARichEdit:TCustomRichEdit; ADataSet:TDataSet; AFieldName:String);
var
{$IFDEF VER150}
ws:WideString;
Stream:TStringStream;
{$ELSE}
s:AnsiString;
//Stream:TMemoryStream;
Stream:TStringStream;
{$ENDIF}
begin
ARichEdit.Lines.Clear();
if (ADataSet=nil) or (ADataSet.FindField(AFieldName)=nil) or (ADataSet.FieldByName(AFieldName).IsNull) then exit;
{$IFDEF VER150}
ws:=UTF8Decode(ADataSet.FieldByName(AFieldName).AsString);
Stream:=TStringStream.Create(ws);
{$ELSE}
{
s:=ADataSet.FieldByName(AFieldName).AsAnsiString;
Stream:=TMemoryStream.Create();
Stream.Clear();
Stream.Write(PAnsiChar(s)^,length(s));
}
s:=ADataSet.FieldByName(AFieldName).AsAnsiString;
Stream:=TStringStream.Create(s,TEncoding.UTF8);
//Stream.WriteString(s);
Stream.Position:=0;
{$ENDIF}
try
ARichEdit.Lines.LoadFromStream(Stream);
finally
Stream.Free();
end;
end;
Все безрезультатно, XE-RTF-Text всегда выглядит либо так, либо просто '':
{\rtf1\fbidis\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 arial;}{\f1\fswiss\fprq2\fcharset0 Arial;}{\f2\fnil arial;}}
\viewkind4\uc1\pard\ltrpar\lang1031\f0\fs20 Gie\'dftemp.: \tab 1350 - 1370 \'b0C
\par \ul\f1 Form fest verklammern und belasten
\par \ulnone\f0
\par \tab\tab\f2
\par }
Более того, оригинальный Код с «текстовым потоком», который я прокомментировал, также больше не работает.
То, что я ищу, - это решение для кода, которое может правильнообрабатывать RTF-текст между различными версиями IDE.
РЕДАКТИРОВАТЬ:
Вот пример кода проекта.Дело в том, что в этом проекте все отлично работает.Я понятия не имею, почему тот же код больше не работает в нашем программном обеспечении, и я не могу его воспроизвести.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Data.DB,
Datasnap.DBClient;
type
TForm1 = class(TForm)
REGoal: TRichEdit;
Button1: TButton;
CDS: TClientDataSet;
RESource: TRichEdit;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure StreamRichTextTo(ARichEdit:TRichEdit; ADataSet:TDataSet; AFieldName:String);
var
Stream:TStringStream;
//{$IFDEF VER150}
ws:WideString;
//{$ELSE}
//{$ENDIF}
begin
ARichEdit.Lines.Clear();
if (ADataSet=nil) or (ADataSet.FindField(AFieldName)=nil) or (ADataSet.FieldByName(AFieldName).IsNull) then exit;
try
//{$IFDEF VER150}
ws:=UTF8Decode(ADataSet.FieldByName(AFieldName).AsString);
Stream:=TStringStream.Create(ws);
//{$ELSE}
// Stream:=TStringStream.Create(ADataSet.FieldByName(AFieldName).AsString);
//{$ENDIF}
ARichEdit.Lines.LoadFromStream(Stream);
finally
Stream.Free();
end;
end;
(* Copy this to RESource
{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 arial;}{\f1\fnil arial;}}
\viewkind4\uc1\pard\lang1031\f0\fs20 Erste Form ist eine Zulegekontrolle durchzuf\fchren.
\par
\par
\par \f1
\par }
*)
procedure TForm1.Button1Click(Sender: TObject);
var
Stream:TStringStream;
begin
if CDS.FindField('TEXT')=nil then
begin
CDS.FieldDefs.Add('TEXT',ftWideString,4096);
CDS.CreateDataSet();
end;
CDS.Edit();
CDS.FieldByName('TEXT').AsString:=RESource.text;
CDS.Post();
StreamRichTextTo(REGoal,CDS,'TEXT');
end;
- Просто создайте новую форму 1
- Добавьте 2 TRichEdits, одинназывается RESource, а другой REGoal
- добавляет TClientDataSet и называет его CDS
- Добавить кнопку
- Назначить процедуру OnClick для кнопки
Я попытаюсь создать проект в D7 и затем перенести его на XE8, возможно, это воспроизведет эффект.
РЕДАКТИРОВАТЬ 2: Создание проекта в Delphi 7 и затем его открытиев XE8 выдает тот же результат.
Я предполагаю, что что-то происходит, когда Database-Value присваивается String-Variable (или передается непосредственно в поток), поэтому я не могучтобы воспроизвести ошибку.
Также, возможно, ошибка в базе данных.это база данных Firebird 3.0 с полем VarChar