Uzyskaj całkowity rozmiar TCheckbox, w tym ramkę i tekst, w Delphi
Chcę uzyskać całkowity rozmiar TCheckbox, w tym pudełko i tekst w Delphi. Sprawdzam artykuł w Delphi FMX TCheckbox / TRadiobutton Autosize , ale wygląda na to, że TCheckbox nie ma właściwości Canvas, więc kod do niego nie pasuje.
Aktualizacja
Pozwól, że wyjaśnię powód, dla którego muszę to wiedzieć. W niektórych moich polach wyboru muszę umieścić spinedit związany z polem wyboru. Na przykład w polu wyboru „Podziel plik, gdy jego rozmiar jest większy niż„ ### ”Bajty”, gdzie ### jest obrotową edycją.
Ponieważ pole wyboru nie obsługuje automatycznego rozmiaru, jednym ze sposobów jest powiększenie pola wyboru tak, aby mieściło się w nim wszystkie teksty. Następnie umieść edycję wirowania po ostatnim widocznym znaku.
Jest to dobre w przypadku jednego języka, jednak aby obsługiwać wiele języków, niektóre języki będą znacznie dłuższe niż inne.
W takim przypadku mam do wyboru:
- Oblicz rozmiar widocznej części checkbxo.
lub
- Zachowaj odstępy między ostatnim widocznym znakiem a edycją obrotu.
metoda 2 nie jest zbyt dobra, ponieważ w niektórych językach będzie duża odległość między polem wyboru a edycją spinową.
Zaktualizuj 2
Jeszcze jedno, próbuję zrobić to samo dla przycisku, jak poniżej:
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;
Ponieważ przycisk nie ma żadnego pola, więc używam pliku size.cx zamiast dodawać jakąś wartość. Jednak w moim teście faktycznie szerokość tekstu jest nieprawidłowa, co powoduje, że przycisk nie może pomieścić całego tekstu, patrz poniżej:
Odpowiedzi
Oto moje dwa centy.
Aby uzyskać rozmiar rzeczywistego pola wyboru, uważam, że powinieneś zapytać API motywu 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;
Podobnie pobiera szerokość tekstu (podpis):
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;
Nieznane pozostaje wypełnienie między polem wyboru a podpisem. Nie wiem, jak to uzyskać, ale wydaje się, że najczęściej jest to to samo, co szerokość przestrzeni:
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;