procedure RichEditToCanvas(RichEdit: TRichEdit; Canvas: TCanvas; PixelsPerInch: Integer);
var
ImageCanvas: TCanvas;
fmt: TFormatRange;
begin
ImageCanvas := Canvas;
with fmt do
begin
hdc:= ImageCanvas.Handle;
hdcTarget:= hdc;
// rect needs to be specified in twips (1/1440 inch) as unit
rc:= Rect(0, 0,
ImageCanvas.ClipRect.Right * 1440 div PixelsPerInch,
ImageCanvas.ClipRect.Bottom * 1440 div PixelsPerInch
);
rcPage:= rc;
chrg.cpMin := 0;
chrg.cpMax := RichEdit.GetTextLen;
end;
SetBkMode(ImageCanvas.Handle, TRANSPARENT);
RichEdit.Perform(EM_FORMATRANGE, 1, Integer(@fmt));
// next call frees some cached data
RichEdit.Perform(EM_FORMATRANGE, 0, 0);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
RichEditToCanvas(RichEdit1, Image1.Canvas, Self.PixelsPerInch);
Image1.Refresh;
end;
Вопрос о рендеринге контрола TRichEdit внутри TCanvas!
Ваш код - хороший старт, но он имеет некоторые проблемы и может быть улучшен. Вот подробный анализ того, что происходит:
Вы создаете промежуточный TCanvas (ImageCanvas) и устанавливаете его handle на handle оригинального Canvas. Это не нужно; вы можете использовать объект Canvas напрямую.
Процедура FormatRange используется для рендеринга текста RichEdit-контрола в формате, независимом от устройства. Однако, она не рисует текст на канвасе. Для этого вам нужно использовать функцию TextOut или ExtTextOut (если вам нужно болееadvanced text rendering).
Вы устанавливаете режим фона промежуточного канваса в TRANSPARENT, что не нужно, поскольку вы его не используете.
Вот измененный вариант вашего кода:
procedureRichEditToCanvas(RichEdit:TRichEdit;Canvas:TCanvas;PixelsPerInch:Integer);varhdc:HDC;rect:TRect;beginhdc:=Canvas.Handle;rect:=Rect(0,0,Canvas.ClipRect.Right*1440divPixelsPerInch,Canvas.ClipRect.Bottom*1440divPixelsPerInch);RichEdit.Perform(EM_FORMATRANGE,1,Integer(@RichEdit.FormatRange));RichEdit.Perform(EM_FORMATRANGE,0,0);end;procedureTForm1.Button1Click(Sender:TObject);beginRichEditToCanvas(RichEdit1,Image1.Canvas,Self.PixelsPerInch);Image1.Invalidate;// или Image1.Refresh для принудительного обновленияend;
Обратите внимание, что я удалил промежуточный канвас и упростил код. Вместо установки режима фона мы используем оригинальный объект Canvas.
Также в измененном коде я использовал свойство RichEdit.FormatRange вместо создания нового экземпляра TFormatRange. Это более эффективно и проще для управления.
Наконец, я заменял Image1.Refresh на Image1.Invalidate, что является рекомендованным способом запроса обновления изображения компонента в Delphi. Это будет вызывать перерисовку изображения с обновленным содержимым из RichEdit-контрола.
Надеюсь, это поможет! Если у вас есть дополнительные вопросы или вам нужна помощь, не стесняйтесь обращаться.
Рендеринг текста TRichEdit внутри canvas позволяет использовать метод EM_FORMATRANGE для форматирования текста RichEdit и его последующего отображения на канвасе.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.