Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Исправление загрузки RTF-текста через поток

01.01.2007
Автор: Лагонский Сергей Николаевич

В версии Borland Delphi 3 Client/Server я обнаружил, что при загрузке текста формата RTF методом "LoadFromStream" в компонент TRichEdit он не интерпретируется как RTF, а отображается полностью (со всеми управляющими символами). Разбираясь в исходном тексте модуля COMCTRLS.PAS (дата создания: 4 августа 1997 года, размер: 391728 байт) я нашел причину, из-за которой вышеуказанный метод не работал как надо. Ниже я привожу исходный и исправленный тексты реализации метода "TRichEditStrings.LoadFromStream" (измененные строки отмечены символом "!"):

1. Исходный текст

procedure TRichEditStrings.LoadFromStream(Stream: TStream);
var
 
EditStream: TEditStream;
 
Position: Longint;
 
TextType: Longint;
 
StreamInfo: TRichEditStreamInfo;
 
Converter: TConversion;
begin
 
StreamInfo.Stream := Stream;
 
if FConverter <> nil then
   
Converter := FConverter
 
else
   
Converter := RichEdit.DefaultConverter.Create;
 
StreamInfo.Converter := Converter;
 
try
   
with EditStream do
   
begin
      dwCookie
:= LongInt(Pointer(@StreamInfo));
      pfnCallBack
:= @StreamLoad;
      dwError
:= 0;
   
end;
   
Position := Stream.Position;
   
if PlainText then
     
TextType := SF_TEXT
   
else
     
TextType := SF_RTF;
   
SendMessage(RichEdit.Handle, EM_STREAMIN, TextType, Longint(@EditStream));
   
if (TextType = SF_RTF) and (EditStream.dwError <> 0) then
   
begin
     
Stream.Position := Position;
     
! if PlainText then
       
TextType := SF_RTF
         
!
       
else
       
TextType := SF_TEXT;
 
     
SendMessage(RichEdit.Handle, EM_STREAMIN, TextType, Longint(@EditStream));
     
if EditStream.dwError <> 0 then
       
raise EOutOfResources.Create(sRichEditLoadFail);
   
end;
 
finally
   
if FConverter = nil then
     
Converter.Free;
 
end;
end;

2. Текст с исправлением:

 
procedure
TRichEditStrings.LoadFromStream(Stream: TStream);
var
 
EditStream: TEditStream;
 
Position: Longint;
 
TextType: Longint;
 
StreamInfo: TRichEditStreamInfo;
 
Converter: TConversion;
begin
 
StreamInfo.Stream := Stream;
 
if FConverter <> nil then
   
Converter := FConverter
 
else
   
Converter := RichEdit.DefaultConverter.Create;
 
StreamInfo.Converter := Converter;
 
try
   
with EditStream do
   
begin
      dwCookie
:= LongInt(Pointer(@StreamInfo));
      pfnCallBack
:= @StreamLoad;
      dwError
:= 0;
   
end;
   
Position := Stream.Position;
   
if PlainText then
     
TextType := SF_TEXT
   
else
     
TextType := SF_RTF;
   
SendMessage(RichEdit.Handle, EM_STREAMIN, TextType, Longint(@EditStream));
   
if (TextType = SF_RTF) and (EditStream.dwError <> 0) then
   
begin
     
Stream.Position := Position;
     
! if PlainText then
       
TextType := SF_TEXT
         
!
       
else
       
TextType := SF_RTF;
 
     
SendMessage(RichEdit.Handle, EM_STREAMIN, TextType, Longint(@EditStream));
     
if EditStream.dwError <> 0 then
       
raise EOutOfResources.Create(sRichEditLoadFail);
   
end;
 
finally
   
if FConverter = nil then
     
Converter.Free;
 
end;
end;