Для того, чтобы компонент TRichEdit сохранял символы национальных алфавитов в
их натуральном виде, а не в виде шестнадцатиричных кодов, необходимо создать
специальный конвертор и зарегистрировать его в компоненте. Конвертор наследуется
от класса TConversion, в котором определены два виртуальных метода
ConvertReadStream и ConvertWriteStream, которые отвечают за преобразование
потока символов соответственно при чтении и записи файла. Чтение файла,
содержащего русские символы, происходит корректно и без применения специальных
мер, поэтому мы должны перекрыть только метод записи. В перекрытом методе
необходимо разместить код, преобразующий шестнадцатиричные коды в символы
русского алфавита. Ниже приведен пример русификации (redMain - компонент типа
TRichEdit).
type
// Объявляем класс конвертора.
TRussianConvertor=class(TConversion)
// Перекрываем только метод записи в поток.
function ConvertWriteStream(Stream: TStream; Buffer: PChar;
BufSize: Integer): Integer; override;
end;
// Реализация метода записи в поток.
function TRussianConvertor.ConvertWriteStream(Stream: TStream;
Buffer: PChar; BufSize: Integer): Integer;
type
// Тип, упрощающий анализ потока символов.
TFourChars = record
HexTag,HexCode: array[0..1] of Char;
end;
PFourChars=^TFourChars;
var
RusBuffer: PChar;
i,RusSize: Integer;
// Функция, преобразующая двухсимвольное
// Hex-представление в символ.
function HexToChar(Hex: PChar): Char;
function HexNumber(C: Char): Integer;
begin
C:=UpCase(C);
case C of
'0'..'9': Result:=Ord(C)-Ord('0');
'A'..'F': Result:=Ord(C)-Ord('A')+10;
else Result:=0;
end;
end;
begin
Result:=Chr(HexNumber(Hex[0])*16+HexNumber(Hex[1]));
end;
begin
RusBuffer:=StrAlloc(BufSize);
RusSize:=0;
i:=0;
// Цикл по всем символам.
while i<BufSize do
begin
with PFourChars(@Buffer[i])^ do
// Hex-представление символа.
if HexTag='\''' then
begin
RusBuffer[RusSize]:=HexToChar(HexCode);
Inc(i,4);
end
else
// Все остальные случаи.
begin
RusBuffer[RusSize]:=Buffer[i];
Inc(i);
end;
Inc(RusSize);
end;
// Запись нового буфера в поток.
Result:=Stream.Write(RusBuffer^,Pred(RusSize));
StrDispose(RusBuffer);
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
// Регистрация конвертора для расширения rft.
redMain.RegisterConversionFormat('rtf',TRussianConvertor);
end;
По аналогичному принципу может быть построен, например, конвертор,
позволяющий загружать и сохранять файлы в формате Microsoft Word.
|