我可以根据它包含的文本制作TMemo大小吗? - Firemonkey

时间:2014-02-17 18:27:18

标签: delphi firemonkey

我发现之前已经向VCL询问了this个问题,但我还没有运气,可以将问题的答案用于Firemonkey TMemo

我注意到memo.Lines.Count似乎总是根据我添加的数量来计算行数,而不是因为它们已经格式化(备忘录确实打开了wordwrap)。在不知道这个数字的情况下,我不知道如何开始解决这个问题。

有什么想法吗?

编辑:备忘录的宽度取决于设备的方向,显然,如果宽度改变,显示的行数可能会改变。另外,我不想改变备忘录的字体。

4 个答案:

答案 0 :(得分:4)

Procedure ResizeMemo(AMemo: TMemo);
const
  Offset = 4; //The diference between ContentBounds and ContentLayout
begin
  AMemo.Height := AMemo.ContentBounds.Height + Offset;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ResizeMemo(Memo1);
end;

答案 1 :(得分:1)

以下功能应该可以满足您的需求。它不会更改备忘录中的任何内容,并会考虑字体和任何换行符和换行符。如果将备忘录高度设置为计算值,则需要为边框添加几个像素以消除滚动条。

(将fmx.text添加到XE3的uses语句,对于其他版本可能会有所不同,因为它们会随着每个版本不断更改)

function get_memo_height(amemo:tmemo):single;

var i:integer;
    astring:string;
    layout:ttextlayout;

begin
  Layout := TTextLayoutManager.DefaultTextLayout.Create;
  astring:='';
  for i:=0 to amemo.lines.count-1 do astring:=astring+amemo.lines[i]+chr(10);
  Layout.BeginUpdate;
  Layout.Text :=astring;
  Layout.WordWrap := amemo.wordwrap;
  Layout.HorizontalAlign := amemo.TextAlign;
  Layout.MaxSize := PointF(amemo.width-amemo.VScrollBar.width,maxint);
  Layout.VerticalAlign := tTextAlign.taLeading;
  Layout.Font := amemo.Font;
  Layout.TopLeft := pointf(0,0);
  Layout.EndUpdate;
  result:=layout.textrect.bottom;
  Layout.free;
end;

答案 2 :(得分:1)

这是我的新尝试:

FMX:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 305
  ClientWidth = 333
  FormFactor.Width = 1920
  FormFactor.Height = 1080
  FormFactor.Devices = [dkDesktop]
  DesignerMobile = False
  DesignerWidth = 0
  DesignerHeight = 0
  DesignerDeviceName = ''
  DesignerOrientation = 0
  DesignerOSVersion = ''
  object Memo1: TMemo
    Touch.InteractiveGestures = [igPan, igLongTap, igDoubleTap]
    Anchors = [akLeft, akTop, akRight]
    Height = 257.000000000000000000
    Position.X = 8.000000000000000000
    Position.Y = 8.000000000000000000
    TabOrder = 0
    Width = 312.000000000000000000
    Lines.Strings = (

        'Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 L' +
        'ine 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 '
      'Line 2 Line 2 Line 2 Line 2 Line 2 '
      ''
      'Line 4'

        'Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 L' +
        'ine 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Li' +
        'ne 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Lin' +
        'e 5 Line 5 Line 5 Line 5 Line 5 ')
    Font.Family = 'Arial'
    WordWrap = True
  end
  object Button1: TButton
    Anchors = [akLeft, akTop, akRight]
    Height = 22.000000000000000000
    Position.X = 8.000000000000000000
    Position.Y = 272.000000000000000000
    TabOrder = 1
    Text = 'Show Line Count'
    Width = 312.000000000000000000
    OnClick = Button1Click
  end
  object Memo3: TMemo
    Touch.InteractiveGestures = [igPan, igLongTap, igDoubleTap]
    Height = 50.000000000000000000
    Position.X = 176.000000000000000000
    Position.Y = 184.000000000000000000
    TabOrder = 2
    Visible = False
    Width = 100.000000000000000000
    Lines.Strings = (
      '1')
  end
end

PAS:

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Layouts,
  FMX.Memo, FMX.Text, FMX.StdCtrls, FMX.TextLayout;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Memo3: TMemo;
    procedure Button1Click(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
    layout: TTextLayout;
    cont, LineHeight : real;
begin
  cont := 0;
  layout:= TTextLayout(memo3.Lines.Objects[0]);
  LineHeight := layout.TextHeight;
  for i:= 0 to memo1.Lines.Count-1 do
  begin
    layout:= TTextLayout(memo1.Lines.Objects[i]);
    if Assigned(layout) then
    begin
      cont := cont + (layout.TextHeight / LineHeight);
    end;
  end;
  showmessage('Line count according to firemonkey: ' + inttostr(memo1.Lines.Count));
  showmessage('Real line count: ' + VarToStr(cont));
end;

end.

希望它有所帮助。

答案 3 :(得分:0)

这当然不优雅,但您可以将插入符号移到TMemo的末尾,然后请求CaretPosition

function getLastMemoLineNumber(const memo: TMemo): Integer;
var
    oldCaretPosition: TCaretPosition;
begin
    Assert( Assigned(memo) );
    oldCaretPosition := memo.CaretPosition;

    try
        memo.GoToTextEnd();
        Result := memo.CaretPosition.Line;
    finally
        memo.CaretPosition := oldCaretPosition;
    end;
end;