รับขนาดทั้งหมดของ TCheckbox รวมถึงกล่องและข้อความใน Delphi

Jan 15 2021

ฉันต้องการรับขนาดทั้งหมดของ TCheckbox รวมถึงกล่องและข้อความใน Delphi ฉันตรวจสอบบทความที่Delphi FMX TCheckbox / TRadiobutton Autosizeแต่ดูเหมือนว่า TCheckbox ไม่มีคุณสมบัติ Canvas ดังนั้นรหัสจึงไม่เหมาะกับมัน

อัปเดต

ให้ฉันอธิบายเหตุผลที่ฉันต้องรู้ ในบางช่องทำเครื่องหมายของฉันฉันต้องใส่ spinedit ที่เกี่ยวข้องกับช่องทำเครื่องหมายนั้น ตัวอย่างเช่นในช่องทำเครื่องหมาย "แยกไฟล์เมื่อมีขนาดใหญ่กว่า" ### "ไบต์" โดยที่ ### คือการแก้ไขสปิน

เนื่องจากช่องทำเครื่องหมายไม่รองรับขนาดอัตโนมัติวิธีหนึ่งคือการขยายช่องทำเครื่องหมายเพื่อให้สามารถรองรับข้อความทั้งหมดได้ จากนั้นใส่การแก้ไขการหมุนหลังจากอักขระที่มองเห็นตัวสุดท้าย

นี่เป็นสิ่งที่ดีสำหรับภาษาเดียวอย่างไรก็ตามเพื่อรองรับหลายภาษาบางภาษาจะยาวกว่าภาษาอื่นมาก

ในกรณีนี้ฉันสามารถเลือก:

  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

นี่คือสองเซ็นต์ของฉัน

เพื่อให้ได้ขนาดของช่องทำเครื่องหมายจริงฉันเชื่อว่าคุณควรถาม Win32 theme 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;