Obtenga el tamaño total de TCheckbox, incluidos el cuadro y el texto, en Delphi
Quiero obtener el tamaño total de TCheckbox, incluido el cuadro y el texto en Delphi. Reviso el artículo en Delphi FMX TCheckbox / TRadiobutton Autosize , pero parece que TCheckbox no tiene una propiedad Canvas, por lo que el código no se ajusta a ella.
Actualizar
Déjame explicarte la razón por la que necesito saber eso. En algunas de mis casillas de verificación, necesito poner un spinedit relacionado con la casilla de verificación. Por ejemplo, en la casilla de verificación "Dividir el archivo cuando su tamaño sea mayor que" ### "Bytes", donde ### es la edición de giro.
Dado que la casilla de verificación no admite el tamaño automático, una forma es ampliar la casilla de verificación para que se adapte a todos los textos. Luego coloque la edición de giro después del último carácter visible.
Esto está bien para un solo idioma, sin embargo, para admitir varios idiomas, algunos idiomas serán mucho más largos que otros.
En tal caso, puedo elegir:
- Calcule el tamaño de la parte visible de checkbxo.
o
- Mantenga algunos espacios entre el último carácter visible y la edición de giro.
El método 2 no es muy bueno ya que habrá una gran distancia entre la casilla de verificación y la edición de giro para algunos idiomas.
Actualización 2
Un problema más, trato de hacer lo mismo con un botón, como se muestra a continuación:
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;
Como el botón no tiene ningún cuadro, utilizo size.cx en lugar de agregar algún valor. Sin embargo, en mi prueba, en realidad el ancho del texto no es correcto, lo que hace que el botón no pueda acomodar todo el texto, ver a continuación:
Respuestas
Aquí están mis dos centavos.
Para obtener el tamaño de la casilla de verificación real, creo que debería preguntar a la API del tema 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;
De manera similar, esto recupera el ancho del texto (título):
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;
Lo que permanece desconocido es el relleno entre la casilla de verificación y el título. No sé la forma correcta de obtener esto, pero parece que suele ser el mismo que el ancho de un espacio:
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;