2010-11-02 23 views
7

Je suis actuellement en train de migrer notre solution logicielle de Delphi 7 vers 2010. La plupart du temps, les changements ont été simples et il ne reste plus qu'un petit nombre d'obstacles à franchir.Chargement du texte RTF de la base de données dans TRichEdit

Sur un formulaire, nous utilisons un TRichEdit qui affiche le texte rtf saisi à partir d'un champ blob dans une base de données MSSQL. Voici comment cela a fonctionné dans Delphi 7:

//Get RTF text from Blob field using TADOQuery 
rtfStream := sql.CreateBlobStream(sql.FieldByName('rtftext'), BmRead) as TMemoryStream; 

//Load into TRichEdit 
RichEdit.PlainText := False; 
RichEdit.Lines.LoadFromStream(rtfStream); 

Ceci afficherait la RTF comme prévu dans le composant TRichEdit, mais le même code dans Delphi 2010 affiche la RTF sous forme de texte avec des onglets entre chaque caractère. Je suppose que cela a beaucoup à voir avec le passage d'Ansi à Unicode, mais je n'ai pas eu de chance pour rectifier le problème.

Toute aide apportée à ce sujet serait grandement appréciée. Merci

Répondre

9

D'accord, je l'ai compris.

Pour charger le texte rtf:

//Get the data from the database as AnsiString 
rtfString := sql.FieldByName('rtftext').AsAnsiString; 

//Write the string into a stream 
stream := TMemoryStream.Create; 
stream.Clear; 
stream.Write(PAnsiChar(rtfString)^, Length(rtfString)); 
stream.Position := 0; 

//Load the stream into the RichEdit 
RichEdit.PlainText := False; 
RichEdit.Lines.LoadFromStream(stream); 

stream.Free; 

Pour sauver le texte rtf:

//Save to stream 
stream := TMemoryStream.Create; 
stream.Clear; 

RichEdit.Lines.SaveToStream(stream); 
stream.Position := 0; 

//Read from the stream into an AnsiString (rtfString) 
if (stream.Size > 0) then begin 
    SetLength(rtfString, stream.Size); 
    if (stream.Read(rtfString[1], stream.Size) <= 0) then 
     raise EStreamError.CreateFmt('End of stream reached with %d bytes left to read.', [stream.Size]); 
end; 

stream.Free; 

//Save to database 
sql.FieldByName('rtftext').AsAnsiString := rtfString; 

Cela m'a pris trop longtemps pour comprendre :) Je suppose que je l'ai appris une chose cependant ... si quelque chose se passe mal dans Delphi 2010, c'est généralement lié à unicode;)

+0

http://kspnew.googlecode.com/svn-history/r334/trunk/additional/bass/AnsiStringStream.pas ou quelque chose de similaire? –

4

Lorsque PlainText est False, LoadFromStream() tente d'abord de charger le code RTF, et si cela échoue, LoadFromStream() tente de charger à nouveau le flux en tant que texte brut. Cela a toujours été le cas dans toutes les versions de Delphi. Avec l'introduction d'Unicode, je suppose que quelque chose aurait pu se casser dans le gestionnaire de callback EM_STREAMIN de LoadFromStream(). Je vous suggère d'entrer dans le code source de LoadFromStream() avec le débogueur et de voir ce qui se passe réellement.

+0

Merci pour le conseil. Je ne pouvais pas tracer dans le code LoadFromStream pour une raison quelconque, mais cela m'a fait penser à la bonne façon qui a conduit à ma solution. –

+1

Traditionnellement, Delphi utilisait RTDEdit v.1.0 et ignorait les versions v.2.0 et v.3.0 * (qui étaient utilisées par RxLib, JediVCL, TRichView, etc.). Et on peut lire que UNICODE est interdit pour EM_STREAMIN par http://msdn.microsoft.com/en-us/library/windows/desktop/bb774302.aspx si Seul Delphi avait TAnsiStringStream ou utilisait des contrôles d'édition RTF plus modernes –

+1

Unicode n'est pas interdit pour 'EM_STREAMIN', il peut être utilisé mais seulement avec le flag' SF_TEXT', ce qui est le cas de 'TRichEdit'. 'SF_UNICODE' n'est pas supporté par RE 1.0, mais' TRichEdit' dans les versions récentes de la VCL (incluant 2010) charge explicitement RE 2.0 (qui charge silencieusement RE 3.0 sur les versions Windows supportant la version 3.0). –