Delphi TRichEdit.Perform( EM_FORMATRANGE, 0,Longint(@fmtRange));

Я хочу найти высоту, которая нуждается в TRichEdit контроль, чтобы сделать себя без отображения vertical scrollbar, Я использую этот код

function RichEditHeight(var RE : TRichEdit; aForm : TForm) : integer;
var fmtRange: TFormatRange;
begin
    FillChar(fmtRange, SizeOf(fmtRange), 0);
    with fmtRange do begin
        hDC := aForm.canvas.Handle;
        hdcTarget := hDC;
        rc.left := 0;
        rc.right := (RE.ClientWidth * 1440) div screen.pixelsPerInch;
        rc.top := 0;
        rc.Bottom := MaxInt;
        rcPage := rc;
        chrg.cpMin := 0;
        chrg.cpMax := -1;
    end;
    RE.Perform(EM_FORMATRANGE, 0, Longint(@fmtRange));
    result := round(fmtRange.rc.Bottom*screen.pixelsPerInch/1440);
    RE.Perform(EM_FORMATRANGE, 0, 0);
end;

Когда документ имеет несколько страниц (<15 A4 portrait) результата достаточно. Но с большим количеством страниц rc.bottom, кажется, преобразуется, и элемент управления нуждается в вертикальной полосе прокрутки. Вопрос в том, есть ли некоторые ограничения внутри кода перформанса. Если я увеличу значение rc.bottom вручную (приблизительно), тогда элемент управления будет работать нормально, но это не тот случай, который я хочу.

PS. если имеет значение, компонент richedit фактически является компонентом TjvRichEdit.

Вот минимальная программа, которая может воспроизвести проблему (даже для 2 страниц)

unit Unit32;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, winAPI.richedit, JvExStdCtrls, JvRichEdit, Vcl.ExtCtrls;

type
  TForm32 = class(TForm)
    ScrollBox1: TScrollBox;
    Button1: TButton;
    RichEdit1: TJvRichEdit;
    panel1: TPanel;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var Form32: TForm32;

implementation

{$R *.dfm}

function RichEditHeight(var RE : TjvRichEdit; aForm : TForm) : integer;
var fmtRange: TFormatRange;
begin
    FillChar(fmtRange, SizeOf(fmtRange), 0);
    with fmtRange do begin
    hDC := aForm.canvas.Handle;
    hdcTarget := hDC;
    rc.left := 0;
    rc.right := (RE.ClientWidth * 1440) div screen.pixelsPerInch;
    rc.top := 0;
    rc.Bottom := 500000;
    rcPage := rc;
    chrg.cpMin := 0;
    chrg.cpMax := -1;
    end;
    RE.Perform(EM_FORMATRANGE, 0, Longint(@fmtRange));
    result := round(fmtRange.rc.Bottom*screen.pixelsPerInch/1440);
    RE.Perform(EM_FORMATRANGE, 0, 0);
end;

procedure TForm32.Button1Click(Sender: TObject);
begin
with OpenDialog1 do
if execute then begin
    RichEdit1.lines.LoadFromFile(filename);
    panel1.height := RichEditHeight(RichEdit1,Form32);
end;
end;

end.

Форма

object Form32: TForm32
  Left = 0
  Top = 0
  Caption = 'Form32'
  ClientHeight = 615
  ClientWidth = 874
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object ScrollBox1: TScrollBox
    Left = 0
    Top = 0
    Width = 874
    Height = 615
    Align = alClient
    TabOrder = 0
    ExplicitWidth = 885
    ExplicitHeight = 583
    object Button1: TButton
      Left = 632
      Top = 24
      Width = 75
      Height = 25
      Caption = 'Button1'
      TabOrder = 0
      OnClick = Button1Click
    end
    object panel1: TPanel
      Left = 0
      Top = 0
      Width = 457
      Height = 561
      Caption = 'panel1'
      TabOrder = 1
      object RichEdit1: TJvRichEdit
        Left = 1
        Top = 1
        Width = 455
        Height = 559
        Align = alClient
        Font.Charset = GREEK_CHARSET
        Font.Color = clWindowText
        Font.Height = -11
        Font.Name = 'Tahoma'
        Font.Style = []
        ParentFont = False
        ScrollBars = ssVertical
        SelText = ''
        TabOrder = 0
        ExplicitHeight = 279
      end
    end
  end
  object OpenDialog1: TOpenDialog
    Left = 656
    Top = 88
  end
end

и результат с документом RTF (всего 2 страницы) документ находится в режиме RTF, и, как вы можете видеть, TjvRichEdit не нашел нужную высоту для рендеринга без полосы прокрутки

1 ответ

Наконец, решение было очень простым! TRichedit имеет событие onResizeRequest, где фактическая высота элемента управления задается параметром rect

Другие вопросы по тегам