Obliczanie rozmiaru tekstu przed rysowaniem na płótnie
Używam Delphi 7. Jestem bardziej niż zaznajomiony z używaniem płótna i rysowaniem tekstu na płótnie, a także używaniem TCanvas.TextHeight itp. Problem pojawia się, gdy chcę zaimplementować Zawijanie Worda. Nie tylko potrzebuję najlepszego sposobu rysowania tekstu na płótnie i automatycznego zawijania go do określonego ograniczenia szerokości, ale także muszę wiedzieć, jak wysoko (lub ile linii)będzie po zawinięciu. Zanim narysuję tekst, muszę przygotować inny obrazek, który musi być wystarczająco duży, aby umieść zawinięty tekst. Jest to próba powtórzenia, jak iPhone wyświetla wiadomości SMS, z balonem po obu stronach ekranu w zmiennej wysokości przewijania pole (TScrollingWinControl jest moją bazą).
1 answers
Użyj (prawie) Wszechmocnego DrawText
funkcja wykorzystująca początkowy prostokąt oraz flagi DT_WORDBREAK
(co oznacza, że łańcuch powinien być zawinięty wyrazem) i DT_CALCRECT
:
procedure TForm1.FormPaint(Sender: TObject);
const
S = 'This is a sample text, I think, is it not?';
var
r: TRect;
begin
r := Rect(10, 10, 60, 60);
DrawText(Canvas.Handle,
PChar(S),
Length(S),
r,
DT_LEFT or DT_WORDBREAK or DT_CALCRECT);
DrawText(Canvas.Handle,
PChar(S),
Length(S),
r,
DT_LEFT or DT_WORDBREAK);
end;
Ze względu na flagę DT_CALCRECT
, Pierwsza DrawText
nie rysuje niczego, a jedynie zmienia wysokość r
tak, aby mogła zawierać cały ciąg S
(lub zmniejszyć szerokość r
, Jeśli S
pasuje do pojedynczej linii; ponadto, jeśli S
zawiera słowo, które nie pasuje do pojedynczej linii, szerokość linii nie może być mniejsza niż szerokość linii. r
zostanie zwiększona). Potem możesz robić co chcesz z r
, a potem możesz narysować ciąg na serio.
Spróbuj tego, na przykład:
procedure TForm1.FormPaint(Sender: TObject);
const
S: array[0..3] of string = ('Hi! How are you?',
'I am fine, thanks. How are you? How are your kids?',
'Fine!',
'Glad to hear that!');
Colors: array[boolean] of TColor = (clMoneyGreen, clSkyBlue);
Aligns: array[boolean] of integer = (DT_RIGHT, DT_LEFT);
var
i, y, MaxWidth, RectWidth: integer;
r, r2: TRect;
begin
y := 10;
MaxWidth := ClientWidth div 2;
for i := low(S) to high(S) do
begin
Canvas.Brush.Color := Colors[Odd(i)];
r := Rect(10, y, MaxWidth, 16);
DrawText(Canvas.Handle,
PChar(S[i]),
Length(S[i]),
r,
Aligns[Odd(i)] or DT_WORDBREAK or DT_CALCRECT);
if not Odd(i) then
begin
RectWidth := r.Right - r.Left;
r.Right := ClientWidth - 10;
r.Left := r.Right - RectWidth;
end;
r2 := Rect(r.Left - 4, r.Top - 4, r.Right + 4, r.Bottom + 4);
Canvas.RoundRect(r2, 5, 5);
DrawText(Canvas.Handle,
PChar(S[i]),
Length(S[i]),
r,
Aligns[Odd(i)] or DT_WORDBREAK);
y := r.Bottom + 10;
end;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
Invalidate;
end;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-10 22:40:54