Получите общий размер TCheckbox, включая поле и текст, в Delphi

Jan 15 2021

Я хочу получить общий размер TCheckbox, включая поле и текст в Delphi. Я проверял статью в Delphi FMX TCheckbox / TRadiobutton Autosize , но мне кажется, что TCheckbox не имеет свойства Canvas, поэтому код для него не подходит.

Обновлять

Позвольте мне объяснить причину, по которой мне нужно это знать. В некоторые из моих флажков мне нужно поставить отметку, связанную с флажком. Например, в чекбоксе «Разделить файл, если его размер больше, чем« ### "байтов», где ### - это изменение вращения.

Поскольку флажок не поддерживает автоматическое изменение размера, один из способов - увеличить флажок, чтобы он умещал все тексты. Затем поместите редактирование вращения после последнего видимого символа.

Это нормально для одного языка, однако для поддержки нескольких языков некоторые языки будут намного длиннее других.

В таком случае я могу выбрать:

  1. Рассчитайте размер видимой части checkbxo.

или же

  1. Сохраняйте пробелы между последним видимым символом и редактированием вращения.

метод 2 не очень хорош, так как для некоторых языков будет огромное расстояние между флажком и редактированием вращения.

Обновление 2

Еще одна проблема, я пытаюсь сделать то же самое для кнопки, как показано ниже:

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

Вот мои два цента.

Чтобы получить фактический размер флажка, я считаю, что вам следует спросить API темы Win32 ( 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;