Ваши юниты выключены. Рассмотрим это выражение из вашего кода, например:
RichText.Width * Screen.Pixelsperinch
Левый член указан в пикселях, а правый - в пикселях / дюйм, поэтому в качестве единиц результата используются пиксели² / дюйм. Ожидаемая единица измерения для прямоугольников, используемых в em_FormatRange
, - это двойки. Если вы хотите конвертировать пиксели в твипы, вам нужно:
const
TwipsPerInch = 1440;
RichText.Width / Screen.PixelsPerInch * TwipsPerInch
Вам не нужен закадровый элемент управления rich-edit. Вам просто необходим элемент управления rich-edit без окон , который вы можете настроить для рисования прямо на подсказке. Я опубликовал некоторый код Delphi, который упрощает основы. Остерегайтесь того, что он не поддерживает Unicode, и у меня нет планов сделать это (хотя это может быть не слишком сложно сделать).
Основная функция из моего кода - DrawRTF
, показанная ниже, в RTFPaint.pas . Это не совсем соответствует вашим потребностям, хотя; Вы хотите обнаружить размер перед его рисованием, в то время как мой код предполагает, что вы уже знаете размеры цели рисования. Чтобы измерить размер текста RTF, звоните ITextServices.TxGetNaturalSize
.
Перенос слов важен. Без этого элемент управления будет предполагать, что он имеет бесконечную ширину для работы, и он только начнет новую строку, когда RTF-текст запросит его.
procedure DrawRTF(Canvas: TCanvas; const RTF: string; const Rect: TRect;
const Transparent, WordWrap: Boolean);
var
Host: ITextHost;
Unknown: IUnknown;
Services: ITextServices;
HostImpl: TTextHostImpl;
Stream: TEditStream;
Cookie: TCookie;
res: Integer;
begin
HostImpl := TDrawRTFTextHost.Create(Rect, Transparent, WordWrap);
Host := CreateTextHost(HostImpl);
OleCheck(CreateTextServices(nil, Host, Unknown));
Services := Unknown as ITextServices;
Unknown := nil;
PatchTextServices(Services);
Cookie.dwCount := 0;
Cookie.dwSize := Length(RTF);
Cookie.Text := PChar(RTF);
Stream.dwCookie := Integer(@Cookie);
Stream.dwError := 0;
Stream.pfnCallback := EditStreamInCallback;
OleCheck(Services.TxSendMessage(em_StreamIn, sf_RTF or sff_PlainRTF,
lParam(@Stream), res));
OleCheck(Services.TxDraw(dvAspect_Content, 0, nil, nil, Canvas.Handle,
0, Rect, PRect(nil)^, PRect(nil)^, nil, 0, txtView_Inactive));
Services := nil;
Host := nil;
end;