Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何获取TMemo中显示的行数?_Delphi_Firemonkey - Fatal编程技术网

Delphi 如何获取TMemo中显示的行数?

Delphi 如何获取TMemo中显示的行数?,delphi,firemonkey,Delphi,Firemonkey,我需要获取TMemo中显示的行数(这包括由于WordWrap设置为true而被包装的行)。我需要这个来自动调整Tmemo的高度以适应它的内容 行。计数当然不关心包装行,所以我不能使用它。奇怪的是,TextPosToPos也不关心换行,所以我也不能使用它 我在firemonkey和delphi Berlin的指导下学习了内容边界。我的原始(和过时的)答案在修订版中仍然可见 为什么需要显示行数来调整TMemo的高度?这会将TMemo的大小调整为其内容: Memo1.Height := Memo1.C

我需要获取TMemo中显示的行数(这包括由于WordWrap设置为true而被包装的行)。我需要这个来自动调整Tmemo的高度以适应它的内容

行。计数当然不关心包装行,所以我不能使用它。奇怪的是,TextPosToPos也不关心换行,所以我也不能使用它


我在firemonkey和delphi Berlin

的指导下学习了
内容边界
。我的原始(和过时的)答案在修订版中仍然可见

为什么需要显示行数来调整
TMemo
的高度?这会将
TMemo
的大小调整为其内容:

Memo1.Height := Memo1.ContentBounds.Height + 5; // Small const to allow for rendering margins

它还考虑了单词换行。

在我了解
内容边界之后进行编辑。我的原始(和过时的)答案在修订版中仍然可见

为什么需要显示行数来调整
TMemo
的高度?这会将
TMemo
的大小调整为其内容:

Memo1.Height := Memo1.ContentBounds.Height + 5; // Small const to allow for rendering margins

它还考虑了单词包装。

我不知道为什么使用ContentBounds“不是很理想”。我是这样做的:

uses
  FMX.TextLayout, FMX.Graphics;

function MeasureTextHeight(const AFont: TFont; const AText: string): Single;
var
  LLayout: TTextLayout;
begin
  LLayout := TTextLayoutManager.DefaultTextLayout.Create;
  try
    LLayout.BeginUpdate;
    try
      LLayout.WordWrap := False;
      LLayout.Font.Assign(AFont);
      LLayout.Text := AText;
    finally
      LLayout.EndUpdate;
    end;
    Result := LLayout.TextHeight;
  finally
    LLayout.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LTextHeight: Single;
  LLines: Integer;
begin
  LTextHeight := MeasureTextHeight(Memo1.TextSettings.Font, Memo1.Text);
  LLines := Round(Memo1.ContentBounds.Height / LTextHeight);
end;

我不知道为什么使用ContentBounds“不是很理想”。我是这样做的:

uses
  FMX.TextLayout, FMX.Graphics;

function MeasureTextHeight(const AFont: TFont; const AText: string): Single;
var
  LLayout: TTextLayout;
begin
  LLayout := TTextLayoutManager.DefaultTextLayout.Create;
  try
    LLayout.BeginUpdate;
    try
      LLayout.WordWrap := False;
      LLayout.Font.Assign(AFont);
      LLayout.Text := AText;
    finally
      LLayout.EndUpdate;
    end;
    Result := LLayout.TextHeight;
  finally
    LLayout.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LTextHeight: Single;
  LLines: Integer;
begin
  LTextHeight := MeasureTextHeight(Memo1.TextSettings.Font, Memo1.Text);
  LLines := Round(Memo1.ContentBounds.Height / LTextHeight);
end;

这是我用来计算firemonkey下TMemo(样式化)的行数的粗略方法:

type
  _TStyledMemoProtectedAccess = class(TStyledMemo);

procedure TALStyledMemo.OnApplyStyleLookupImpl(sender: Tobject);
Var I, j, k, l: integer;
begin

  // TALStyledMemo
  //   TStyledMemo
  //      TLayout
  //         TActiveStyleObject
  //            TLayout
  //            TScrollBar
  //            TScrollBar
  //            TLayout
  //               TSmallScrollBar
  //               TSmallScrollBar
  //   TScrollContent
  for I := 0 to controls.Count - 1 do begin
    if (controls[i] is TStyledMemo) then begin // << TStyledMemo
      fStyledMemo := TStyledMemo(controls[i]);
    end;
  end;

end;

function TALStyledMemo.getLineHeight: Single;
begin
  if fStyledMemo <> nil then result := _TStyledMemoProtectedAccess(fStyledMemo).GetLineHeight
  else result := 0;
end;

function TALStyledMemo.getLineCount: integer;
var aLineHeight: Single;
begin
  aLineHeight := getLineHeight;
  if compareValue(aLineHeight, 0, Tepsilon.Position) > 0 then result := round(ContentBounds.Height / aLineHeight)
  else result := 0;
end;
类型
_TStyledMemoProtectedAccess=类(TStyledMemo);
过程TALStyledMemo.OnApplyStyleLookupImpl(发送方:ToObject);
变量I,j,k,l:整数;
开始
//TALStyledMemo
//TStyledMemo
//特拉约特
//战术目标
//特拉约特
//滚动条
//滚动条
//特拉约特
//滚动条
//滚动条
//滚动内容
对于I:=0的控件。计数-1不开始
如果(controls[i]是TStyledMemo),则开始//0,然后结果:=round(ContentBounds.Height/alinehight)
其他结果:=0;
结束;

这是我用来计算firemonkey下TMemo(样式化)的行数的粗略方法:

type
  _TStyledMemoProtectedAccess = class(TStyledMemo);

procedure TALStyledMemo.OnApplyStyleLookupImpl(sender: Tobject);
Var I, j, k, l: integer;
begin

  // TALStyledMemo
  //   TStyledMemo
  //      TLayout
  //         TActiveStyleObject
  //            TLayout
  //            TScrollBar
  //            TScrollBar
  //            TLayout
  //               TSmallScrollBar
  //               TSmallScrollBar
  //   TScrollContent
  for I := 0 to controls.Count - 1 do begin
    if (controls[i] is TStyledMemo) then begin // << TStyledMemo
      fStyledMemo := TStyledMemo(controls[i]);
    end;
  end;

end;

function TALStyledMemo.getLineHeight: Single;
begin
  if fStyledMemo <> nil then result := _TStyledMemoProtectedAccess(fStyledMemo).GetLineHeight
  else result := 0;
end;

function TALStyledMemo.getLineCount: integer;
var aLineHeight: Single;
begin
  aLineHeight := getLineHeight;
  if compareValue(aLineHeight, 0, Tepsilon.Position) > 0 then result := round(ContentBounds.Height / aLineHeight)
  else result := 0;
end;
类型
_TStyledMemoProtectedAccess=类(TStyledMemo);
过程TALStyledMemo.OnApplyStyleLookupImpl(发送方:ToObject);
变量I,j,k,l:整数;
开始
//TALStyledMemo
//TStyledMemo
//特拉约特
//战术目标
//特拉约特
//滚动条
//滚动条
//特拉约特
//滚动条
//滚动条
//滚动内容
对于I:=0的控件。计数-1不开始
如果(controls[i]是TStyledMemo),则开始//0,然后结果:=round(ContentBounds.Height/alinehight)
其他结果:=0;
结束;

谢谢tom,我实际上做了contentbounds/text.size,但不是真正的idealthanks tom,是的,使用contentbounds很容易,但是我想将备忘录的高度限制为4行,这就是为什么我需要行数Hanks tom,我实际上做了contentbounds/text.size,但不是真正的idealthanks tom,是的,使用contentBounds很容易,但是我想将备忘录的高度限制为4行,这就是为什么我需要行数换行怎么办?这没有考虑宽度限制。事实上,您的代码显式地将其关闭,这与OP所寻找的正好相反。@Jerrydoge我没有在备忘录中关闭WordWrap;再次检查代码。当我说“我就是这样做的”时,我的意思是我已经在使用它了。如果它不起作用,我就不会把它发出去了汉克斯·戴夫!是的,就是这样的工作。不过我用了一种稍有不同的方式(我后来发布了我的答案)。那么换行符呢?这没有考虑宽度限制。事实上,您的代码显式地将其关闭,这与OP所寻找的正好相反。@Jerrydoge我没有在备忘录中关闭WordWrap;再次检查代码。当我说“我就是这样做的”时,我的意思是我已经在使用它了。如果它不起作用,我就不会把它发出去了汉克斯·戴夫!是的,就是这样的工作。然而,我用了一种稍微不同的方式(稍后我发布了我的答案)。