Delphi'de kutu ve metin dahil olmak üzere TCheckbox'ın toplam boyutunu alın

Jan 15 2021

Kutu ve Delphi'deki metin dahil olmak üzere TCheckbox'ın toplam boyutunu almak istiyorum. Delphi FMX TCheckbox / TRadiobutton Autosize'daki makaleye bakıyorum , ancak TCheckbox'ın Canvas özelliği olmadığı için kod buna uymuyor gibi görünüyor.

Güncelleme

Bunu neden bilmem gerektiğini açıklamama izin verin. Bazı onay kutularımda, onay kutusu ile ilgili bir işaret koymam gerekiyor. Örneğin, "###" Bayt "dan büyük olduğunda dosyayı böl" onay kutusunda, burada ### döndürme düzenlemesidir.

Onay kutusu otomatik boyutlandırmayı desteklemediğinden, bir yol, onay kutusunu tüm metinlere uyacak şekilde büyütmektir. Ardından, döndürme düzenlemesini görünen son karakterden sonra yerleştirin.

Bu tek dil için iyidir, ancak çoklu dili desteklemek için bazı diller diğerlerinden çok daha uzun olacaktır.

Böyle bir durumda şunları seçebilirim:

  1. Checkbxo görünür parçasının boyutunu hesaplayın.

veya

  1. Son görünür karakter ile döndürme düzenlemesi arasında biraz boşluk bırakın.

Yöntem 2, bazı diller için onay kutusu ve döndürme düzenlemesi arasında çok büyük bir mesafe olacağından çok iyi değildir.

Güncelleme 2

Bir sorun daha, aşağıdaki gibi bir düğme için aynı şeyi yapmaya çalışıyorum:

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;

Düğmenin herhangi bir kutusu olmadığı için, bir değer eklemek yerine size.cx'i kullanıyorum. Bununla birlikte, benim testimde, aslında metin genişliği doğru değil, bu da düğmenin tüm metne eşlik edememesine neden oluyor, aşağıya bakın:

Yanıtlar

2 AndreasRejbrand Jan 15 2021 at 21:20

İşte benim iki sentim.

Gerçek onay kutusunun boyutunu almak için, Win32 tema API'sına ( uses UxTheme) sormanız gerektiğine inanıyorum :

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;

Benzer şekilde, bu, metnin (başlık) genişliğini alır:

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;

Bilinmeyen kalan, onay kutusu ile başlık arasındaki dolgu. Bunu elde etmenin doğru yolunu bilmiyorum, ancak çoğu zaman bir alanın genişliğiyle aynı gibi görünüyor:

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;