1

私は TMemo を持っており、そこに含まれる行数を表示するのに十分な高さに常にしたいと考えています。残念ながら、私はそれを計算する方法をよく知りません。.Font.SizeDPIによって異なるため、プロパティに基づいて設定することはできません。また、TMemoにはキャンバスTCanvas.TextHeightがないようで使えません。

誰でもこれを正しく行う方法を知っていますか?

4

4 に答える 4

8

問題が発生しました。TMemo のすべての行の高さが等しいと思いますが、一部が空になる可能性があります...

したがって、空のものの高さを取得すると、TMemo の高さはゼロではありませんが、ゼロになります。

したがって、ソリューションはおそらく Memo.Lines.Count*LineHeight のようなことをしています

Canvas.TextHeight はテキストの最小高さの正確な高さを多かれ少なかれ与えるため、Lineheight は Canvas.TextHeight によって取得されない可能性があることに注意してください。など...

(Windows API を呼び出したくない場合) Font.Height を使用することをお勧めしますが、負の場合、各行の内部行送りは測定されません...

したがって、次の手順を実行することをお勧めします(テスト済み):

  • OnCreate イベントまたは任意の場所で Memo.Font.Height に正の値を割り当てます。これにより、TMemo の lineheight は割り当てた値になります。
  • Memo.Font.Height に正の値を代入しているため、合計の高さは Memo.Lines.Count*LineHeight によって直接取得できるようになりました (Memo.Font.Size が負になることに注意してください)。

個人的には、視覚的なフォント サイズが変更されず、MyMemo.Font.Height に各行の内部の行送りが含まれていることを確認するためだけに、TForm OnCreate イベントでこれを行います (1 回だけ実行されるようにするため)。

MyMemo.Font.Height:=Abs(MyMemo.Font.Size*MyMemo.Font.PixelsPerInch div Screen.PixelsPerInch);

前の手順を 1 回だけ実行するようにしてください。そうしないと、実行するたびにテキスト サイズが視覚的に大きくなります...常に MyMemo.Font.PixelsPerInch が Screen.PixelsPerInch と等しいとは限らないためです...私の場合、それらはそれぞれ 80 と 96 です。

次に、行の高さを知る必要があるときは、次を使用します。

Abs(MyMemo.Font.Height*Screen.PixelsPerInch div 72)

すべての行の高さが同じであるため、合計の高さは次のようになります。

MyMemo.Lines.Count*Abs(MyMemo.Font.Height*Screen.PixelsPerInch div 72)

したがって、TMemo の高さを含まれるテキストと同じくらい大きくするには、次のようにします (各行のコメントを読んでください。非常に重要です)。

MyMemo.Font.Height:=Abs(MyMemo.Font.Size*MyMemo.Font.PixelsPerInch div Screen.PixelsPerInch); // I do this on the Tform OnCreate event, to ensure only done once
MyMemo.Height:=1+MyMemo.Lines.Count*Abs(MyMemo.Font.Height*Screen.PixelsPerInch div 72); // I do this anywhere after adding the text and/or after editing it

Screen.PixelsPerInch で遊びたくない場合は、これを行うことができます (各行のコメントを読んでください。非常に重要です)。

MyMemo.Font.Height:=Abs(MyMemo.Font.Height); // This may make text size to visually change, that was why i use the corrector by using MyMemo.Font.PixelsPerInch and Screen.PixelsPerInch
MyMemo.Height:=1+MyMemo.Lines.Count*Abs(MyMemo.Font.Height*MyMemo.Font.PixelsPerInch div 72);

これが誰にも役立つことを願っています。

于 2012-11-12T10:41:07.613 に答える
4

TMemo の TCanvas.TextHeight の独自の実装を作成できます。

function CountMemoLineHeights(Memo: TMemo): Integer;
var
  DC: HDC;
  SaveFont: HFont;
  Size: TSize;
  I: Integer;

begin
  DC:= GetDC(Memo.Handle);
  SaveFont:= SelectObject(DC, Memo.Font.Handle);
  Size.cX := 0;
  Size.cY := 0;
//  I have not noticed difference in actual line heights for TMemo,
//    so the next line should work OK
  Windows.GetTextExtentPoint32(DC, 'W', 1, Size);
//  BTW next (commented) line returns Size.cY = 0 for empty line (Memo.Lines[I] = '') 
//    Windows.GetTextExtentPoint32(DC, Memo.Lines[I], Length(Memo.Lines[I]), Size);
  Result:= Memo.Lines.Count * Size.cY;
  SelectObject(DC, SaveFont);
  ReleaseDC(Memo.Handle, DC);
end;
于 2011-07-24T05:41:30.153 に答える
3

これには TCanvas を使用する必要があります。バックグラウンドで TBitMap を作成し、その TCanvas を (Memo の Font プロパティを Bitmap.Canvas のプロパティに割り当てた後に) 使用するか、別のコンポーネントから TCanvas を使用することができます。このようなもの:

BMP:=TBitMap.Create;
TRY
  BMP.Canvas.Font.Assign(Memo.Font);
  TotalHeight:=0;
  FOR LineNo:=1 TO Memo.Lines.Count DO INC(TotalHeight,BMP.Canvas.TextHeight(Memo.Lines[PRED(I)]))
FINALLY
  FreeAndNIL(BMP)
END;

編集:

またはおそらくこれ:

BMP:=TBitMap.Create;
TRY
  BMP.Canvas.Font.Assign(Memo.Font);
  LineHeight:=BMP.Canvas.TextHeight('Wq');
  TotalHeight:=Memo.Lines.Count*LineHeight
FINALLY
  FreeAndNIL(BMP)
END;
于 2011-07-24T05:08:59.340 に答える
0

私は当初、TMemo の「Lines」TStrings リスト メンバを参照することを提案しました。

代わりに、親クラス TCustomEdit の "Font" メンバーを見てください。

'それが役立つことを願っています.. PS

于 2011-07-24T04:30:26.227 に答える