2014-02-17 42 views
3

我发现this问题已经为VCL问过,但我没有任何运气获得该问题上Firemonkey TMemo工作的答案。我可以根据它包含的文本制作TMemo大小吗? - Firemonkey

我注意到,memo.Lines.Count似乎总是基于我添加的行数来计算行数,而不是格式化(备忘录确实打开了wordwrap)。不知道这个数字我不确定如何开始解决这个问题。

任何想法?

编辑:备忘录的宽度将取决于装置的定向,很明显,如果宽度改变显示可以改变的行数。另外,我想不改变备忘录的字体。

+0

如何使用具有'DT_CALC_RECT'标志的'DrawTextEx'? –

+0

等一下,Firemonkey,那不起作用 –

回答

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

这很好。我很高兴有一个简单的解决方案。 – Sentient

+1

只是一个简单的参考:当我试图在FormResize事件中调整我的备忘录时发现ContentBounds已经失效。在调整大小之前添加'Memo.RealignContent'。 – Sentient

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; 
+1

不幸的是,这有同样的问题。我得到的结果是我添加的行数,而不是备忘录中显示的行数。任何由wordwrap导致的行都不计算在内。 – Sentient

+0

@ Sentient:它适用于我在XE5上。你的Delphi/FireMonkey版本是什么?你如何插入你的文字?我通过在键盘上输入并输入了一行,导致一个或几个换行符只计为一行。 –

+0

我想你是在描述我所看到的问题。如果我添加一条缠绕两遍的线,所以它实际上显示为3,我无法知道备忘录实际应该有多大。我需要知道的调整备忘录的是显示多少行。 – Sentient

0

下面的函数应该给你你想要的东西。它不会更改备忘录中的任何内容,并会考虑字体和任何换行符和换行。如果将备忘录高度设置为计算值,则需要为边框添加几个像素以消除滚动条。

(添加fmx.text到使用语句XE3,因为他们不断变化的东西在每个版本中,可能是其他的版本不同)

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; 
+0

memo1.height:= get_memo_height(memo1)+4似乎很好地工作 –

+0

我使用XE5,似乎没有memo.VScrollBar属性。 – Sentient

+0

对XE4,XE5使用contentbounds解决方案,但这对XE3不起作用。实际上,每次发布都必须在Firemonkey中重写任何内容,因此即使有维护,我仍然使用XE3。 –

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. 

希望它有助于。

+0

这对于获得行数非常有用。我不知道TTextLayout。 – Sentient

+0

很高兴帮助,@Sentient –

相关问题