3

i want to find the height that needs the TRichEdit control to render itself without showing the vertical scrollbar. I use this code

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;

When the document has a few pages (<15 A4 portrait) the result is sufficient. But with more pages, the rc.bottom seems to be trancated and the control needs the vertical scrollbar. The question is : there are some limitations inside perform's code ? If i increase the rc.bottom manually (approximately) then the control renders itself ok but this isn't the case i want.

PS. if matters, the richedit component, actually is a TjvRichEdit one.

Here is a minimal program that can reproduce the problem (for even 2 pages)

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.

The form

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

and the result with a RTF document (just 2 pages) the document is in RTF mode and as you can see the TjvRichEdit hasn't found its right height to render without its scrollbar

JimPapas
  • 715
  • 2
  • 12
  • 27
  • I don't understand the question. What do you mean by "perform's code"? – Sertac Akyuz Dec 30 '16 at 17:29
  • in this code : RE.`Perform`(EM_FORMATRANGE, 0, Longint(@fmtRange)); – JimPapas Dec 30 '16 at 20:11
  • 1
    Quite likely there would be limitation, not of "perform" but of the control. Perform calls the window procedure of the control with the message and parameters you specify - simulates SendMessage without Dispatch, that's all it does. You can't display 15 A4 pages without a scroll bar on any display, why do you care? – Sertac Akyuz Dec 30 '16 at 20:14
  • I use a scrollbox for this. Making the height enough for all the pages, i can use scrollbox's scrollbar not TRichedit's – JimPapas Dec 30 '16 at 20:51
  • 1
    Ok. Provide a [mcve] if you want anyone to have a look by reproducing the problem. – Sertac Akyuz Dec 30 '16 at 20:59
  • I can reproduce, can't tell the reason. Anyway, I think what you really need is a bottomless rich edit. – Sertac Akyuz Dec 31 '16 at 16:18
  • You need to hide the vertical scroll bar of the rich edit control. – Sertac Akyuz Dec 31 '16 at 16:37
  • No, this isn't the problem. If i hide the scroll bar (and this is exactly what i want) then nothing changes except that i have to use PgDn to see the rest of the doc – JimPapas Dec 31 '16 at 18:44
  • You would scroll the edit with the scrollbox of course. Here it works fine when the edit has no scroll bar. In any case bottomless is better, which the answer implements, although I'm not sure it answers the question. – Sertac Akyuz Jan 01 '17 at 17:11
  • Happy new year Sertac. You are right, the answer doesn't answers the question (why EM_FORMATRANGE doesn't return the right height ... is there a limitation...) but, at least, it works for me. – JimPapas Jan 01 '17 at 17:35
  • Thank you! To you too... :) – Sertac Akyuz Jan 01 '17 at 17:36

1 Answers1

0

Finally, the solution was very simple! TRichedit has the event onResizeRequest where the actual height of the control is given by the rect parameter

JimPapas
  • 715
  • 2
  • 12
  • 27