Nhận tổng kích thước của TCheckbox, bao gồm hộp và văn bản, trong Delphi

Jan 15 2021

Tôi muốn lấy tổng kích thước của TCheckbox, bao gồm cả hộp và văn bản trong Delphi. Tôi kiểm tra bài viết tại Delphi FMX TCheckbox / TRadiobutton Autosize , nhưng có vẻ như TCheckbox không có thuộc tính Canvas nên mã không phù hợp với nó.

Cập nhật

Hãy để tôi giải thích lý do tại sao tôi cần biết điều đó. Trong một số hộp kiểm của tôi, tôi cần đặt một dấu chấm liên quan đến hộp kiểm. Ví dụ: trong hộp kiểm "Chia tệp khi nó có kích thước lớn hơn" ### "Byte", trong đó ### là chỉnh sửa xoay.

Vì hộp kiểm không hỗ trợ kích thước tự động, một cách là phóng to hộp kiểm để nó chứa tất cả các văn bản. Sau đó đặt chỉnh sửa vòng quay sau ký tự hiển thị cuối cùng.

Điều này là tốt cho một ngôn ngữ, tuy nhiên, để hỗ trợ đa ngôn ngữ, một số ngôn ngữ sẽ rất dài hơn những ngôn ngữ khác.

Trong trường hợp như vậy, tôi có thể chọn:

  1. Tính kích thước của phần có thể nhìn thấy checkbxo.

hoặc là

  1. Giữ một số khoảng cách giữa ký tự hiển thị cuối cùng và chỉnh sửa spin.

Phương pháp 2 không tốt lắm vì sẽ có khoảng cách rất lớn giữa hộp kiểm và phần chỉnh sửa xoay đối với một số ngôn ngữ.

Cập nhật 2

Một vấn đề nữa, tôi cố gắng làm điều tương tự cho một nút, như bên dưới:

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;

Vì nút không có bất kỳ ô nào, vì vậy tôi sử dụng size.cx thay vì thêm một số giá trị. Tuy nhiên, trong thử nghiệm của tôi, thực sự độ rộng văn bản không chính xác, điều này làm cho nút không thể tiếp nhận toàn bộ văn bản, hãy xem bên dưới:

Trả lời

2 AndreasRejbrand Jan 15 2021 at 21:20

Đây là hai xu của tôi.

Để có được kích thước của hộp kiểm thực tế, tôi tin rằng bạn nên hỏi API chủ đề 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;

Tương tự, điều này truy xuất chiều rộng của văn bản (chú thích):

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;

Điều vẫn chưa được biết là phần đệm giữa hộp kiểm và chú thích. Tôi không biết cách thích hợp để có được điều này, nhưng có vẻ như nó thường giống với chiều rộng của một khoảng trắng nhất:

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;