Rufen Sie die Gesamtgröße der TCheckbox einschließlich Feld und Text in Delphi ab

Jan 15 2021

Ich möchte die Gesamtgröße der TCheckbox erhalten, einschließlich der Box und des Textes in Delphi. Ich überprüfe den Artikel bei Delphi FMX TCheckbox / TRadiobutton Autosize , aber es scheint, dass TCheckbox keine Canvas-Eigenschaft hat, sodass der Code nicht dazu passt.

Aktualisieren

Lassen Sie mich den Grund erklären, warum ich das wissen muss. In einigen meiner Kontrollkästchen muss ein Spinedit für das Kontrollkästchen eingefügt werden. Beispiel: Aktivieren Sie im Kontrollkästchen "Datei teilen, wenn sie größer als" ### "Bytes" ist, wobei ### die Drehbearbeitung ist.

Da das Kontrollkästchen die automatische Größe nicht unterstützt, besteht eine Möglichkeit darin, das Kontrollkästchen so zu vergrößern, dass es alle Texte enthält. Setzen Sie dann die Drehbearbeitung nach dem letzten sichtbaren Zeichen.

Dies ist in Ordnung für eine einzelne Sprache. Um jedoch mehrere Sprachen zu unterstützen, sind einige Sprachen sehr lang als die anderen.

In einem solchen Fall kann ich wählen:

  1. Berechnen Sie die Größe des sichtbaren Teils von checkbxo.

oder

  1. Lassen Sie zwischen dem letzten sichtbaren Zeichen und der Drehbearbeitung einige Leerzeichen.

Methode 2 ist nicht sehr gut, da bei einigen Sprachen ein großer Abstand zwischen dem Kontrollkästchen und der Drehbearbeitung besteht.

Update 2

Noch ein Problem, ich versuche dasselbe für eine Schaltfläche zu tun, wie unten:

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;

Da die Schaltfläche kein Feld enthält, verwende ich die Datei size.cx, anstatt einen Wert hinzuzufügen. In meinem Test ist die Textbreite jedoch nicht korrekt, sodass die Schaltfläche nicht den gesamten Text aufnehmen kann (siehe unten):

Antworten

2 AndreasRejbrand Jan 15 2021 at 21:20

Hier sind meine zwei Cent.

Um die Größe des tatsächlichen Kontrollkästchens zu ermitteln, sollten Sie meines Erachtens die Win32-Design-API ( uses UxTheme) fragen :

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;

In ähnlicher Weise wird die Breite des Textes (Beschriftung) abgerufen:

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;

Unbekannt bleibt der Abstand zwischen dem Kontrollkästchen und der Beschriftung. Ich weiß nicht, wie ich das richtig erreichen kann, aber es scheint, dass es meistens der Breite eines Raums entspricht:

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;