Delphiで、ボックスとテキストを含むTCheckboxの合計サイズを取得します

Jan 15 2021

Delphiのボックスとテキストを含むTCheckboxの合計サイズを取得したいと思います。Delphi FMX TCheckbox / TRadiobutton Autosizeで記事を確認しましたが、TCheckboxにはCanvasプロパティがないため、コードが適合していません。

更新

私がそれを知る必要がある理由を説明させてください。一部のチェックボックスでは、チェックボックスに関連するスピンエディットを配置する必要があります。たとえば、[サイズが大きい場合はファイルを分割する]チェックボックスで### "Bytes"、ここで###はスピン編集です。

チェックボックスは自動サイズ変更をサポートしていないため、1つの方法は、チェックボックスを拡大してすべてのテキストを収容することです。次に、最後に表示された文字の後にスピン編集を配置します。

これは単一言語では問題ありませんが、複数言語をサポートするために、一部の言語は他の言語よりも非常に長くなります。

そのような場合、私は選択することができます:

  1. checkbxoの可視部分のサイズを計算します。

または

  1. 最後に表示された文字とスピン編集の間にスペースを入れてください。

一部の言語では、チェックボックスとスピン編集の間に大きな距離があるため、方法2はあまり良くありません。

アップデート2

もう1つの問題は、以下のように、ボタンに対して同じことをしようとしています。

var
  bmp: TBitmap;
  size: TSize;
  width: Integer;
begin
  Checkbox1.Caption := Edit3.Text;
  Button3.Caption := Edit3.Text;

  bmp := TBitmap.Create;
  try
    bmp.SetSize(CheckBox1.Width, CheckBox1.Height);
    bmp.Canvas.Font := CheckBox1.Font;
    size := bmp.Canvas.TextExtent(CheckBox1.Caption);
    Width := bmp.Canvas.TextWidth(Checkbox1.Caption);
    CheckBox1.Width := size.cx + 20;
    button3.Width := size.cx;
    SpinEdit1.Left := Checkbox1.Left + Checkbox1.Width + 5;
  finally
    bmp.Free;
  end;
end;

ボタンにはボックスがないので、値を追加する代わりにsize.cxを使用します。ただし、私のテストでは、実際にはテキストの幅が正しくないため、ボタンでテキスト全体を表示できません。以下を参照してください。

回答

2 AndreasRejbrand Jan 15 2021 at 21:20

これが私の2セントです。

実際のチェックボックスのサイズを取得するには、Win32テーマAPI(uses UxTheme)に問い合わせる必要があると思います。

var
  h: HTHEME;
  S: TSize;
begin

  h := OpenThemeData(Handle, 'BUTTON');
  try

    if Succeeded(GetThemePartSize(h, Canvas.Handle, BP_CHECKBOX,
      CBS_UNCHECKEDNORMAL, nil, TS_DRAW, S))
    then
      ShowMessage('Check box width: ' + S.cx.ToString);

  finally
    CloseThemeData(h);
  end;

同様に、これはテキストの幅(キャプション)を取得します。

var
  h: HTHEME;
  R: TRect;
begin

  h := OpenThemeData(Handle, 'BUTTON');
  try

    if Succeeded(GetThemeTextExtent(h, Canvas.Handle, BP_CHECKBOX,
      CBS_UNCHECKEDNORMAL, PChar(CheckBox1.Caption),
      Length(CheckBox1.Caption), 0, nil, R))
    then
      ShowMessage('Caption width: ' + R.Width.ToString);

  finally
    CloseThemeData(h);
  end;

不明な点は、チェックボックスとキャプションの間のパディングです。これを取得する正しい方法はわかりませんが、ほとんどの場合、スペースの幅と同じであるようです。

var
  h: HTHEME;
  S: TSize;
  R: TRect;
begin

  h := OpenThemeData(Handle, 'BUTTON');
  try

    if Succeeded(GetThemePartSize(h, Canvas.Handle, BP_CHECKBOX,
      CBS_UNCHECKEDNORMAL, nil, TS_DRAW, S))
    then
      ShowMessage('Check box width: ' + S.cx.ToString);

    if Succeeded(GetThemeTextExtent(h, Canvas.Handle, BP_CHECKBOX,
      CBS_UNCHECKEDNORMAL, PChar(#32+CheckBox1.Caption),
      1+Length(CheckBox1.Caption), 0, nil, R))
    then
      ShowMessage('Caption width including padding: ' + R.Width.ToString);

  finally
    CloseThemeData(h);
  end;