私は TMemo を持っており、そこに含まれる行数を表示するのに十分な高さに常にしたいと考えています。残念ながら、私はそれを計算する方法をよく知りません。.Font.Size
DPIによって異なるため、プロパティに基づいて設定することはできません。また、TMemoにはキャンバスTCanvas.TextHeight
がないようで使えません。
誰でもこれを正しく行う方法を知っていますか?
問題が発生しました。TMemo のすべての行の高さが等しいと思いますが、一部が空になる可能性があります...
したがって、空のものの高さを取得すると、TMemo の高さはゼロではありませんが、ゼロになります。
したがって、ソリューションはおそらく Memo.Lines.Count*LineHeight のようなことをしています
Canvas.TextHeight はテキストの最小高さの正確な高さを多かれ少なかれ与えるため、Lineheight は Canvas.TextHeight によって取得されない可能性があることに注意してください。など...
(Windows API を呼び出したくない場合) Font.Height を使用することをお勧めしますが、負の場合、各行の内部行送りは測定されません...
したがって、次の手順を実行することをお勧めします(テスト済み):
個人的には、視覚的なフォント サイズが変更されず、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);
これが誰にも役立つことを願っています。
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;
これには 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;
私は当初、TMemo の「Lines」TStrings リスト メンバを参照することを提案しました。
代わりに、親クラス TCustomEdit の "Font" メンバーを見てください。
'それが役立つことを願っています.. PS